cache_item_t *beast_cache_create(cache_key_t *key, int size) { cache_item_t *item, *next; int i, msize, bsize; int pid = (int)getpid(); msize = sizeof(*item) + size; bsize = sizeof(cache_item_t *) * BUCKETS_DEFAULT_SIZE; if ((msize + bsize) > beast_mm_realspace()) { beast_write_log(beast_log_error, "Cache item size too big"); return NULL; } item = beast_mm_malloc(msize); if (!item) { #if 0 int index; /* clean all caches */ beast_spinlock(cache_lock, pid); for (index = 0; index < BUCKETS_DEFAULT_SIZE; index++) { beast_cache_buckets[index] = NULL; } beast_mm_flush(); beast_spinunlock(cache_lock, pid); item = beast_mm_malloc(msize); if (!item) { return NULL; } #endif beast_write_log(beast_log_notice, "Not enough caches, " "please setting <beast.cache_size> bigger in `php.ini' file"); return NULL; } item->key.device = key->device; item->key.inode = key->inode; item->key.fsize = key->fsize; item->key.mtime = key->mtime; item->next = NULL; return item; }
/* * Push cache item into cache manager, * this function return a cache item, * may be return value not equals push item, * so we must use return value. */ cache_item_t *beast_cache_push(cache_item_t *item) { int hashval = beast_cache_hash(&item->key); int index = hashval % BUCKETS_DEFAULT_SIZE; cache_item_t **this, *self; int pid = (int)getpid(); beast_spinlock(cache_lock, pid); #if 0 this = &beast_cache_buckets[index]; while (*this) { self = *this; /* the same files */ if (self->key.device == item->key.device && self->key.inode == item->key.inode) { if (self->key.mtime >= item->key.mtime) { beast_mm_free(item); beast_spinunlock(cache_lock, pid); return self; } else { /* do replace */ item->next = self->next; beast_mm_free(self); *this = item; beast_spinunlock(cache_lock, pid); return item; } } this = &self->next; } *this = item; #endif item->next = beast_cache_buckets[index]; beast_cache_buckets[index] = item; beast_spinunlock(cache_lock, pid); return item; }
void beast_cache_info(zval *retval) { char key[128]; int i; cache_item_t *item; int pid = (int)getpid(); beast_spinlock(cache_lock, pid); for (i = 0; i < BUCKETS_DEFAULT_SIZE; i++) { item = beast_cache_buckets[i]; while (item) { sprintf(key, "{device(%d)#inode(%d)}", item->key.device, item->key.inode); add_assoc_long(retval, key, item->key.fsize); item = item->next; } } beast_spinunlock(cache_lock, pid); }
cache_item_t *beast_cache_find(cache_key_t *key) { int hashval = beast_cache_hash(key); int index = hashval % BUCKETS_DEFAULT_SIZE; cache_item_t *item, *temp; int pid = (int)getpid(); beast_spinlock(cache_lock, pid); item = beast_cache_buckets[index]; while (item) { if (item->key.device == key->device && item->key.inode == key->inode) { break; } item = item->next; } if (item && item->key.mtime < key->mtime) /* cache exprie */ { temp = beast_cache_buckets[index]; if (temp == item) { /* the header node */ beast_cache_buckets[index] = item->next; } else { while (temp->next != item) /* find prev node */ temp = temp->next; temp->next = item->next; } beast_mm_free(item); item = NULL; } beast_spinunlock(cache_lock, pid); return item; }