Hash :
8d9a85d4
Author :
Date :
2013-08-22T11:40:53
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_sorted_cache_h__
#define INCLUDE_sorted_cache_h__
#include "util.h"
#include "fileops.h"
#include "vector.h"
#include "thread-utils.h"
#include "pool.h"
#include "strmap.h"
/*
* The purpose of this data structure is to cache the parsed contents of a
* file where each item in the file can be identified by a key string and
* you want to both look them up by name and traverse them in sorted
* order. Each item is assumed to itself end in a GIT_FLEX_ARRAY.
*/
typedef void (*git_sortedcache_free_item_fn)(void *payload, void *item);
typedef struct {
git_refcount rc;
git_rwlock lock;
size_t item_path_offset;
git_sortedcache_free_item_fn free_item;
void *free_item_payload;
git_pool pool;
git_vector items;
git_strmap *map;
git_futils_filestamp stamp;
char path[GIT_FLEX_ARRAY];
} git_sortedcache;
/* Create a new sortedcache
*
* Even though every sortedcache stores items with a GIT_FLEX_ARRAY at
* the end containing their key string, you have to provide the item_cmp
* sorting function because the sorting function doesn't get a payload
* and therefore can't know the offset to the item key string. :-(
*/
int git_sortedcache_new(
git_sortedcache **out,
size_t item_path_offset, /* use offsetof(struct, path-field) macro */
git_sortedcache_free_item_fn free_item,
void *free_item_payload,
git_vector_cmp item_cmp,
const char *path);
/* Copy a sorted cache
*
* - `copy_item` can be NULL to just use memcpy
* - if `wlock`, grabs write lock on `src` during copy and releases after
*/
int git_sortedcache_copy(
git_sortedcache **out,
git_sortedcache *src,
bool wlock,
int (*copy_item)(void *payload, void *tgt_item, void *src_item),
void *payload);
/* Free sorted cache (first calling `free_item` callbacks)
*
* Don't call on a locked collection - it may acquire a write lock
*/
void git_sortedcache_free(git_sortedcache *sc);
/* Increment reference count - balance with call to free */
void git_sortedcache_incref(git_sortedcache *sc);
/* Get the pathname associated with this cache at creation time */
const char *git_sortedcache_path(git_sortedcache *sc);
/*
* CACHE WRITE FUNCTIONS
*
* The following functions require you to have a writer lock to make the
* modification. Some of the functions take a `wlock` parameter and
* will optionally lock and unlock for you if that is passed as true.
*
*/
/* Lock sortedcache for write */
int git_sortedcache_wlock(git_sortedcache *sc);
/* Unlock sorted cache when done with write */
void git_sortedcache_wunlock(git_sortedcache *sc);
/* Lock cache and test if the file has changed. If the file has changed,
* then load the contents into `buf` otherwise unlock and return 0.
*
* @return 0 if up-to-date, 1 if out-of-date, <0 on error
*/
int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf);
/* Refresh file timestamp after write completes
* You should already be holding the write lock when you call this.
*/
void git_sortedcache_updated(git_sortedcache *sc);
/* Release all items in sorted cache
*
* If `wlock` is true, grabs write lock and releases when done, otherwise
* you should already be holding a write lock when you call this.
*/
int git_sortedcache_clear(git_sortedcache *sc, bool wlock);
/* Find and/or insert item, returning pointer to item data.
* You should already be holding the write lock when you call this.
*/
int git_sortedcache_upsert(
void **out, git_sortedcache *sc, const char *key);
/* Removes entry at pos from cache
* You should already be holding the write lock when you call this.
*/
int git_sortedcache_remove(git_sortedcache *sc, size_t pos);
/*
* CACHE READ FUNCTIONS
*
* The following functions access items in the cache. To prevent the
* results from being invalidated before they can be used, you should be
* holding either a read lock or a write lock when using these functions.
*
*/
/* Lock sortedcache for read */
int git_sortedcache_rlock(git_sortedcache *sc);
/* Unlock sorted cache when done with read */
void git_sortedcache_runlock(git_sortedcache *sc);
/* Lookup item by key - returns NULL if not found */
void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key);
/* Get how many items are in the cache
*
* You can call this function without holding a lock, but be aware
* that it may change before you use it.
*/
size_t git_sortedcache_entrycount(const git_sortedcache *sc);
/* Lookup item by index - returns NULL if out of range */
void *git_sortedcache_entry(git_sortedcache *sc, size_t pos);
/* Lookup index of item by key - returns GIT_ENOTFOUND if not found */
int git_sortedcache_lookup_index(
size_t *out, git_sortedcache *sc, const char *key);
#endif