Hi Stefan,
building on Mac OS X 64-bits raises some warnings (and an error, but
that's in another revision).
Comments inline.
Lieven
On Mon, Jul 26, 2010 at 10:30 AM, <stefan2_at_apache.org> wrote:
> Author: stefan2
> Date: Mon Jul 26 08:30:08 2010
> New Revision: 979193
>
> URL: http://svn.apache.org/viewvc?rev=979193&view=rev
> Log:
> Provide a memcached-like implementation of svn_cache_t that does not have
> the same latency and reliability issues. Detailed descriptions can be found in
> the .c file.
>
[..]
> +/* Get the entry references for the given ENTRY.
> + */
> +static APR_INLINE apr_uint32_t
> +get_index(membuffer_cache_t *cache, entry_t *entry)
> +{
> + return entry - (entry_t *)cache->directory;
> +}
In a 64-bit build this function triggers a "implicit conversion
shortens 64-bit value into a 32-bit value" warning.
[..]
> +/* If necessary, enlarge the insertion window until it is at least
> + * SIZE bytes long. SIZE must not exceed the data buffer size;
> + */
> +static void
> +ensure_data_insertable(membuffer_cache_t* cache, apr_size_t size)
> +{
> + int average_hits;
> + int threashold;
> + entry_t *entry;
> +
> + /* Make sure that this function actually terminates.
> + */
> + assert(cache->data_size >= size);
> +
> + while (1)
> + {
> + /* first offset behind the insertion window
> + */
> + apr_uint64_t end = cache->next == -1
> + ? cache->data_size
> + : get_entry(cache, cache->next)->offset;
> +
> + /* leave function as soon as the insertion window is large enough
> + */
> + if (end - cache->current_data >= size)
> + return;
> +
> + /* try to enlarge the insertion window
> + */
> + if (cache->next == -1)
> + {
> + /* We reached the end of the data buffer; restart at the beginning.
> + * Due to the randomized nature of our LFU implementation, very
> + * large data items may require multiple passes. Therefore, SIZE
> + * should be restricted to significantly less than data_size.
> + */
> + cache->current_data = 0;
> + cache->next = cache->first;
> + }
> + else
> + {
> + /* Roll the dice and determine a threashold somewhere from 0 up
Typo.
> + * to 2 times the average hit count.
> + */
> + average_hits = cache->hit_count / cache->used_entries;
Here too.
> + if (average_hits < 1)
> + average_hits = 1;
> +
[..]
> +svn_error_t*
> +svn_cache__membuffer_cache_create(membuffer_cache_t **cache,
> + apr_size_t total_size,
> + apr_size_t directory_size,
> + svn_boolean_t thread_safe,
> + apr_pool_t *pool)
> +{
> + membuffer_cache_t* c = apr_palloc(pool, sizeof(*c));
> + int i, k;
> +
> + /* We use this sub-pool to allocate the data buffer and the dictionary
> + * so that we can release that memory easily upon OOM.
> + */
> + apr_pool_t *sub_pool = svn_pool_create(pool);
> +
> + /* prevent pathological conditions: ensure a certain minimum cache size
> + */
> + if (total_size < 2 * sizeof(entry_group_t))
> + total_size = 2 * sizeof(entry_group_t);
> +
> + /* adapt the dictionary size accordingly, if necessary:
> + * It must hold at least one group and must not exceed the cache size.
> + */
> + if (directory_size > total_size - sizeof(entry_group_t))
> + directory_size = total_size - sizeof(entry_group_t);
> + if (directory_size < sizeof(entry_group_t))
> + directory_size = sizeof(entry_group_t);
> +
> + /* allocate buffers and initialize cache members
> + */
> + c->group_count = directory_size / sizeof (entry_group_t);
And here.
> + c->directory = apr_palloc(sub_pool, c->group_count * sizeof(entry_group_t));
> + c->first = -1;
> + c->last = -1;
> + c->next = -1;
> +
[..]
> +static svn_error_t*
> +membuffer_cache_set(membuffer_cache_t *cache,
> + const void *key,
> + apr_size_t key_len,
> + void *item,
> + svn_cache__serialize_func_t serializer,
> + apr_pool_t *pool)
> +{
> + apr_uint32_t group_index;
> + unsigned char to_find[KEY_SIZE];
> + entry_t *entry;
> + char *buffer;
> + apr_size_t size;
> + svn_error_t *err;
> +
> + /* find the entry group that will hold the key.
> + */
> + group_index = get_group_index(cache, key, key_len, to_find, pool);
> + if (group_index == -1)
> + return err;
> +
> + /* Serialize data data.
> + */
> + SVN_ERR(serializer(&buffer, &size, item, pool));
> +
> + /* The actual cache data access needs to sync'ed
> + */
> + SVN_ERR(lock_cache(cache));
> +
> + if (cache->data_size / 4 > size)
> + {
> + /* if necessary, enlarge the insertion window.
> + */
> + ensure_data_insertable(cache, size);
> +
> + /* Remove old data for this key, if it that exists.
> + * Get an unused entry for the key and and initialize it with
> + * the serialized item's (future) posion within data buffer.
> + */
> + entry = find_entry(cache, group_index, to_find, TRUE);
> + entry->size = size;
And here too.
> + entry->offset = cache->current_data;
> +
> + /* Copy the serialized item data into the cache.
> + */
Received on 2010-08-28 10:43:27 CEST