Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_subr/cache-inprocess.c view on Meta::CPAN
#include <assert.h>
#include <apr_thread_mutex.h>
#include "svn_pools.h"
#include "svn_private_config.h"
#include "cache.h"
#include "private/svn_mutex.h"
/* The (internal) cache object. */
typedef struct inprocess_cache_t {
/* A user-defined identifier for this cache instance. */
const char *id;
/* HASH maps a key (of size KLEN) to a struct cache_entry. */
apr_hash_t *hash;
apr_ssize_t klen;
/* Used to copy values into the cache. */
svn_cache__serialize_func_t serialize_func;
/* Used to copy values out of the cache. */
svn_cache__deserialize_func_t deserialize_func;
/* Maximum number of pages that this cache instance may allocate */
apr_uint64_t total_pages;
/* The number of pages we're allowed to allocate before having to
* try to reuse one. */
apr_uint64_t unallocated_pages;
/* Number of cache entries stored on each page. Must be at least 1. */
apr_uint64_t items_per_page;
/* A dummy cache_page serving as the head of a circular doubly
* linked list of cache_pages. SENTINEL->NEXT is the most recently
* used page, and SENTINEL->PREV is the least recently used page.
* All pages in this list are "full"; the page currently being
* filled (PARTIAL_PAGE) is not in the list. */
struct cache_page *sentinel;
/* A page currently being filled with entries, or NULL if there's no
* partially-filled page. This page is not in SENTINEL's list. */
struct cache_page *partial_page;
/* If PARTIAL_PAGE is not null, this is the number of entries
* currently on PARTIAL_PAGE. */
apr_uint64_t partial_page_number_filled;
/* The pool that the svn_cache__t itself, HASH, and all pages are
* allocated in; subpools of this pool are used for the cache_entry
* structs, as well as the dup'd values and hash keys.
*/
apr_pool_t *cache_pool;
/* Sum of the SIZE members of all cache_entry elements that are
* accessible from HASH. This is used to make statistics available
* even if the sub-pools have already been destroyed.
*/
apr_size_t data_size;
/* A lock for intra-process synchronization to the cache, or NULL if
* the cache's creator doesn't feel the cache needs to be
* thread-safe. */
svn_mutex__t *mutex;
} inprocess_cache_t;
/* A cache page; all items on the page are allocated from the same
* pool. */
struct cache_page {
/* Pointers for the LRU list anchored at the cache's SENTINEL.
* (NULL for the PARTIAL_PAGE.) */
struct cache_page *prev;
struct cache_page *next;
/* The pool in which cache_entry structs, hash keys, and dup'd
* values are allocated. The CACHE_PAGE structs are allocated
* in CACHE_POOL and have the same lifetime as the cache itself.
* (The cache will never allocate more than TOTAL_PAGES page
* structs (inclusive of the sentinel) from CACHE_POOL.)
*/
apr_pool_t *page_pool;
/* A singly linked list of the entries on this page; used to remove
* them from the cache's HASH before reusing the page. */
struct cache_entry *first_entry;
};
/* An cache entry. */
struct cache_entry {
const void *key;
/* serialized value */
void *value;
/* length of the serialized value in bytes */
apr_size_t size;
/* The page it's on (needed so that the LRU list can be
* maintained). */
struct cache_page *page;
/* Next entry on the page. */
struct cache_entry *next_entry;
};
/* Removes PAGE from the doubly-linked list it is in (leaving its PREV
* and NEXT fields undefined). */
static void
remove_page_from_list(struct cache_page *page)
{
page->prev->next = page->next;
page->next->prev = page->prev;
}
/* Inserts PAGE after CACHE's sentinel. */
static void
insert_page(inprocess_cache_t *cache,
struct cache_page *page)
{
struct cache_page *pred = cache->sentinel;
( run in 0.884 second using v1.01-cache-2.11-cpan-d7f47b0818f )