cachelib.h revision 194089
156067Smarkm/*- 256067Smarkm * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 356067Smarkm * All rights reserved. 456067Smarkm * 556067Smarkm * Redistribution and use in source and binary forms, with or without 656067Smarkm * modification, are permitted provided that the following conditions 756067Smarkm * are met: 856067Smarkm * 1. Redistributions of source code must retain the above copyright 956067Smarkm * notice, this list of conditions and the following disclaimer. 1056067Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1156067Smarkm * notice, this list of conditions and the following disclaimer in the 1256067Smarkm * documentation and/or other materials provided with the distribution. 1356067Smarkm * 1456549Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1556549Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1657672Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1758485Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1857672Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1956549Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2056549Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2156549Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2256549Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2356067Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2456067Smarkm * SUCH DAMAGE. 2556067Smarkm * 2656067Smarkm * $FreeBSD: head/usr.sbin/nscd/cachelib.h 194089 2009-06-13 00:06:52Z des $ 2756067Smarkm */ 2856067Smarkm 2956067Smarkm#ifndef __NSCD_CACHELIB_H__ 3056067Smarkm#define __NSCD_CACHELIB_H__ 3156067Smarkm 3256067Smarkm#include "hashtable.h" 3356067Smarkm#include "cacheplcs.h" 3456067Smarkm 3556067Smarkmenum cache_entry_t { 3656067Smarkm CET_COMMON = 0, /* cache item is atomic */ 3756067Smarkm CET_MULTIPART /* cache item is formed part by part */ 3856067Smarkm}; 3956067Smarkm 4056067Smarkmenum cache_transformation_t { 4156067Smarkm CTT_FLUSH = 0, /* flush the cache - delete all obsolete items */ 4256067Smarkm CTT_CLEAR = 1 /* delete all items in the cache */ 4356067Smarkm}; 4456067Smarkm 4556067Smarkm/* cache deletion policy type enum */ 4656067Smarkmenum cache_policy_t { 4772450Sassar CPT_FIFO = 0, /* first-in first-out */ 4872450Sassar CPT_LRU = 1, /* least recently used */ 4972450Sassar CPT_LFU = 2 /* least frequently used */ 5072450Sassar}; 5172450Sassar 5272450Sassar/* multipart sessions can be used for reading and writing */ 5356067Smarkmenum cache_mp_session_t { 5456067Smarkm CMPT_READ_SESSION, 5556067Smarkm CMPT_WRITE_SESSION 5656067Smarkm}; 5756067Smarkm 5856067Smarkm/* 5956067Smarkm * When doing partial transformations of entries (which are applied for 6056067Smarkm * elements with keys, that contain specified buffer in its left or 6156067Smarkm * right part), this enum will show the needed position of the key part. 6256067Smarkm */ 6356067Smarkmenum part_position_t { 6456067Smarkm KPPT_LEFT, 6556067Smarkm KPPT_RIGHT 6656067Smarkm}; 6756067Smarkm 6856067Smarkm/* num_levels attribute is obsolete, i think - user can always emulate it 6956067Smarkm * by using one entry. 7056067Smarkm * get_time_func is needed to have the clocks-independent counter 7156067Smarkm */ 7256067Smarkmstruct cache_params 7356067Smarkm{ 7456067Smarkm void (*get_time_func)(struct timeval *); 7556067Smarkm}; 7656067Smarkm 7756067Smarkm/* 7856067Smarkm * base structure - normal_cache_entry_params and multipart_cache_entry_params 7956067Smarkm * are "inherited" from it 8056067Smarkm */ 8156067Smarkmstruct cache_entry_params 8256067Smarkm{ 8356067Smarkm enum cache_entry_t entry_type; 8456067Smarkm char *entry_name; 8556067Smarkm}; 8656067Smarkm 8756067Smarkm/* params, used for most entries */ 8856067Smarkmstruct common_cache_entry_params 8956067Smarkm{ 9056067Smarkm /* inherited fields */ 9156067Smarkm enum cache_entry_t entry_type; 9256067Smarkm 9356067Smarkm /* unique fields */ 9456067Smarkm char *entry_name; 9556067Smarkm size_t cache_entries_size; 9656067Smarkm 9756067Smarkm size_t max_elemsize; /* if 0 then no check is made */ 9856067Smarkm size_t satisf_elemsize; /* if entry size is exceeded, 9956067Smarkm * this number of elements will be left, 10056067Smarkm * others will be deleted */ 10156067Smarkm struct timeval max_lifetime; /* if 0 then no check is made */ 10256067Smarkm enum cache_policy_t policy; /* policy used for transformations */ 10356067Smarkm}; 10456067Smarkm 10556067Smarkm/* params, used for multipart entries */ 10656067Smarkmstruct mp_cache_entry_params 10756067Smarkm{ 10856067Smarkm /* inherited fields */ 10956067Smarkm enum cache_entry_t entry_type; 11056067Smarkm char *entry_name; 11156067Smarkm 11256067Smarkm /* unique fields */ 11356067Smarkm size_t max_elemsize; /* if 0 then no check is made */ 11456067Smarkm size_t max_sessions; /* maximum number of active sessions */ 11556067Smarkm 11656067Smarkm struct timeval max_lifetime; /* maximum elements lifetime */ 11756067Smarkm}; 11856067Smarkm 11956067Smarkmstruct cache_ht_item_data_ 12056067Smarkm{ 12156067Smarkm /* key is the bytes sequence only - not the null-terminated string */ 12256067Smarkm char *key; 12356067Smarkm size_t key_size; 12456067Smarkm 12556067Smarkm char *value; 12656067Smarkm size_t value_size; 12756067Smarkm 12856067Smarkm struct cache_policy_item_ *fifo_policy_item; 12956067Smarkm}; 13056067Smarkm 13156067Smarkmstruct cache_ht_item_ 13256067Smarkm{ 13356067Smarkm HASHTABLE_ENTRY_HEAD(ht_item_, struct cache_ht_item_data_) data; 13456067Smarkm}; 13556067Smarkm 13656067Smarkmstruct cache_entry_ 13756067Smarkm{ 13856067Smarkm char *name; 13956067Smarkm struct cache_entry_params *params; 14056067Smarkm}; 14156067Smarkm 14256067Smarkmstruct cache_common_entry_ 14357566Smarkm{ 14456067Smarkm char *name; 14556067Smarkm struct cache_entry_params *params; 14656067Smarkm 14757452Smarkm struct common_cache_entry_params common_params; 14857452Smarkm 14957452Smarkm HASHTABLE_HEAD(cache_ht_, cache_ht_item_) items; 15057452Smarkm size_t items_size; 15157452Smarkm 15257452Smarkm /* 15357452Smarkm * Entry always has the FIFO policy, that is used to eliminate old 15457452Smarkm * elements (the ones, with lifetime more than max_lifetime). Besides, 15557452Smarkm * user can specify another policy to be applied, when there are too 15657452Smarkm * many elements in the entry. So policies_size can be 1 or 2. 15756067Smarkm */ 15856067Smarkm struct cache_policy_ **policies; 15956067Smarkm size_t policies_size; 16056067Smarkm 16156067Smarkm void (*get_time_func)(struct timeval *); 16256067Smarkm}; 16356067Smarkm 16456067Smarkmstruct cache_mp_data_item_ { 16556067Smarkm char *value; 16656067Smarkm size_t value_size; 167 168 TAILQ_ENTRY(cache_mp_data_item_) entries; 169}; 170 171struct cache_mp_write_session_ 172{ 173 struct cache_mp_entry_ *parent_entry; 174 175 /* 176 * All items are accumulated in this queue. When the session is 177 * committed, they all will be copied to the multipart entry. 178 */ 179 TAILQ_HEAD(cache_mp_data_item_head, cache_mp_data_item_) items; 180 size_t items_size; 181 182 TAILQ_ENTRY(cache_mp_write_session_) entries; 183}; 184 185struct cache_mp_read_session_ 186{ 187 struct cache_mp_entry_ *parent_entry; 188 struct cache_mp_data_item_ *current_item; 189 190 TAILQ_ENTRY(cache_mp_read_session_) entries; 191}; 192 193struct cache_mp_entry_ 194{ 195 char *name; 196 struct cache_entry_params *params; 197 198 struct mp_cache_entry_params mp_params; 199 200 /* All opened write sessions */ 201 TAILQ_HEAD(write_sessions_head, cache_mp_write_session_) ws_head; 202 size_t ws_size; 203 204 /* All opened read sessions */ 205 TAILQ_HEAD(read_sessions_head, cache_mp_read_session_) rs_head; 206 size_t rs_size; 207 208 /* 209 * completed_write_session is the committed write sessions. All read 210 * sessions use data from it. If the completed_write_session is out of 211 * date, but still in use by some of the read sessions, the newly 212 * committed write session is stored in the pending_write_session. 213 * In such a case, completed_write_session will be substituted with 214 * pending_write_session as soon as it won't be used by any of 215 * the read sessions. 216 */ 217 struct cache_mp_write_session_ *completed_write_session; 218 struct cache_mp_write_session_ *pending_write_session; 219 struct timeval creation_time; 220 struct timeval last_request_time; 221 222 void (*get_time_func)(struct timeval *); 223}; 224 225struct cache_ 226{ 227 struct cache_params params; 228 229 struct cache_entry_ **entries; 230 size_t entries_capacity; 231 size_t entries_size; 232}; 233 234/* simple abstractions - for not to write "struct" every time */ 235typedef struct cache_ *cache; 236typedef struct cache_entry_ *cache_entry; 237typedef struct cache_mp_write_session_ *cache_mp_write_session; 238typedef struct cache_mp_read_session_ *cache_mp_read_session; 239 240#define INVALID_CACHE (NULL) 241#define INVALID_CACHE_ENTRY (NULL) 242#define INVALID_CACHE_MP_WRITE_SESSION (NULL) 243#define INVALID_CACHE_MP_READ_SESSION (NULL) 244 245/* 246 * NOTE: all cache operations are thread-unsafe. You must ensure thread-safety 247 * externally, by yourself. 248 */ 249 250/* cache initialization/destruction routines */ 251extern cache init_cache(struct cache_params const *); 252extern void destroy_cache(cache); 253 254/* cache entries manipulation routines */ 255extern int register_cache_entry(cache, struct cache_entry_params const *); 256extern int unregister_cache_entry(cache, const char *); 257extern cache_entry find_cache_entry(cache, const char *); 258 259/* read/write operations used on common entries */ 260extern int cache_read(cache_entry, const char *, size_t, char *, size_t *); 261extern int cache_write(cache_entry, const char *, size_t, char const *, size_t); 262 263/* read/write operations used on multipart entries */ 264extern cache_mp_write_session open_cache_mp_write_session(cache_entry); 265extern int cache_mp_write(cache_mp_write_session, char *, size_t); 266extern void abandon_cache_mp_write_session(cache_mp_write_session); 267extern void close_cache_mp_write_session(cache_mp_write_session); 268 269extern cache_mp_read_session open_cache_mp_read_session(cache_entry); 270extern int cache_mp_read(cache_mp_read_session, char *, size_t *); 271extern void close_cache_mp_read_session(cache_mp_read_session); 272 273/* transformation routines */ 274extern int transform_cache_entry(cache_entry, enum cache_transformation_t); 275extern int transform_cache_entry_part(cache_entry, enum cache_transformation_t, 276 const char *, size_t, enum part_position_t); 277 278#endif 279