cvs: php4 /ext/ircg ircg.c

From: Date: Wed, 25 Apr 2001 13:14:40 +0000
Subject: cvs: php4 /ext/ircg ircg.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-5253@lists.php.net to get a copy of this message
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);

« previous php.cvs (#5253) next »