cachelib.h revision 194097
1158115Sume/*- 2158115Sume * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 3158115Sume * All rights reserved. 4158115Sume * 5158115Sume * Redistribution and use in source and binary forms, with or without 6158115Sume * modification, are permitted provided that the following conditions 7158115Sume * are met: 8158115Sume * 1. Redistributions of source code must retain the above copyright 9158115Sume * notice, this list of conditions and the following disclaimer. 10158115Sume * 2. Redistributions in binary form must reproduce the above copyright 11158115Sume * notice, this list of conditions and the following disclaimer in the 12158115Sume * documentation and/or other materials provided with the distribution. 13158115Sume * 14158115Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15158115Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16158115Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17158115Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18158115Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19158115Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20158115Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21158115Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22158115Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23158115Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24158115Sume * SUCH DAMAGE. 25158115Sume * 26158115Sume * $FreeBSD: head/usr.sbin/nscd/cachelib.h 194097 2009-06-13 01:22:56Z des $ 27158115Sume */ 28158115Sume 29171795Sbushman#ifndef __NSCD_CACHELIB_H__ 30171795Sbushman#define __NSCD_CACHELIB_H__ 31158115Sume 32158115Sume#include "hashtable.h" 33158115Sume#include "cacheplcs.h" 34158115Sume 35158115Sumeenum cache_entry_t { 36158115Sume CET_COMMON = 0, /* cache item is atomic */ 37158115Sume CET_MULTIPART /* cache item is formed part by part */ 38158115Sume}; 39158115Sume 40158115Sumeenum cache_transformation_t { 41158115Sume CTT_FLUSH = 0, /* flush the cache - delete all obsolete items */ 42158115Sume CTT_CLEAR = 1 /* delete all items in the cache */ 43158115Sume}; 44158115Sume 45158115Sume/* cache deletion policy type enum */ 46158115Sumeenum cache_policy_t { 47158115Sume CPT_FIFO = 0, /* first-in first-out */ 48158115Sume CPT_LRU = 1, /* least recently used */ 49158115Sume CPT_LFU = 2 /* least frequently used */ 50158115Sume}; 51158115Sume 52158115Sume/* multipart sessions can be used for reading and writing */ 53158115Sumeenum cache_mp_session_t { 54158115Sume CMPT_READ_SESSION, 55158115Sume CMPT_WRITE_SESSION 56158115Sume}; 57158115Sume 58158115Sume/* 59158115Sume * When doing partial transformations of entries (which are applied for 60158115Sume * elements with keys, that contain specified buffer in its left or 61158115Sume * right part), this enum will show the needed position of the key part. 62158115Sume */ 63158115Sumeenum part_position_t { 64158115Sume KPPT_LEFT, 65158115Sume KPPT_RIGHT 66158115Sume}; 67158115Sume 68158115Sume/* num_levels attribute is obsolete, i think - user can always emulate it 69158115Sume * by using one entry. 70158115Sume * get_time_func is needed to have the clocks-independent counter 71158115Sume */ 72158115Sumestruct cache_params 73158115Sume{ 74158115Sume void (*get_time_func)(struct timeval *); 75158115Sume}; 76158115Sume 77158115Sume/* 78158115Sume * base structure - normal_cache_entry_params and multipart_cache_entry_params 79158115Sume * are "inherited" from it 80158115Sume */ 81158115Sumestruct cache_entry_params 82158115Sume{ 83158115Sume enum cache_entry_t entry_type; 84158115Sume char *entry_name; 85158115Sume}; 86158115Sume 87158115Sume/* params, used for most entries */ 88158115Sumestruct common_cache_entry_params 89158115Sume{ 90194097Sdes struct cache_entry_params cep; 91158115Sume 92158115Sume size_t cache_entries_size; 93158115Sume 94158115Sume size_t max_elemsize; /* if 0 then no check is made */ 95158115Sume size_t satisf_elemsize; /* if entry size is exceeded, 96158115Sume * this number of elements will be left, 97158115Sume * others will be deleted */ 98158115Sume struct timeval max_lifetime; /* if 0 then no check is made */ 99158115Sume enum cache_policy_t policy; /* policy used for transformations */ 100158115Sume}; 101158115Sume 102158115Sume/* params, used for multipart entries */ 103158115Sumestruct mp_cache_entry_params 104158115Sume{ 105194097Sdes struct cache_entry_params cep; 106158115Sume 107158115Sume /* unique fields */ 108158115Sume size_t max_elemsize; /* if 0 then no check is made */ 109158115Sume size_t max_sessions; /* maximum number of active sessions */ 110158115Sume 111158115Sume struct timeval max_lifetime; /* maximum elements lifetime */ 112158115Sume}; 113158115Sume 114158115Sumestruct cache_ht_item_data_ 115158115Sume{ 116158115Sume /* key is the bytes sequence only - not the null-terminated string */ 117158115Sume char *key; 118158115Sume size_t key_size; 119158115Sume 120158115Sume char *value; 121158115Sume size_t value_size; 122158115Sume 123158115Sume struct cache_policy_item_ *fifo_policy_item; 124158115Sume}; 125158115Sume 126158115Sumestruct cache_ht_item_ 127158115Sume{ 128158115Sume HASHTABLE_ENTRY_HEAD(ht_item_, struct cache_ht_item_data_) data; 129158115Sume}; 130158115Sume 131158115Sumestruct cache_entry_ 132158115Sume{ 133158115Sume char *name; 134158115Sume struct cache_entry_params *params; 135158115Sume}; 136158115Sume 137158115Sumestruct cache_common_entry_ 138158115Sume{ 139158115Sume char *name; 140158115Sume struct cache_entry_params *params; 141158115Sume 142158115Sume struct common_cache_entry_params common_params; 143158115Sume 144158115Sume HASHTABLE_HEAD(cache_ht_, cache_ht_item_) items; 145158115Sume size_t items_size; 146158115Sume 147158115Sume /* 148158115Sume * Entry always has the FIFO policy, that is used to eliminate old 149158115Sume * elements (the ones, with lifetime more than max_lifetime). Besides, 150158115Sume * user can specify another policy to be applied, when there are too 151158115Sume * many elements in the entry. So policies_size can be 1 or 2. 152158115Sume */ 153158115Sume struct cache_policy_ **policies; 154158115Sume size_t policies_size; 155158115Sume 156158115Sume void (*get_time_func)(struct timeval *); 157158115Sume}; 158158115Sume 159158115Sumestruct cache_mp_data_item_ { 160158115Sume char *value; 161158115Sume size_t value_size; 162158115Sume 163158115Sume TAILQ_ENTRY(cache_mp_data_item_) entries; 164158115Sume}; 165158115Sume 166158115Sumestruct cache_mp_write_session_ 167158115Sume{ 168158115Sume struct cache_mp_entry_ *parent_entry; 169158115Sume 170158115Sume /* 171158115Sume * All items are accumulated in this queue. When the session is 172158115Sume * committed, they all will be copied to the multipart entry. 173158115Sume */ 174158115Sume TAILQ_HEAD(cache_mp_data_item_head, cache_mp_data_item_) items; 175158115Sume size_t items_size; 176158115Sume 177158115Sume TAILQ_ENTRY(cache_mp_write_session_) entries; 178158115Sume}; 179158115Sume 180158115Sumestruct cache_mp_read_session_ 181158115Sume{ 182158115Sume struct cache_mp_entry_ *parent_entry; 183158115Sume struct cache_mp_data_item_ *current_item; 184158115Sume 185158115Sume TAILQ_ENTRY(cache_mp_read_session_) entries; 186158115Sume}; 187158115Sume 188158115Sumestruct cache_mp_entry_ 189158115Sume{ 190158115Sume char *name; 191158115Sume struct cache_entry_params *params; 192158115Sume 193158115Sume struct mp_cache_entry_params mp_params; 194158115Sume 195158115Sume /* All opened write sessions */ 196158115Sume TAILQ_HEAD(write_sessions_head, cache_mp_write_session_) ws_head; 197158115Sume size_t ws_size; 198158115Sume 199158115Sume /* All opened read sessions */ 200158115Sume TAILQ_HEAD(read_sessions_head, cache_mp_read_session_) rs_head; 201158115Sume size_t rs_size; 202158115Sume 203158115Sume /* 204158115Sume * completed_write_session is the committed write sessions. All read 205158115Sume * sessions use data from it. If the completed_write_session is out of 206158115Sume * date, but still in use by some of the read sessions, the newly 207158115Sume * committed write session is stored in the pending_write_session. 208158115Sume * In such a case, completed_write_session will be substituted with 209158115Sume * pending_write_session as soon as it won't be used by any of 210158115Sume * the read sessions. 211158115Sume */ 212158115Sume struct cache_mp_write_session_ *completed_write_session; 213158115Sume struct cache_mp_write_session_ *pending_write_session; 214158115Sume struct timeval creation_time; 215158115Sume struct timeval last_request_time; 216158115Sume 217158115Sume void (*get_time_func)(struct timeval *); 218158115Sume}; 219158115Sume 220158115Sumestruct cache_ 221158115Sume{ 222158115Sume struct cache_params params; 223158115Sume 224158115Sume struct cache_entry_ **entries; 225158115Sume size_t entries_capacity; 226158115Sume size_t entries_size; 227158115Sume}; 228158115Sume 229158115Sume/* simple abstractions - for not to write "struct" every time */ 230158115Sumetypedef struct cache_ *cache; 231158115Sumetypedef struct cache_entry_ *cache_entry; 232158115Sumetypedef struct cache_mp_write_session_ *cache_mp_write_session; 233158115Sumetypedef struct cache_mp_read_session_ *cache_mp_read_session; 234158115Sume 235158115Sume#define INVALID_CACHE (NULL) 236158115Sume#define INVALID_CACHE_ENTRY (NULL) 237158115Sume#define INVALID_CACHE_MP_WRITE_SESSION (NULL) 238158115Sume#define INVALID_CACHE_MP_READ_SESSION (NULL) 239158115Sume 240158115Sume/* 241158115Sume * NOTE: all cache operations are thread-unsafe. You must ensure thread-safety 242158115Sume * externally, by yourself. 243158115Sume */ 244158115Sume 245158115Sume/* cache initialization/destruction routines */ 246158115Sumeextern cache init_cache(struct cache_params const *); 247158115Sumeextern void destroy_cache(cache); 248158115Sume 249158115Sume/* cache entries manipulation routines */ 250158115Sumeextern int register_cache_entry(cache, struct cache_entry_params const *); 251158115Sumeextern int unregister_cache_entry(cache, const char *); 252158115Sumeextern cache_entry find_cache_entry(cache, const char *); 253158115Sume 254158115Sume/* read/write operations used on common entries */ 255158115Sumeextern int cache_read(cache_entry, const char *, size_t, char *, size_t *); 256158115Sumeextern int cache_write(cache_entry, const char *, size_t, char const *, size_t); 257158115Sume 258158115Sume/* read/write operations used on multipart entries */ 259158115Sumeextern cache_mp_write_session open_cache_mp_write_session(cache_entry); 260158115Sumeextern int cache_mp_write(cache_mp_write_session, char *, size_t); 261158115Sumeextern void abandon_cache_mp_write_session(cache_mp_write_session); 262158115Sumeextern void close_cache_mp_write_session(cache_mp_write_session); 263158115Sume 264158115Sumeextern cache_mp_read_session open_cache_mp_read_session(cache_entry); 265158115Sumeextern int cache_mp_read(cache_mp_read_session, char *, size_t *); 266158115Sumeextern void close_cache_mp_read_session(cache_mp_read_session); 267158115Sume 268158115Sume/* transformation routines */ 269158115Sumeextern int transform_cache_entry(cache_entry, enum cache_transformation_t); 270158115Sumeextern int transform_cache_entry_part(cache_entry, enum cache_transformation_t, 271158115Sume const char *, size_t, enum part_position_t); 272158115Sume 273158115Sume#endif 274