[go: up one dir, main page]

File: vy_cache.h

package info (click to toggle)
tarantool 2.6.0-1.4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 85,412 kB
  • sloc: ansic: 513,775; cpp: 69,493; sh: 25,650; python: 19,190; perl: 14,973; makefile: 4,178; yacc: 1,329; sql: 1,074; pascal: 620; ruby: 190; awk: 18; lisp: 7
file content (311 lines) | stat: -rw-r--r-- 9,302 bytes parent folder | download | duplicates (3)
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 */