sas Wed Apr 25 06:14:40 2001 EDT
Modified files:
/php4/ext/ircg ircg.c
Log:
Past profiling has shown that we waste too much time in the message
scanner. In the context of a channel message which is supposedly
addressed to a large number of users, we therefore cache the result
of the operation and recycle it.
Index: php4/ext/ircg/ircg.c
diff -u php4/ext/ircg/ircg.c:1.61 php4/ext/ircg/ircg.c:1.62
--- php4/ext/ircg/ircg.c:1.61 Tue Apr 24 02:40:05 2001
+++ php4/ext/ircg/ircg.c Wed Apr 25 06:14:40 2001
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: ircg.c,v 1.61 2001/04/24 09:40:05 sas Exp $ */
+/* $Id: ircg.c,v 1.62 2001/04/25 13:14:40 sas Exp $ */
#include "php.h"
#include "php_ini.h"
@@ -268,9 +268,74 @@
}
}
-
+/* This is an expensive operation in terms of CPU time. We
+ try to spend as little time in it by caching messages which
+ are sent to channels (and hence used multiple times). */
void ircg_mirc_color(const char *, smart_str *, size_t);
+#define NR_CACHE_ENTRIES 10
+
+struct {
+ smart_str src;
+ smart_str result;
+ int score;
+} static cache_entries[NR_CACHE_ENTRIES];
+
+void ircg_mirc_color_cache(smart_str *src, smart_str *result,
+ smart_str *channel)
+{
+ /* We only cache messages in the context of a channel */
+ if (channel) {
+ int i;
+ int least_used_slot = 0;
+ int least_used_score = 50;
+
+ /* Score system. Initially, each slot gets 100 points.
+ * If a slot result is used, the slot earns three points.
+ * If a slot is not used but looked at, it gets punished.
+ * Slots with less than 50 points are considered for recycling,
+ * when the cache is full.
+ * This should ensure that new entries are not thrown out too
+ * early and that old entries are expired appropiately.
+ */
+
+ for (i = 0; i < NR_CACHE_ENTRIES && cache_entries[i].score; i++) {
+ /* case-sensitive comparison */
+ if (cache_entries[i].src.len == src->len &&
+ memcmp(cache_entries[i].src.c, src->c,
+src->len) == 0) {
+ cache_entries[i].score += 3;
+ smart_str_append_ex(result, &cache_entries[i].result,
+1);
+ return;
+ }
+
+ /* old entries will "expire" */
+ if (cache_entries[i].score > 1)
+ cache_entries[i].score--;
+
+ /* looks like this is the least used entry up to now */
+ if (cache_entries[i].score < least_used_score) {
+ least_used_score = cache_entries[i].score;
+ least_used_slot = i;
+ }
+ }
+
+ /* cache is full */
+ if (i == NR_CACHE_ENTRIES)
+ i = least_used_slot;
+
+ cache_entries[i].score = 100;
+ cache_entries[i].src.len = 0;
+ cache_entries[i].result.len = 0;
+ ircg_mirc_color(src->c, &cache_entries[i].result, src->len);
+
+ smart_str_append_ex(&cache_entries[i].src, src, 1);
+ smart_str_append_ex(result, &cache_entries[i].result, 1);
+ } else {
+ /* No channel message, no caching */
+ ircg_mirc_color(src->c, result, src->len);
+ }
+}
+
static void format_msg(const char *fmt, smart_str *channel, smart_str *to, smart_str
*from, smart_str *msg, smart_str *result)
{
const char *p;
@@ -336,7 +401,7 @@
case 'j':
append_js_encoded_msg:
if (!encoded) {
- ircg_mirc_color(msg->c, &encoded_msg, msg->len);
+ ircg_mirc_color_cache(msg, &encoded_msg, channel);
encoded = 1;
}
if (!js_encoded) {
@@ -348,7 +413,7 @@
case 'm':
if (mod_encode) goto append_js_encoded_msg;
if (!encoded) {
- ircg_mirc_color(msg->c, &encoded_msg, msg->len);
+ ircg_mirc_color_cache(msg, &encoded_msg, channel);
encoded = 1;
}
smart_str_append_ex(result, &encoded_msg, 1);
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]