From: Graham Leggett Date: Tue, 6 Dec 2011 13:03:34 +0000 (+0000) Subject: mod_cache: Remove dead code from the legacy mod_mem_cache module. X-Git-Tag: 2.5.0-alpha~7708 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00f036ee3833814f572ce286f7fff04d238d9b43;p=apache mod_cache: Remove dead code from the legacy mod_mem_cache module. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1210892 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/cache/cache_cache.c b/modules/cache/cache_cache.c deleted file mode 100644 index b0dd597123..0000000000 --- a/modules/cache/cache_cache.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_general.h" - -#include "mod_cache.h" -#include "cache_hash.h" -#include "cache_pqueue.h" -#include "cache_cache.h" - -#if APR_HAVE_STDLIB_H -#include -#endif -#if APR_HAVE_STRING_H -#include -#endif - -APLOG_USE_MODULE(cache); - -struct cache_cache_t { - int max_entries; - apr_size_t max_size; - apr_size_t current_size; - int total_purges; - long queue_clock; - cache_hash_t *ht; - cache_pqueue_t *pq; - cache_pqueue_set_priority set_pri; - cache_pqueue_get_priority get_pri; - cache_cache_inc_frequency *inc_entry; - cache_cache_get_size *size_entry; - cache_cache_get_key *key_entry; - cache_cache_free *free_entry; -}; - -cache_cache_t* cache_init(int max_entries, - apr_size_t max_size, - cache_pqueue_get_priority get_pri, - cache_pqueue_set_priority set_pri, - cache_pqueue_getpos get_pos, - cache_pqueue_setpos set_pos, - cache_cache_inc_frequency *inc_entry, - cache_cache_get_size *size_entry, - cache_cache_get_key* key_entry, - cache_cache_free *free_entry) -{ - cache_cache_t *tmp; - tmp = ap_malloc(sizeof(cache_cache_t)); - tmp->max_entries = max_entries; - tmp->max_size = max_size; - tmp->current_size = 0; - tmp->total_purges = 0; - tmp->queue_clock = 0; - tmp->get_pri = get_pri; - tmp->set_pri = set_pri; - tmp->inc_entry = inc_entry; - tmp->size_entry = size_entry; - tmp->key_entry = key_entry; - tmp->free_entry = free_entry; - - tmp->ht = cache_hash_make(max_entries); - tmp->pq = cache_pq_init(max_entries, get_pri, get_pos, set_pos); - - return tmp; -} - -void cache_free(cache_cache_t *c) -{ - cache_pq_free(c->pq); - cache_hash_free(c->ht); - free(c); -} - - -void* cache_find(cache_cache_t* c, const char *key) -{ - return cache_hash_get(c->ht, key, CACHE_HASH_KEY_STRING); -} - -void cache_update(cache_cache_t* c, void *entry) -{ - long old_priority; - long new_priority; - - old_priority = c->set_pri(c->queue_clock, entry); - c->inc_entry(entry); - new_priority = c->set_pri(c->queue_clock, entry); - cache_pq_change_priority(c->pq, old_priority, new_priority, entry); -} - -void cache_insert(cache_cache_t* c, void *entry) -{ - void *ejected = NULL; - long priority; - - c->set_pri(c->queue_clock, entry); - /* FIX: check if priority of bottom item is greater than inserted one */ - while ((cache_pq_size(c->pq) >= c->max_entries) || - ((c->current_size + c->size_entry(entry)) > c->max_size)) { - - ejected = cache_pq_pop(c->pq); - /* FIX: If ejected is NULL, we'll segfault here */ - priority = c->get_pri(ejected); - - if (c->queue_clock > priority) - c->queue_clock = priority; - - cache_hash_set(c->ht, - c->key_entry(ejected), - CACHE_HASH_KEY_STRING, - NULL); - - c->current_size -= c->size_entry(ejected); - c->free_entry(ejected); - c->total_purges++; - } - c->current_size += c->size_entry(entry); - - cache_pq_insert(c->pq, entry); - cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, entry); -} - -void* cache_pop(cache_cache_t *c) -{ - void *entry; - - if (!c) - return NULL; - - entry = cache_pq_pop(c->pq); - - if (!entry) - return NULL; - - c->current_size -= c->size_entry(entry); - cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL); - - return entry; -} - -apr_status_t cache_remove(cache_cache_t *c, void *entry) -{ - apr_size_t entry_size = c->size_entry(entry); - apr_status_t rc; - rc = cache_pq_remove(c->pq, entry); - if (rc != APR_SUCCESS) - return rc; - - cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL); - c->current_size -= entry_size; - - return APR_SUCCESS; -} diff --git a/modules/cache/cache_cache.h b/modules/cache/cache_cache.h deleted file mode 100644 index 9532a98d3e..0000000000 --- a/modules/cache/cache_cache.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file cache_cache.h - * @brief Cache Cache Functions - * - * @defgroup Cache_cache Cache Functions - * @ingroup MOD_CACHE - * @{ - */ - -#ifndef CACHE_CACHE_H -#define CACHE_CACHE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mod_cache.h" - -/** ADT for the cache */ -typedef struct cache_cache_t cache_cache_t; - -/** callback to increment the frequency of a item */ -typedef void cache_cache_inc_frequency(void*a); -/** callback to get the size of a item */ -typedef apr_size_t cache_cache_get_size(void*a); -/** callback to get the key of a item */ -typedef const char* cache_cache_get_key(void *a); -/** callback to free an entry */ -typedef void cache_cache_free(void *a); - -/** - * initialize the cache ADT - * @param max_entries the number of entries in the cache - * @param max_size the size of the cache - * @param get_pri callback to get a priority of a entry - * @param set_pri callback to set a priority of a entry - * @param get_pos callback to get the position of a entry in the cache - * @param set_pos callback to set the position of a entry in the cache - * @param inc_entry callback to increment the frequency of a entry - * @param size_entry callback to get the size of a entry - * @param key_entry callback to get the key of a entry - * @param free_entry callback to free an entry - */ -cache_cache_t* cache_init(int max_entries, - apr_size_t max_size, - cache_pqueue_get_priority get_pri, - cache_pqueue_set_priority set_pri, - cache_pqueue_getpos get_pos, - cache_pqueue_setpos set_pos, - cache_cache_inc_frequency *inc_entry, - cache_cache_get_size *size_entry, - cache_cache_get_key *key_entry, - cache_cache_free *free_entry); - -/** - * free up the cache - * @param c the cache - */ -void cache_free(cache_cache_t *c); -/** - * find a entry in the cache, incrementing the frequency if found - * @param c the cache - * @param key the key - */ -void* cache_find(cache_cache_t* c, const char *key); -/** - * insert a entry into the cache - * @param c the cache - * @param entry the entry - */ -void cache_update(cache_cache_t* c, void *entry); -/** - * insert a entry into the cache - * @param c the cache - * @param entry the entry - */ -void cache_insert(cache_cache_t* c, void *entry); -/** - * pop the lowest priority item off - * @param c the cache - * @returns the entry or NULL - */ -void* cache_pop(cache_cache_t* c); -/** - * remove an item from the cache - * @param c the cache - * @param entry the actual entry (from a find) - */ -apr_status_t cache_remove(cache_cache_t* c, void *entry); -#ifdef __cplusplus -} -#endif - -#endif /* !CACHE_CACHE_H */ -/** @} */ diff --git a/modules/cache/cache_hash.c b/modules/cache/cache_hash.c deleted file mode 100644 index 57f7db17ca..0000000000 --- a/modules/cache/cache_hash.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_general.h" - -#include "mod_cache.h" -#include "cache_hash.h" - -#if APR_HAVE_STDLIB_H -#include -#endif -#if APR_HAVE_STRING_H -#include -#endif - - -/* - * The internal form of a hash table. - * - * The table is an array indexed by the hash of the key; collisions - * are resolved by hanging a linked list of hash entries off each - * element of the array. Although this is a really simple design it - * isn't too bad given that pools have a low allocation overhead. - */ - -typedef struct cache_hash_entry_t cache_hash_entry_t; - -struct cache_hash_entry_t { - cache_hash_entry_t *next; - unsigned int hash; - const void *key; - apr_ssize_t klen; - const void *val; -}; - -/* - * Data structure for iterating through a hash table. - * - * We keep a pointer to the next hash entry here to allow the current - * hash entry to be freed or otherwise mangled between calls to - * cache_hash_next(). - */ -struct cache_hash_index_t { - cache_hash_t *ht; - cache_hash_entry_t *this, *next; - int index; -}; - -/* - * The size of the array is always a power of two. We use the maximum - * index rather than the size so that we can use bitwise-AND for - * modular arithmetic. - * The count of hash entries may be greater depending on the chosen - * collision rate. - */ -struct cache_hash_t { - cache_hash_entry_t **array; - cache_hash_index_t iterator; /* For cache_hash_first(NULL, ...) */ - int count, max; -}; - -/* - * Hash creation functions. - */ -static cache_hash_entry_t **alloc_array(cache_hash_t *ht, int max) -{ - return ap_calloc(1, sizeof(*ht->array) * (max + 1)); -} - -cache_hash_t* cache_hash_make(apr_size_t size) -{ - cache_hash_t *ht; - ht = ap_malloc(sizeof(cache_hash_t)); - ht->count = 0; - ht->max = size; - ht->array = alloc_array(ht, ht->max); - return ht; -} - -void cache_hash_free(cache_hash_t *ht) -{ - if (ht) { - if (ht->array) { - free (ht->array); - } - free (ht); - } -} -/* - * Hash iteration functions. - */ - -cache_hash_index_t* cache_hash_next(cache_hash_index_t *hi) -{ - hi->this = hi->next; - while (!hi->this) { - if (hi->index > hi->ht->max) - return NULL; - hi->this = hi->ht->array[hi->index++]; - } - hi->next = hi->this->next; - return hi; -} - -cache_hash_index_t* cache_hash_first(cache_hash_t *ht) -{ - cache_hash_index_t *hi; - - hi = &ht->iterator; - hi->ht = ht; - hi->index = 0; - hi->this = NULL; - hi->next = NULL; - return cache_hash_next(hi); -} - -void cache_hash_this(cache_hash_index_t *hi, - const void **key, - apr_ssize_t *klen, - void **val) -{ - if (key) *key = hi->this->key; - if (klen) *klen = hi->this->klen; - if (val) *val = (void *)hi->this->val; -} - - -/* - * This is where we keep the details of the hash function and control - * the maximum collision rate. - * - * If val is non-NULL it creates and initializes a new hash entry if - * there isn't already one there; it returns an updatable pointer so - * that hash entries can be removed. - */ - -static cache_hash_entry_t **find_entry(cache_hash_t *ht, - const void *key, - apr_ssize_t klen, - const void *val) -{ - cache_hash_entry_t **hep, *he; - const unsigned char *p; - unsigned int hash; - apr_ssize_t i; - - /* - * This is the popular `times 33' hash algorithm which is used by - * perl and also appears in Berkeley DB. This is one of the best - * known hash functions for strings because it is both computed - * very fast and distributes very well. - * - * The originator may be Dan Bernstein but the code in Berkeley DB - * cites Chris Torek as the source. The best citation I have found - * is "Chris Torek, Hash function for text in C, Usenet message - * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich - * Salz's USENIX 1992 paper about INN which can be found at - * . - * - * The magic of number 33, i.e. why it works better than many other - * constants, prime or not, has never been adequately explained by - * anyone. So I try an explanation: if one experimentally tests all - * multipliers between 1 and 256 (as I did while writing a low-level - * data structure library some time ago) one detects that even - * numbers are not useable at all. The remaining 128 odd numbers - * (except for the number 1) work more or less all equally well. - * They all distribute in an acceptable way and this way fill a hash - * table with an average percent of approx. 86%. - * - * If one compares the chi^2 values of the variants (see - * Bob Jenkins ``Hashing Frequently Asked Questions'' at - * http://burtleburtle.net/bob/hash/hashfaq.html for a description - * of chi^2), the number 33 not even has the best value. But the - * number 33 and a few other equally good numbers like 17, 31, 63, - * 127 and 129 have nevertheless a great advantage to the remaining - * numbers in the large set of possible multipliers: their multiply - * operation can be replaced by a faster operation based on just one - * shift plus either a single addition or subtraction operation. And - * because a hash function has to both distribute good _and_ has to - * be very fast to compute, those few numbers should be preferred. - * - * -- Ralf S. Engelschall - */ - hash = 0; - if (klen == CACHE_HASH_KEY_STRING) { - for (p = key; *p; p++) { - hash = hash * 33 + *p; - } - klen = p - (const unsigned char *)key; - } - else { - for (p = key, i = klen; i; i--, p++) { - hash = hash * 33 + *p; - } - } - - /* scan linked list */ - for (hep = &ht->array[hash % ht->max], he = *hep; - he; - hep = &he->next, he = *hep) { - if (he->hash == hash && - he->klen == klen && - memcmp(he->key, key, klen) == 0) - break; - } - if (he || !val) - return hep; - /* add a new entry for non-NULL values */ - he = ap_malloc(sizeof(*he)); - he->next = NULL; - he->hash = hash; - he->key = key; - he->klen = klen; - he->val = val; - *hep = he; - ht->count++; - return hep; -} - -void* cache_hash_get(cache_hash_t *ht, - const void *key, - apr_ssize_t klen) -{ - cache_hash_entry_t *he; - he = *find_entry(ht, key, klen, NULL); - if (he) - return (void *)he->val; - else - return NULL; -} - -void* cache_hash_set(cache_hash_t *ht, - const void *key, - apr_ssize_t klen, - const void *val) -{ - cache_hash_entry_t **hep, *tmp; - const void *tval; - hep = find_entry(ht, key, klen, val); - if (*hep) { - if (!val) { - /* delete entry */ - tval = (*hep)->val; - tmp = *hep; - *hep = (*hep)->next; - free(tmp); - --ht->count; - } - else { - /* replace entry */ - tval = (*hep)->val; - (*hep)->val = val; - } - /* Return the object just removed from the cache to let the - * caller clean it up. Cast the constness away upon return. - */ - return (void *) tval; - } - /* else key not present and val==NULL */ - return NULL; -} - -int cache_hash_count(cache_hash_t *ht) -{ - return ht->count; -} diff --git a/modules/cache/cache_hash.h b/modules/cache/cache_hash.h deleted file mode 100644 index 3ae9861770..0000000000 --- a/modules/cache/cache_hash.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file cache_hash.h - * @brief Cache Hash Tables - * - * @defgroup Cache_Hash Hash Tables - * @ingroup MOD_CACHE - * @{ - */ - -#ifndef CACHE_HASH_H -#define CACHE_HASH_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mod_cache.h" - -/** - * When passing a key to cache_hash_set or cache_hash_get, this value can be - * passed to indicate a string-valued key, and have cache_hash compute the - * length automatically. - * - * @remark cache_hash will use strlen(key) for the length. The null-terminator - * is not included in the hash value (why throw a constant in?). - * Since the hash table merely references the provided key (rather - * than copying it), cache_hash_this() will return the null-term'd key. - */ -#define CACHE_HASH_KEY_STRING (-1) - -/** - * Abstract type for hash tables. - */ -typedef struct cache_hash_t cache_hash_t; - -/** - * Abstract type for scanning hash tables. - */ -typedef struct cache_hash_index_t cache_hash_index_t; - -/** - * Create a hash table. - * @param size - * @return The hash table just created - */ -cache_hash_t* cache_hash_make(apr_size_t size); - -/** - * Create a hash table. - * @param *ht Pointer to the hash table to be freed. - * @return void - * @remark The caller should ensure that all objects have been removed - * from the cache prior to calling cache_hash_free(). Objects - * not removed from the cache prior to calling cache_hash_free() - * will be unaccessable. - */ -void cache_hash_free(cache_hash_t *ht); - - -/** - * Associate a value with a key in a hash table. - * @param ht The hash table - * @param key Pointer to the key - * @param klen Length of the key. Can be CACHE_HASH_KEY_STRING to use the string length. - * @param val Value to associate with the key - * @remark If the value is NULL the hash entry is deleted. - * @return The value of the deleted cache entry (so the caller can clean it up). - */ -void* cache_hash_set(cache_hash_t *ht, const void *key, - apr_ssize_t klen, const void *val); - -/** - * Look up the value associated with a key in a hash table. - * @param ht The hash table - * @param key Pointer to the key - * @param klen Length of the key. Can be CACHE_HASH_KEY_STRING to use the string length. - * @return Returns NULL if the key is not present. - */ -void* cache_hash_get(cache_hash_t *ht, const void *key, - apr_ssize_t klen); - -/** - * Start iterating over the entries in a hash table. - * @param ht The hash table - * - * Here is an example of using this: - * @code - * int sum_values(cache_hash_t *ht) - * { - * cache_hash_index_t *hi; - * void *val; - * int sum = 0; - * for (hi = cache_hash_first(ht); hi; hi = cache_hash_next(hi)) { - * cache_hash_this(hi, NULL, NULL, &val); - * sum += *(int *)val; - * } - * return sum; - * } - * @endcode - * - * There is no restriction on adding or deleting hash entries during an - * iteration (although the results may be unpredictable unless all you do - * is delete the current entry) and multiple iterations can be in - * progress at the same time. - */ -cache_hash_index_t* cache_hash_first(cache_hash_t *ht); - -/** - * Continue iterating over the entries in a hash table. - * @param hi The iteration state - * @return a pointer to the updated iteration state. NULL if there are no more - * entries. - */ -cache_hash_index_t* cache_hash_next(cache_hash_index_t *hi); - -/** - * Get the current entry's details from the iteration state. - * @param hi The iteration state - * @param key Return pointer for the pointer to the key. - * @param klen Return pointer for the key length. - * @param val Return pointer for the associated value. - * @remark The return pointers should point to a variable that will be set to the - * corresponding data, or they may be NULL if the data isn't interesting. - */ -void cache_hash_this(cache_hash_index_t *hi, const void **key, - apr_ssize_t *klen, void **val); - -/** - * Get the number of key/value pairs in the hash table. - * @param ht The hash table - * @return The number of key/value pairs in the hash table. - */ -int cache_hash_count(cache_hash_t *ht); - - -/** @} */ -#ifdef __cplusplus -} -#endif - -#endif /* !CACHE_HASH_H */ diff --git a/modules/cache/cache_pqueue.c b/modules/cache/cache_pqueue.c deleted file mode 100644 index 164bb9d26a..0000000000 --- a/modules/cache/cache_pqueue.c +++ /dev/null @@ -1,282 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_general.h" - -#if APR_HAVE_STDLIB_H -#include -#endif -#if APR_HAVE_STDIO_H -#include -#endif - -#if APR_HAVE_STRING_H -#include -#endif - -#include "cache_pqueue.h" -#define left(i) (2*(i)) -#define right(i) ((2*(i))+1) -#define parent(i) ((i)/2) -/* - * Priority queue structure - */ -struct cache_pqueue_t -{ - apr_ssize_t size; - apr_ssize_t avail; - apr_ssize_t step; - cache_pqueue_get_priority pri; - cache_pqueue_getpos get; - cache_pqueue_setpos set; - void **d; -}; - -cache_pqueue_t *cache_pq_init(apr_ssize_t n, - cache_pqueue_get_priority pri, - cache_pqueue_getpos get, - cache_pqueue_setpos set) -{ - cache_pqueue_t *q = ap_malloc(sizeof(cache_pqueue_t)); - /* Need to allocate n+1 elements since element 0 isn't used. */ - q->d = ap_malloc(sizeof(void*) * (n+1)); - q->avail = q->step = (n+1); /* see comment above about n+1 */ - q->pri = pri; - q->size = 1; - q->get = get; - q->set = set; - return q; -} -/* - * cleanup - */ -void cache_pq_free(cache_pqueue_t *q) -{ - free(q->d); - free(q); -} -/* - * pqsize: size of the queue. - */ -apr_ssize_t cache_pq_size(cache_pqueue_t *q) -{ - /* queue element 0 exists but doesn't count since it isn't used. */ - return (q->size - 1); -} - -static void cache_pq_bubble_up(cache_pqueue_t *q, apr_ssize_t i) -{ - apr_ssize_t parent_node; - void *moving_node = q->d[i]; - long moving_pri = q->pri(moving_node); - - for (parent_node = parent(i); - ((i > 1) && (q->pri(q->d[parent_node]) < moving_pri)); - i = parent_node, parent_node = parent(i)) - { - q->d[i] = q->d[parent_node]; - q->set(q->d[i], i); - } - - q->d[i] = moving_node; - q->set(moving_node, i); -} - -static apr_ssize_t maxchild(cache_pqueue_t *q, apr_ssize_t i) -{ - apr_ssize_t child_node = left(i); - - if (child_node >= q->size) - return 0; - - if ((child_node+1 < q->size) && - (q->pri(q->d[child_node+1]) > q->pri(q->d[child_node]))) - { - child_node++; /* use right child instead of left */ - } - - return child_node; -} - -static void cache_pq_percolate_down(cache_pqueue_t *q, apr_ssize_t i) -{ - apr_ssize_t child_node; - void *moving_node = q->d[i]; - long moving_pri = q->pri(moving_node); - - while ((child_node = maxchild(q, i)) && - (moving_pri < q->pri(q->d[child_node]))) - { - q->d[i] = q->d[child_node]; - q->set(q->d[i], i); - i = child_node; - } - - q->d[i] = moving_node; - q->set(moving_node, i); -} - -apr_status_t cache_pq_insert(cache_pqueue_t *q, void *d) -{ - void *tmp; - apr_ssize_t i; - apr_ssize_t newsize; - - if (!q) return APR_EGENERAL; - - /* allocate more memory if necessary */ - if (q->size >= q->avail) { - newsize = q->size + q->step; - if (!(tmp = ap_realloc(q->d, sizeof(void*) * newsize))) { - return APR_EGENERAL; - }; - q->d = tmp; - q->avail = newsize; - } - - /* insert item */ - i = q->size++; - q->d[i] = d; - cache_pq_bubble_up(q, i); - return APR_SUCCESS; -} - -/* - * move a existing entry to a new priority - */ -void cache_pq_change_priority(cache_pqueue_t *q, - long old_priority, - long new_priority, - void *d) -{ - apr_ssize_t posn; - - posn = q->get(d); - if (new_priority > old_priority) - cache_pq_bubble_up(q, posn); - else - cache_pq_percolate_down(q, posn); -} - -apr_status_t cache_pq_remove(cache_pqueue_t *q, void *d) -{ - apr_ssize_t posn = q->get(d); - q->d[posn] = q->d[--q->size]; - if (q->pri(q->d[posn]) > q->pri(d)) - cache_pq_bubble_up(q, posn); - else - cache_pq_percolate_down(q, posn); - - return APR_SUCCESS; -} - -void *cache_pq_pop(cache_pqueue_t *q) -{ - void *head; - - if (!q || q->size == 1) - return NULL; - - head = q->d[1]; - q->d[1] = q->d[--q->size]; - cache_pq_percolate_down(q, 1); - - return head; -} - -void *cache_pq_peek(cache_pqueue_t *q) -{ - void *d; - if (!q || q->size == 1) - return NULL; - d = q->d[1]; - return d; -} - -static void cache_pq_set_null( void*d, apr_ssize_t val) -{ - /* do nothing */ -} - -/* - * this is a debug function.. so it's EASY not fast - */ -void cache_pq_dump(cache_pqueue_t *q, - FILE*out, - cache_pqueue_print_entry print) -{ - int i; - - fprintf(stdout,"posn\tleft\tright\tparent\tmaxchild\t...\n"); - for (i = 1; i < q->size ;i++) { - fprintf(stdout, - "%d\t%d\t%d\t%d\t%" APR_SSIZE_T_FMT "\t", - i, - left(i), right(i), parent(i), - maxchild(q, i)); - print(out, q->d[i]); - } -} - -/* - * this is a debug function.. so it's EASY not fast - */ -void cache_pq_print(cache_pqueue_t *q, - FILE*out, - cache_pqueue_print_entry print) -{ - cache_pqueue_t *dup; - dup = cache_pq_init(q->size, q->pri, q->get, cache_pq_set_null); - dup->size = q->size; - dup->avail = q->avail; - dup->step = q->step; - - memcpy(dup->d, q->d, q->size*sizeof(void*)); - - while (cache_pq_size(dup) > 1) { - void *e = NULL; - e = cache_pq_pop(dup); - if (e) - print(out, e); - else - break; - } - cache_pq_free(dup); -} - -static int cache_pq_subtree_is_valid(cache_pqueue_t *q, int pos) -{ - if (left(pos) < q->size) { - /* has a left child */ - if (q->pri(q->d[pos]) < q->pri(q->d[left(pos)])) - return 0; - if (!cache_pq_subtree_is_valid(q, left(pos))) - return 0; - } - if (right(pos) < q->size) { - /* has a right child */ - if (q->pri(q->d[pos]) < q->pri(q->d[right(pos)])) - return 0; - if (!cache_pq_subtree_is_valid(q, right(pos))) - return 0; - } - return 1; -} - -int cache_pq_is_valid(cache_pqueue_t *q) -{ - return cache_pq_subtree_is_valid(q, 1); -} diff --git a/modules/cache/cache_pqueue.h b/modules/cache/cache_pqueue.h deleted file mode 100644 index 9b73690517..0000000000 --- a/modules/cache/cache_pqueue.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file cache_pqueue.h - * @brief Cache Priority Queue function declarations - * - * @defgroup MOD_CACHE_QUEUE Priority Queue - * @ingroup MOD_CACHE - * @{ - */ - -#ifndef CACHE_PQUEUE_H -#define CACHE_PQUEUE_H - -#include -#include - -#if APR_HAVE_STDIO_H -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** the cache priority queue handle */ -typedef struct cache_pqueue_t cache_pqueue_t; - -/** - * callback function to assign a priority for a element - * @param a the element - * @return the score (the lower the score the longer it is kept int the queue) - */ -typedef long (*cache_pqueue_set_priority)(long queue_clock, void *a); -typedef long (*cache_pqueue_get_priority)(void *a); - -/** callback function to get a position of a element */ -typedef apr_ssize_t (*cache_pqueue_getpos)(void *a); - -/** - * callback function to set a position of a element - * @param a the element - * @param pos the position to set it to - */ -typedef void (*cache_pqueue_setpos)(void *a, apr_ssize_t pos); - -/** debug callback function to print a entry */ -typedef void (*cache_pqueue_print_entry)(FILE *out, void *a); - -/** - * initialize the queue - * - * @param n the initial estimate of the number of queue items for which memory - * should be preallocated - * @param pri the callback function to run to assign a score to a element - * @param get the callback function to get the current element's position - * @param set the callback function to set the current element's position - * - * @return the handle or NULL for insufficent memory - */ -cache_pqueue_t *cache_pq_init(apr_ssize_t n, - cache_pqueue_get_priority pri, - cache_pqueue_getpos get, - cache_pqueue_setpos set); -/** - * free all memory used by the queue - * @param q the queue - */ -void cache_pq_free(cache_pqueue_t *q); -/** - * return the size of the queue. - * @param q the queue - */ -apr_ssize_t cache_pq_size(cache_pqueue_t *q); - -/** - * insert an item into the queue. - * @param q the queue - * @param d the item - * @return APR_SUCCESS on success - */ -apr_status_t cache_pq_insert(cache_pqueue_t *q, void *d); - -/* - * move a existing entry to a different priority - * @param q the queue - * @param old the old priority - * @param d the entry - */ -void cache_pq_change_priority(cache_pqueue_t *q, - long old_priority, - long new_priority, - void *d); - -/** - * pop the highest-ranking item from the queue. - * @param q the queue - * @return NULL on error, otherwise the entry - */ -void *cache_pq_pop(cache_pqueue_t *q); - -/** - * remove an item from the queue. - * @param q the queue - * @param d the entry - * @return APR_SUCCESS on success - */ -apr_status_t cache_pq_remove(cache_pqueue_t *q, void *d); - -/** - * access highest-ranking item without removing it. - * @param q the queue - * @return NULL on error, otherwise the entry - */ -void *cache_pq_peek(cache_pqueue_t *q); - -/** - * print the queue - * @internal - * DEBUG function only - * @param q the queue - * @param out the output handle - * @param print the callback function to print the entry - */ -void cache_pq_print(cache_pqueue_t *q, - FILE *out, - cache_pqueue_print_entry print); - -/** - * dump the queue and its internal structure - * @internal - * debug function only - * @param q the queue - * @param out the output handle - * @param print the callback function to print the entry - */ -void cache_pq_dump(cache_pqueue_t *q, - FILE *out, - cache_pqueue_print_entry print); - -/** - * checks that the pq is in the right order, etc - * @internal - * debug function only - * @param q the queue - */ -int cache_pq_is_valid(cache_pqueue_t *q); - -#ifdef __cplusplus -} -#endif - -#endif /* !CACHE_PQUEUE_H */ -/** @} */