1 /** 2 * @copyright 3 * ==================================================================== 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 * ==================================================================== 21 * @endcopyright 22 * 23 * @file svn_cache.h 24 * @brief In-memory cache implementation. 25 */ 26 27 28 #ifndef SVN_CACHE_H 29 #define SVN_CACHE_H 30 31 #include <apr_pools.h> 32 #include <apr_hash.h> 33 34 #include "svn_types.h" 35 #include "svn_error.h" 36 #include "svn_iter.h" 37 #include "svn_config.h" 38 #include "svn_string.h" 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif /* __cplusplus */ 43 44 45 46 /** 47 * @defgroup svn_cache__support In-memory caching 48 * @{ 49 */ 50 51 /** 52 * A function type for deserializing an object @a *out from the string 53 * @a data of length @a data_len into @a result_pool. It is legal and 54 * generally suggested that the deserialization will be done in-place, 55 * i.e. modify @a data directly and return it in @a *out. 56 */ 57 typedef svn_error_t *(*svn_cache__deserialize_func_t)(void **out, 58 void *data, 59 apr_size_t data_len, 60 apr_pool_t *result_pool); 61 62 /** 63 * A function type for deserializing an object @a *out from the string 64 * @a data of length @a data_len into @a result_pool. The extra information 65 * @a baton passed into can be used to deserialize only a specific part or 66 * sub-structure or to perform any other non-modifying operation that may 67 * not require the whole structure to be processed. 68 */ 69 typedef svn_error_t *(*svn_cache__partial_getter_func_t)(void **out, 70 const void *data, 71 apr_size_t data_len, 72 void *baton, 73 apr_pool_t *result_pool); 74 75 /** 76 * A function type for modifying an already deserialized in the @a *data 77 * buffer of length @a *data_len. Additional information of the modification 78 * to do will be provided in @a baton. The function may change the size of 79 * data buffer and may re-allocate it if necessary. In that case, the new 80 * values must be passed back in @a *data_len and @a *data, respectively. 81 * Allocations will be done from @a result_pool. 82 */ 83 typedef svn_error_t *(*svn_cache__partial_setter_func_t)(void **data, 84 apr_size_t *data_len, 85 void *baton, 86 apr_pool_t *result_pool); 87 88 /** 89 * A function type for serializing an object @a in into bytes. The 90 * function should allocate the serialized value in @a result_pool, set 91 * @a *data to the serialized value, and set @a *data_len to its length. 92 */ 93 typedef svn_error_t *(*svn_cache__serialize_func_t)(void **data, 94 apr_size_t *data_len, 95 void *in, 96 apr_pool_t *result_pool); 97 98 /** 99 * A function type for transforming or ignoring errors. @a scratch_pool may 100 * be used for temporary allocations. 101 */ 102 typedef svn_error_t *(*svn_cache__error_handler_t)(svn_error_t *err, 103 void *baton, 104 apr_pool_t *scratch_pool); 105 106 /** 107 * A wrapper around apr_memcache_t, provided essentially so that the 108 * Subversion public API doesn't depend on whether or not you have 109 * access to the APR memcache libraries. 110 */ 111 typedef struct svn_memcache_t svn_memcache_t; 112 113 /** 114 * An opaque structure representing a membuffer cache object. 115 */ 116 typedef struct svn_membuffer_t svn_membuffer_t; 117 118 /** 119 * Opaque type for an in-memory cache. 120 */ 121 typedef struct svn_cache__t svn_cache__t; 122 123 /** 124 * A structure containing typical statistics about a given cache instance. 125 * Use svn_cache__get_info() to get this data. Note that not all types 126 * of caches will be able to report complete and correct information. 127 */ 128 typedef struct svn_cache__info_t 129 { 130 /** A string identifying the cache instance. Usually a copy of the @a id 131 * or @a prefix parameter passed to the cache constructor. 132 */ 133 const char* id; 134 135 /** Number of getter calls (svn_cache__get() or svn_cache__get()). 136 */ 137 apr_uint64_t gets; 138 139 /** Number of getter calls that return data. 140 */ 141 apr_uint64_t hits; 142 143 /** Number of setter calls (svn_cache__set()). 144 */ 145 apr_uint64_t sets; 146 147 /** Number of function calls that returned an error. 148 */ 149 apr_uint64_t failures; 150 151 /** Size of the data currently stored in the cache. 152 * May be 0 if that information is not available. 153 */ 154 apr_uint64_t used_size; 155 156 /** Amount of memory currently reserved for cached data. 157 * Will be equal to @a used_size if no precise information is available. 158 */ 159 apr_uint64_t data_size; 160 161 /** Lower threshold of the total size of memory allocated to the cache and 162 * its index as well as management structures. The actual memory allocated 163 * by the cache may be larger. 164 */ 165 apr_uint64_t total_size; 166 167 /** Number of cache entries. 168 * May be 0 if that information is not available. 169 */ 170 apr_uint64_t used_entries; 171 172 /** Maximum numbers of cache entries. 173 * May be 0 if that information is not available. 174 */ 175 apr_uint64_t total_entries; 176 177 /** Number of index buckets with the given number of entries. 178 * Bucket sizes larger than the array will saturate into the 179 * highest array index. 180 */ 181 apr_uint64_t histogram[32]; 182 } svn_cache__info_t; 183 184 /** 185 * Creates a new cache in @a *cache_p. This cache will use @a pool 186 * for all of its storage needs. The elements in the cache will be 187 * indexed by keys of length @a klen, which may be APR_HASH_KEY_STRING 188 * if they are strings. Cached values will be copied in and out of 189 * the cache using @a serialize_func and @a deserialize_func, respectively. 190 * 191 * If @a deserialize_func is NULL, then the data is returned as an 192 * svn_stringbuf_t; if @a serialize_func is NULL, then the data is 193 * assumed to be an svn_stringbuf_t. 194 * 195 * The cache stores up to @a pages * @a items_per_page items at a 196 * time. The exact cache invalidation strategy is not defined here, 197 * but in general, a lower value for @a items_per_page means more 198 * memory overhead for the same number of items, but a higher value 199 * for @a items_per_page means more items are cleared at once. Both 200 * @a pages and @a items_per_page must be positive (though they both 201 * may certainly be 1). 202 * 203 * If @a thread_safe is true, and APR is compiled with threads, all 204 * accesses to the cache will be protected with a mutex. The @a id 205 * is a purely user-visible information that will allow coders to 206 * identify this cache instance in a #svn_cache__info_t struct. 207 * It does not influence the behavior of the cache itself. 208 * 209 * Note that NULL is a legitimate value for cache entries (and 210 * @a serialize_func will not be called on it). 211 * 212 * It is not safe for @a serialize_func nor @a deserialize_func to 213 * interact with the cache itself. 214 */ 215 svn_error_t * 216 svn_cache__create_inprocess(svn_cache__t **cache_p, 217 svn_cache__serialize_func_t serialize_func, 218 svn_cache__deserialize_func_t deserialize_func, 219 apr_ssize_t klen, 220 apr_int64_t pages, 221 apr_int64_t items_per_page, 222 svn_boolean_t thread_safe, 223 const char *id, 224 apr_pool_t *pool); 225 226 /** 227 * Creates a new cache in @a *cache_p, communicating to a memcached 228 * process via @a memcache. The elements in the cache will be indexed 229 * by keys of length @a klen, which may be APR_HASH_KEY_STRING if they 230 * are strings. Values will be serialized for memcached using @a 231 * serialize_func and deserialized using @a deserialize_func. Because 232 * the same memcached server may cache many different kinds of values, 233 * @a prefix should be specified to differentiate this cache from 234 * other caches. @a *cache_p will be allocated in @a result_pool. 235 * 236 * If @a deserialize_func is NULL, then the data is returned as an 237 * svn_stringbuf_t; if @a serialize_func is NULL, then the data is 238 * assumed to be an svn_stringbuf_t. 239 * 240 * These caches are always thread safe. 241 * 242 * These caches do not support svn_cache__iter. 243 * 244 * If Subversion was not built with apr_memcache support, always 245 * raises SVN_ERR_NO_APR_MEMCACHE. 246 */ 247 svn_error_t * 248 svn_cache__create_memcache(svn_cache__t **cache_p, 249 svn_memcache_t *memcache, 250 svn_cache__serialize_func_t serialize_func, 251 svn_cache__deserialize_func_t deserialize_func, 252 apr_ssize_t klen, 253 const char *prefix, 254 apr_pool_t *result_pool); 255 256 /** 257 * Given @a config, returns an APR memcached interface in @a 258 * *memcache_p allocated in @a result_pool if @a config contains entries in 259 * the SVN_CACHE_CONFIG_CATEGORY_MEMCACHED_SERVERS section describing 260 * memcached servers; otherwise, sets @a *memcache_p to NULL. Use 261 * @a scratch_pool for temporary allocations. 262 * 263 * If Subversion was not built with apr_memcache_support, then raises 264 * SVN_ERR_NO_APR_MEMCACHE if and only if @a config is configured to 265 * use memcache. 266 */ 267 svn_error_t * 268 svn_cache__make_memcache_from_config(svn_memcache_t **memcache_p, 269 svn_config_t *config, 270 apr_pool_t *result_pool, 271 apr_pool_t *scratch_pool); 272 273 /** 274 * Creates a new membuffer cache object in @a *cache. It will contain 275 * up to @a total_size bytes of data, using @a directory_size bytes 276 * for index information and the remainder for serialized objects. 277 * 278 * Since each index entry is about 50 bytes long, 1 to 10 percent of 279 * the @a total_size should be allocated to the @a directory_size, 280 * depending on the average serialized object size. Higher percentages 281 * will generally result in higher hit rates and reduced conflict 282 * resolution overhead. 283 * 284 * The cache will be split into @a segment_count segments of equal size. 285 * A higher number reduces lock contention but also limits the maximum 286 * cachable item size. If it is not a power of two, it will be rounded 287 * down to next lower power of two. Also, there is an implementation 288 * specific upper limit and the setting will be capped there automatically. 289 * If the number is 0, a default will be derived from @a total_size. 290 * 291 * If access to the resulting cache object is guaranteed to be serialized, 292 * @a thread_safe may be set to @c FALSE for maximum performance. 293 * 294 * There is no limit on the number of threads reading a given cache segment 295 * concurrently. Writes, however, need an exclusive lock on the respective 296 * segment. @a allow_blocking_writes controls contention is handled here. 297 * If set to TRUE, writes will wait until the lock becomes available, i.e. 298 * reads should be short. If set to FALSE, write attempts will be ignored 299 * (no data being written to the cache) if some reader or another writer 300 * currently holds the segment lock. 301 * 302 * Allocations will be made in @a result_pool, in particular the data buffers. 303 */ 304 svn_error_t * 305 svn_cache__membuffer_cache_create(svn_membuffer_t **cache, 306 apr_size_t total_size, 307 apr_size_t directory_size, 308 apr_size_t segment_count, 309 svn_boolean_t thread_safe, 310 svn_boolean_t allow_blocking_writes, 311 apr_pool_t *result_pool); 312 313 /** 314 * @defgroup Standard priority classes for #svn_cache__create_membuffer_cache. 315 * @{ 316 */ 317 318 /** 319 * Data in this priority class should not be removed from the cache unless 320 * absolutely necessary. Use of this should be very restricted. 321 */ 322 #define SVN_CACHE__MEMBUFFER_HIGH_PRIORITY 10000 323 324 /** 325 * Data in this priority class has a good chance to remain in cache unless 326 * there is more data in this class than the cache's capacity. Use of this 327 * as the default for all information that is costly to fetch from disk. 328 */ 329 #define SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY 1000 330 331 /** 332 * Data in this priority class will be removed as soon as the cache starts 333 * filling up. Use of this for ephemeral data that can easily be acquired 334 * again from other sources. 335 */ 336 #define SVN_CACHE__MEMBUFFER_LOW_PRIORITY 100 337 338 /** @} */ 339 340 /** 341 * Creates a new cache in @a *cache_p, storing the data in a potentially 342 * shared @a membuffer object. The elements in the cache will be indexed 343 * by keys of length @a klen, which may be APR_HASH_KEY_STRING if they 344 * are strings. Values will be serialized for the memcache using @a 345 * serialize_func and deserialized using @a deserialize_func. Because 346 * the same memcache object may cache many different kinds of values 347 * form multiple caches, @a prefix should be specified to differentiate 348 * this cache from other caches. All entries written through this cache 349 * interface will be assigned into the given @a priority class. @a *cache_p 350 * will be allocated in @a result_pool. @a scratch_pool is used for 351 * temporary allocations. 352 * 353 * If @a deserialize_func is NULL, then the data is returned as an 354 * svn_stringbuf_t; if @a serialize_func is NULL, then the data is 355 * assumed to be an svn_stringbuf_t. 356 * 357 * If @a thread_safe is true, and APR is compiled with threads, all 358 * accesses to the cache will be protected with a mutex, if the shared 359 * @a membuffer has also been created with thread_safe flag set. 360 * 361 * If @a short_lived is set, assume that the data stored through this 362 * cache will probably only be needed for a short period of time. 363 * Typically, some UUID is used as part of the prefix in that scenario. 364 * This flag is a mere hint and does not affect functionality. 365 * 366 * These caches do not support svn_cache__iter. 367 */ 368 svn_error_t * 369 svn_cache__create_membuffer_cache(svn_cache__t **cache_p, 370 svn_membuffer_t *membuffer, 371 svn_cache__serialize_func_t serialize, 372 svn_cache__deserialize_func_t deserialize, 373 apr_ssize_t klen, 374 const char *prefix, 375 apr_uint32_t priority, 376 svn_boolean_t thread_safe, 377 svn_boolean_t short_lived, 378 apr_pool_t *result_pool, 379 apr_pool_t *scratch_pool); 380 381 /** 382 * Creates a null-cache instance in @a *cache_p, allocated from 383 * @a result_pool. The given @c id is the only data stored in it and can 384 * be retrieved through svn_cache__get_info(). 385 * 386 * The cache object will immediately evict (reject) any data being added 387 * to it and will always report as empty. 388 */ 389 svn_error_t * 390 svn_cache__create_null(svn_cache__t **cache_p, 391 const char *id, 392 apr_pool_t *result_pool); 393 394 /** 395 * Sets @a handler to be @a cache's error handling routine. If any 396 * error is returned from a call to svn_cache__get or svn_cache__set, @a 397 * handler will be called with @a baton and the error, and the 398 * original function will return whatever error @a handler returns 399 * instead (possibly SVN_NO_ERROR); @a handler will receive the pool 400 * passed to the svn_cache_* function. @a scratch_pool is used for temporary 401 * allocations. 402 */ 403 svn_error_t * 404 svn_cache__set_error_handler(svn_cache__t *cache, 405 svn_cache__error_handler_t handler, 406 void *baton, 407 apr_pool_t *scratch_pool); 408 409 /** 410 * Returns @c TRUE if the @a cache supports objects of the given @a size. 411 * There is no guarantee, that svn_cache__set() will actually store the 412 * respective object in that case. However, a @c FALSE return value indicates 413 * that an attempt to cache the item will either fail or impair the overall 414 * cache performance. @c FALSE will also be returned if @a cache is @c NULL. 415 */ 416 svn_boolean_t 417 svn_cache__is_cachable(svn_cache__t *cache, 418 apr_size_t size); 419 420 #define SVN_CACHE_CONFIG_CATEGORY_MEMCACHED_SERVERS "memcached-servers" 421 422 /** 423 * Fetches a value indexed by @a key from @a cache into @a *value, 424 * setting @a *found to TRUE iff it is in the cache and FALSE if it is 425 * not found. @a key may be NULL in which case @a *found will be 426 * FALSE. The value is copied into @a result_pool using the deserialize 427 * function provided to the cache's constructor. 428 */ 429 svn_error_t * 430 svn_cache__get(void **value, 431 svn_boolean_t *found, 432 svn_cache__t *cache, 433 const void *key, 434 apr_pool_t *result_pool); 435 436 /** 437 * Looks for an entry indexed by @a key in @a cache, setting @a *found 438 * to TRUE if an entry has been found and FALSE otherwise. @a key may be 439 * NULL in which case @a *found will be FALSE. Temporary allocations will 440 * be made from @a scratch_pool. 441 */ 442 svn_error_t * 443 svn_cache__has_key(svn_boolean_t *found, 444 svn_cache__t *cache, 445 const void *key, 446 apr_pool_t *scratch_pool); 447 448 /** 449 * Stores the value @a value under the key @a key in @a cache. Uses @a 450 * scratch_pool for temporary allocations. The cache makes copies of 451 * @a key and @a value if necessary (that is, @a key and @a value may 452 * have shorter lifetimes than the cache). @a key may be NULL in which 453 * case the cache will remain unchanged. 454 * 455 * If there is already a value for @a key, this will replace it. Bear 456 * in mind that in some circumstances this may leak memory (that is, 457 * the cache's copy of the previous value may not be immediately 458 * cleared); it is only guaranteed to not leak for caches created with 459 * @a items_per_page equal to 1. 460 */ 461 svn_error_t * 462 svn_cache__set(svn_cache__t *cache, 463 const void *key, 464 void *value, 465 apr_pool_t *scratch_pool); 466 467 /** 468 * Iterates over the elements currently in @a cache, calling @a func 469 * for each one until there are no more elements or @a func returns an 470 * error. Uses @a scratch_pool for temporary allocations. 471 * 472 * If @a completed is not NULL, then on return - if @a func returns no 473 * errors - @a *completed will be set to @c TRUE. 474 * 475 * If @a func returns an error other than @c SVN_ERR_ITER_BREAK, that 476 * error is returned. When @a func returns @c SVN_ERR_ITER_BREAK, 477 * iteration is interrupted, but no error is returned and @a 478 * *completed is set to @c FALSE. (The error handler set by 479 * svn_cache__set_error_handler is not used for svn_cache__iter.) 480 * 481 * It is not legal to perform any other cache operations on @a cache 482 * inside @a func. 483 * 484 * svn_cache__iter is not supported by all cache implementations; see 485 * the svn_cache__create_* function for details. 486 */ 487 svn_error_t * 488 svn_cache__iter(svn_boolean_t *completed, 489 svn_cache__t *cache, 490 svn_iter_apr_hash_cb_t func, 491 void *baton, 492 apr_pool_t *scratch_pool); 493 494 /** 495 * Similar to svn_cache__get() but will call a specific de-serialization 496 * function @a func. @a found will be set depending on whether the @a key 497 * has been found. Even if that reports @c TRUE, @a value may still return 498 * a @c NULL pointer depending on the logic inside @a func. For a @a NULL 499 * @a key, no data will be found. @a value will be allocated in 500 * @a result_pool. 501 */ 502 svn_error_t * 503 svn_cache__get_partial(void **value, 504 svn_boolean_t *found, 505 svn_cache__t *cache, 506 const void *key, 507 svn_cache__partial_getter_func_t func, 508 void *baton, 509 apr_pool_t *result_pool); 510 511 /** 512 * Find the item identified by @a key in the @a cache. If it has been found, 513 * call @a func for it and @a baton to potentially modify the data. Changed 514 * data will be written back to the cache. If the item cannot be found, 515 * or if @a key is NULL, @a func does not get called. @a scratch_pool is 516 * used for temporary allocations. 517 */ 518 svn_error_t * 519 svn_cache__set_partial(svn_cache__t *cache, 520 const void *key, 521 svn_cache__partial_setter_func_t func, 522 void *baton, 523 apr_pool_t *scratch_pool); 524 525 /** 526 * Collect all available usage statistics on the cache instance @a cache 527 * and write the data into @a info. If @a reset has been set, access 528 * counters will be reset right after copying the statistics info. 529 * @a result_pool will be used for allocations. 530 */ 531 svn_error_t * 532 svn_cache__get_info(svn_cache__t *cache, 533 svn_cache__info_t *info, 534 svn_boolean_t reset, 535 apr_pool_t *result_pool); 536 537 /** 538 * Return the information given in @a info formatted as a multi-line string. 539 * If @a access_only has been set, size and fill-level statistics will be 540 * omitted. Allocations take place in @a result_pool. 541 */ 542 svn_string_t * 543 svn_cache__format_info(const svn_cache__info_t *info, 544 svn_boolean_t access_only, 545 apr_pool_t *result_pool); 546 547 /** 548 * Access the process-global (singleton) membuffer cache. The first call 549 * will automatically allocate the cache using the current cache config. 550 * NULL will be returned if the desired cache size is 0. 551 * 552 * @since New in 1.7. 553 */ 554 struct svn_membuffer_t * 555 svn_cache__get_global_membuffer_cache(void); 556 557 /** 558 * Return total access and size stats over all membuffer caches as they 559 * share the underlying data buffer. The result will be allocated in POOL. 560 */ 561 svn_cache__info_t * 562 svn_cache__membuffer_get_global_info(apr_pool_t *pool); 563 564 /** 565 * Remove all current contents from CACHE. 566 * 567 * NOTE: In a multi-threaded environment, new contents may have been put 568 * into the cache by the time this function returns. 569 */ 570 svn_error_t * 571 svn_cache__membuffer_clear(svn_membuffer_t *cache); 572 573 /** @} */ 574 575 576 #ifdef __cplusplus 577 } 578 #endif /* __cplusplus */ 579 580 #endif /* SVN_CACHE_H */ 581