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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
|
#ifndef INCLUDES_TARANTOOL_BOX_VY_CACHE_H
#define INCLUDES_TARANTOOL_BOX_VY_CACHE_H
/*
* Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdint.h>
#include <stdbool.h>
#include <small/rlist.h>
#include "iterator_type.h"
#include "vy_stmt.h" /* for comparators */
#include "vy_read_view.h"
#include "vy_stat.h"
#include "small/mempool.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
struct vy_history;
/**
* A record in tuple cache
*/
struct vy_cache_node {
/* Cache */
struct vy_cache *cache;
/* Statement in cache */
struct vy_entry entry;
/* Link in LRU list */
struct rlist in_lru;
/* VY_CACHE_LEFT_LINKED and/or VY_CACHE_RIGHT_LINKED, see
* description of them for more information */
uint32_t flags;
/* Number of parts in key when the value was the first in EQ search */
uint8_t left_boundary_level;
/* Number of parts in key when the value was the last in EQ search */
uint8_t right_boundary_level;
};
/**
* Internal comparator (1) for BPS tree.
*/
static inline int
vy_cache_tree_cmp(struct vy_cache_node *a,
struct vy_cache_node *b, struct key_def *cmp_def)
{
return vy_entry_compare(a->entry, b->entry, cmp_def);
}
/**
* Internal comparator (2) for BPS tree.
*/
static inline int
vy_cache_tree_key_cmp(struct vy_cache_node *a, struct vy_entry b,
struct key_def *cmp_def)
{
return vy_entry_compare(a->entry, b, cmp_def);
}
#define VY_CACHE_TREE_EXTENT_SIZE (16 * 1024)
#define BPS_TREE_NAME vy_cache_tree
#define BPS_TREE_BLOCK_SIZE 512
#define BPS_TREE_EXTENT_SIZE VY_CACHE_TREE_EXTENT_SIZE
#define BPS_TREE_COMPARE(a, b, cmp_def) vy_cache_tree_cmp(a, b, cmp_def)
#define BPS_TREE_COMPARE_KEY(a, b, cmp_def) vy_cache_tree_key_cmp(a, b, cmp_def)
#define bps_tree_elem_t struct vy_cache_node *
#define bps_tree_key_t struct vy_entry
#define bps_tree_arg_t struct key_def *
#define BPS_TREE_IS_IDENTICAL(a, b) vy_entry_is_equal(a->entry, b->entry)
#include "salad/bps_tree.h"
#undef BPS_TREE_NAME
#undef BPS_TREE_BLOCK_SIZE
#undef BPS_TREE_EXTENT_SIZE
#undef BPS_TREE_COMPARE
#undef BPS_TREE_COMPARE_KEY
#undef bps_tree_elem_t
#undef bps_tree_key_t
#undef bps_tree_arg_t
#undef BPS_TREE_IS_IDENTICAL
/**
* Environment of the cache
*/
struct vy_cache_env {
/** Common LRU list of read cache. The first element is the newest */
struct rlist cache_lru;
/** Common mempool for vy_cache_node struct */
struct mempool cache_node_mempool;
/** Size of memory occupied by cached tuples */
size_t mem_used;
/** Max memory size that can be used for cache */
size_t mem_quota;
};
/**
* Initialize common cache environment.
* @param e - the environment.
* @param slab_cache - source of memory.
*/
void
vy_cache_env_create(struct vy_cache_env *env, struct slab_cache *slab_cache);
/**
* Destroy and free resources of cache environment.
* @param e - the environment.
*/
void
vy_cache_env_destroy(struct vy_cache_env *e);
/**
* Set memory limit for the cache.
* @param e - the environment.
* @param quota - memory limit for the cache.
*
* This function blocks until it manages to free enough memory
* to fit in the new limit.
*/
void
vy_cache_env_set_quota(struct vy_cache_env *e, size_t quota);
/**
* Tuple cache (of one particular LSM tree)
*/
struct vy_cache {
/**
* Key definition for tuple comparison, includes primary
* key parts
*/
struct key_def *cmp_def;
/** Set if this cache is for a primary index. */
bool is_primary;
/* Tree of cache entries */
struct vy_cache_tree cache_tree;
/* The vesrion of state of cache_tree. Increments on every change */
uint32_t version;
/* Saved pointer to common cache environment */
struct vy_cache_env *env;
/* Cache statistics. */
struct vy_cache_stat stat;
};
/**
* Allocate and initialize tuple cache.
* @param env - pointer to common cache environment.
* @param cmp_def - key definition for tuple comparison.
* @param is_primary - set if cache is for primary index
*/
void
vy_cache_create(struct vy_cache *cache, struct vy_cache_env *env,
struct key_def *cmp_def, bool is_primary);
/**
* Destroy and deallocate tuple cache.
* @param cache - pointer to tuple cache to destroy.
*/
void
vy_cache_destroy(struct vy_cache *cache);
/**
* Add a value to the cache. Can be used only if the reader read the latest
* data (vlsn = INT64_MAX).
* @param cache - pointer to tuple cache.
* @param curr - statement that was recently read and should be added to the
* cache.
* @param prev - previous statement that was read by the reader in one
* sequence (by one iterator).
* @param direction - direction in which the reader (iterator) observes data,
* +1 - forward, -1 - backward.
*/
void
vy_cache_add(struct vy_cache *cache, struct vy_entry curr,
struct vy_entry prev, struct vy_entry key,
enum iterator_type order);
/**
* Find value in cache.
* @return A tuple equal to key or NULL if not found.
*/
struct vy_entry
vy_cache_get(struct vy_cache *cache, struct vy_entry key);
/**
* Invalidate possibly cached value due to its overwriting
* @param cache - pointer to tuple cache.
* @param entry - overwritten statement.
* @param[out] deleted - If not NULL, then is set to deleted
* statement.
*/
void
vy_cache_on_write(struct vy_cache *cache, struct vy_entry entry,
struct vy_entry *deleted);
/**
* Cache iterator
*/
struct vy_cache_iterator {
/* The cache */
struct vy_cache *cache;
/**
* Iterator type, that specifies direction, start position and stop
* criteria if the key is not specified, GT and EQ are changed to
* GE, LT to LE for beauty.
*/
enum iterator_type iterator_type;
/* Search key data in terms of vinyl, vy_entry_compare argument */
struct vy_entry key;
/* LSN visibility, iterator shows values with lsn <= vlsn */
const struct vy_read_view **read_view;
/* State of iterator */
/* Current position in tree */
struct vy_cache_tree_iterator curr_pos;
/* stmt in current position in tree */
struct vy_entry curr;
/* Last version of cache */
uint32_t version;
/* Is false until first .._get or .._next_.. method is called */
bool search_started;
};
/**
* Open an iterator over cache.
* @param itr - iterator to open.
* @param cache - the cache.
* @param iterator_type - iterator type (EQ, GT, GE, LT, LE or ALL)
* @param key - search key data in terms of vinyl, vy_entry_compare argument
* @param vlsn - LSN visibility, iterator shows values with lsn <= vlsn
*/
void
vy_cache_iterator_open(struct vy_cache_iterator *itr, struct vy_cache *cache,
enum iterator_type iterator_type, struct vy_entry key,
const struct vy_read_view **rv);
/**
* Advance a cache iterator to the next key.
* The key history is returned in @history (empty if EOF).
* @stop flag is set if a chain was found in the cache
* and so there shouldn't be statements preceding the
* returned statement in memory or on disk. The function
* returns 0 on success, -1 on memory allocation error.
*/
NODISCARD int
vy_cache_iterator_next(struct vy_cache_iterator *itr,
struct vy_history *history, bool *stop);
/**
* Advance a cache iterator to the key following @last.
* The key history is returned in @history (empty if EOF).
* Returns 0 on success, -1 on memory allocation error.
*/
NODISCARD int
vy_cache_iterator_skip(struct vy_cache_iterator *itr, struct vy_entry last,
struct vy_history *history, bool *stop);
/**
* Check if a cache iterator was invalidated and needs to be restored.
* If it does, set the iterator position to the first key following
* @last and return 1, otherwise return 0. Returns -1 on memory
* allocation error.
*/
NODISCARD int
vy_cache_iterator_restore(struct vy_cache_iterator *itr, struct vy_entry last,
struct vy_history *history, bool *stop);
/**
* Close a cache iterator.
*/
void
vy_cache_iterator_close(struct vy_cache_iterator *itr);
#if defined(__cplusplus)
} /* extern "C" { */
#endif /* defined(__cplusplus) */
#endif /* INCLUDES_TARANTOOL_BOX_VY_CACHE_H */
|