MySQL 8.3.0
Source Code Documentation
lf.h
Go to the documentation of this file.
1/* Copyright (c) 2007, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef _lf_h
24#define _lf_h
25
26/**
27 @file include/lf.h
28*/
29
30#include "my_config.h"
31
32#include <stddef.h>
33#include <sys/types.h>
34
35#include <atomic>
36
37#include "my_inttypes.h"
38#include "my_macros.h"
41#include "sql_string.h"
42
43struct CHARSET_INFO;
44
45/*
46 wait-free dynamic array, see lf_dynarray.c
47
48 4 levels of 256 elements each mean 4311810304 elements in an array - it
49 should be enough for a while
50*/
51#define LF_DYNARRAY_LEVEL_LENGTH 256
52#define LF_DYNARRAY_LEVELS 4
53
55 std::atomic<void *> level[LF_DYNARRAY_LEVELS];
57};
58
59typedef int (*lf_dynarray_func)(void *, void *);
60
61void lf_dynarray_init(LF_DYNARRAY *array, uint element_size);
63void *lf_dynarray_value(LF_DYNARRAY *array, uint idx);
64void *lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx);
65int lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg);
66
67/*
68 pin manager for memory allocator, lf_alloc-pin.c
69*/
70
71#define LF_PINBOX_PINS 4
72#define LF_PURGATORY_SIZE 10
73
74typedef void lf_pinbox_free_func(void *, void *, void *);
75
76struct LF_PINBOX {
81 std::atomic<uint32> pinstack_top_ver; /* this is a versioned pointer */
82 std::atomic<uint32> pins_in_array; /* number of elements in array */
83};
84
85struct LF_PINS {
86 std::atomic<void *> pin[LF_PINBOX_PINS];
88 void *purgatory;
90 std::atomic<uint32> link;
91 /* we want sizeof(LF_PINS) to be 64 to avoid false sharing */
92#if SIZEOF_INT * 2 + SIZEOF_CHARP * (LF_PINBOX_PINS + 2) != 64
93 char pad[64 - sizeof(uint32) * 2 - sizeof(void *) * (LF_PINBOX_PINS + 2)];
94#endif
95};
96
97/*
98 compile-time assert, to require "no less than N" pins
99 it's enough if it'll fail on at least one compiler, so
100 we'll enable it on GCC only, which supports zero-length arrays.
101*/
102#if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
103#define LF_REQUIRE_PINS(N) \
104 static const char require_pins[LF_PINBOX_PINS - N] [[maybe_unused]]; \
105 static const int LF_NUM_PINS_IN_THIS_FILE = N;
106#else
107#define LF_REQUIRE_PINS(N)
108#endif
109
110static inline void lf_pin(LF_PINS *pins, int pin, void *addr) {
111#if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
112 assert(pin < LF_NUM_PINS_IN_THIS_FILE);
113#endif
114 pins->pin[pin].store(addr);
115}
116
117static inline void lf_unpin(LF_PINS *pins, int pin) {
118#if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
119 assert(pin < LF_NUM_PINS_IN_THIS_FILE);
120#endif
121 pins->pin[pin].store(nullptr);
122}
123
124void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset,
125 lf_pinbox_free_func *free_func, void *free_func_arg);
126void lf_pinbox_destroy(LF_PINBOX *pinbox);
128void lf_pinbox_put_pins(LF_PINS *pins);
129void lf_pinbox_free(LF_PINS *pins, void *addr);
130
131/*
132 memory allocator, lf_alloc-pin.c
133*/
134typedef void lf_allocator_func(uchar *);
135
138 std::atomic<uchar *> top;
140 std::atomic<uint32> mallocs;
141 lf_allocator_func *constructor; /* called, when an object is malloc()'ed */
142 lf_allocator_func *destructor; /* called, when an object is free()'d */
143};
144
145#define lf_alloc_init(A, B, C) lf_alloc_init2(A, B, C, NULL, NULL)
146void lf_alloc_init2(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset,
148void lf_alloc_destroy(LF_ALLOCATOR *allocator);
149uint lf_alloc_pool_count(LF_ALLOCATOR *allocator);
150
151static inline void lf_alloc_direct_free(LF_ALLOCATOR *allocator, void *addr) {
152 if (allocator->destructor) {
153 allocator->destructor((uchar *)addr);
154 }
155 my_free(addr);
156}
157
158void *lf_alloc_new(LF_PINS *pins);
159
160struct LF_HASH;
161
162typedef uint lf_hash_func(const LF_HASH *, const uchar *, size_t);
163typedef int lf_cmp_func(const uchar *key1, size_t key1_length,
164 const uchar *key2, size_t key2_length);
165typedef void lf_hash_init_func(uchar *dst, const uchar *src);
166
167#define LF_HASH_UNIQUE 1
168#define MY_LF_ERRPTR ((void *)(intptr)1)
169
170/* lf_hash overhead per element (that is, sizeof(LF_SLIST) */
172
173/**
174 Callback for extracting key and key length from user data in a LF_HASH.
175
176 @param arg Pointer to user data.
177 @param[out] length Store key length here.
178 @return Pointer to key to be hashed.
179
180 @note Was my_hash_get_key, with lots of C-style casting when calling
181 my_hash_init. Renamed to force build error (since signature changed)
182 in case someone keeps following that coding style.
183 */
184typedef const uchar *(*hash_get_key_function)(const uchar *arg, size_t *length);
185
186struct LF_HASH {
187 LF_DYNARRAY array; /* hash itself */
188 LF_ALLOCATOR alloc; /* allocator for elements */
190 CHARSET_INFO *charset; /* see HASH */
192 lf_cmp_func *cmp_function; /* Compare two keys. */
193 uint key_offset, key_length; /* see HASH */
194 uint element_size; /* size of memcpy'ed area on insert */
195 uint flags; /* LF_HASH_UNIQUE, etc */
196 std::atomic<int32> size; /* size of array */
197 std::atomic<int32> count; /* number of elements in the hash */
198 /**
199 "Initialize" hook - called to finish initialization of object provided by
200 LF_ALLOCATOR (which is pointed by "dst" parameter) and set element key
201 from object passed as parameter to lf_hash_insert (pointed by "src"
202 parameter). Allows to use LF_HASH with objects which are not "trivially
203 copyable".
204 NULL value means that element initialization is carried out by copying
205 first element_size bytes from object which provided as parameter to
206 lf_hash_insert.
207 */
209};
210
211#define lf_hash_init(A, B, C, D, E, F, G) \
212 lf_hash_init2(A, B, C, D, E, F, G, NULL, NULL, NULL, NULL)
213
214void lf_hash_init2(LF_HASH *hash, uint element_size, uint flags,
215 uint key_offset, uint key_length,
217 lf_hash_func *hash_function, lf_allocator_func *ctor,
219
220void lf_hash_init3(LF_HASH *hash, uint element_size, uint flags,
221 hash_get_key_function get_key, lf_hash_func *hash_function,
222 lf_cmp_func *cmp_function, lf_allocator_func *ctor,
224
225void lf_hash_destroy(LF_HASH *hash);
226int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data);
227void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key,
228 uint keylen);
229int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
230
231static inline LF_PINS *lf_hash_get_pins(LF_HASH *hash) {
232 return lf_pinbox_get_pins(&hash->alloc.pinbox);
233}
234
235static inline void lf_hash_put_pins(LF_PINS *pins) { lf_pinbox_put_pins(pins); }
236
237static inline void lf_hash_search_unpin(LF_PINS *pins) { lf_unpin(pins, 2); }
238
239typedef int lf_hash_match_func(const uchar *el, void *arg);
240void *lf_hash_random_match(LF_HASH *hash, LF_PINS *pins,
241 lf_hash_match_func *match, uint rand_val,
242 void *match_arg);
243
244#endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
static int flags[50]
Definition: hp_test1.cc:39
static uint16 key1[1001]
Definition: hp_test2.cc:49
void lf_hash_init_func(uchar *dst, const uchar *src)
Definition: lf.h:165
void lf_allocator_func(uchar *)
Definition: lf.h:134
uint lf_hash_func(const LF_HASH *, const uchar *, size_t)
Definition: lf.h:162
static void lf_unpin(LF_PINS *pins, int pin)
Definition: lf.h:117
static void lf_alloc_direct_free(LF_ALLOCATOR *allocator, void *addr)
Definition: lf.h:151
static void lf_pin(LF_PINS *pins, int pin, void *addr)
Definition: lf.h:110
void lf_alloc_destroy(LF_ALLOCATOR *allocator)
Definition: lf_alloc-pin.cc:418
int lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg)
Definition: lf_dynarray.cc:226
#define LF_PINBOX_PINS
Definition: lf.h:71
void lf_pinbox_put_pins(LF_PINS *pins)
Definition: lf_alloc-pin.cc:218
void lf_pinbox_free_func(void *, void *, void *)
Definition: lf.h:74
void lf_pinbox_destroy(LF_PINBOX *pinbox)
Definition: lf_alloc-pin.cc:151
LF_PINS * lf_pinbox_get_pins(LF_PINBOX *pinbox)
Definition: lf_alloc-pin.cc:165
void * lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
Find hash element corresponding to the key.
Definition: lf_hash.cc:722
const uchar *(* hash_get_key_function)(const uchar *arg, size_t *length)
Callback for extracting key and key length from user data in a LF_HASH.
Definition: lf.h:184
int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
Definition: lf_hash.cc:669
void lf_pinbox_free(LF_PINS *pins, void *addr)
Definition: lf_alloc-pin.cc:272
static void lf_hash_search_unpin(LF_PINS *pins)
Definition: lf.h:237
void lf_hash_init3(LF_HASH *hash, uint element_size, uint flags, hash_get_key_function get_key, lf_hash_func *hash_function, lf_cmp_func *cmp_function, lf_allocator_func *ctor, lf_allocator_func *dtor, lf_hash_init_func *init)
Definition: lf_hash.cc:572
void lf_alloc_init2(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset, lf_allocator_func *ctor, lf_allocator_func *dtor)
Initialize lock-free allocator.
Definition: lf_alloc-pin.cc:396
void lf_hash_destroy(LF_HASH *hash)
Definition: lf_hash.cc:580
int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data)
Definition: lf_hash.cc:615
static LF_PINS * lf_hash_get_pins(LF_HASH *hash)
Definition: lf.h:231
void lf_dynarray_destroy(LF_DYNARRAY *array)
Definition: lf_dynarray.cc:85
int lf_cmp_func(const uchar *key1, size_t key1_length, const uchar *key2, size_t key2_length)
Definition: lf.h:163
void lf_hash_init2(LF_HASH *hash, uint element_size, uint flags, uint key_offset, uint key_length, hash_get_key_function get_key, CHARSET_INFO *charset, lf_hash_func *hash_function, lf_allocator_func *ctor, lf_allocator_func *dtor, lf_hash_init_func *init)
Definition: lf_hash.cc:563
void * lf_dynarray_value(LF_DYNARRAY *array, uint idx)
Definition: lf_dynarray.cc:174
#define LF_DYNARRAY_LEVELS
Definition: lf.h:52
static void lf_hash_put_pins(LF_PINS *pins)
Definition: lf.h:235
int(* lf_dynarray_func)(void *, void *)
Definition: lf.h:59
void * lf_alloc_new(LF_PINS *pins)
Definition: lf_alloc-pin.cc:439
uint lf_alloc_pool_count(LF_ALLOCATOR *allocator)
Definition: lf_alloc-pin.cc:475
void lf_dynarray_init(LF_DYNARRAY *array, uint element_size)
Definition: lf_dynarray.cc:64
void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset, lf_pinbox_free_func *free_func, void *free_func_arg)
Definition: lf_alloc-pin.cc:139
MYSQL_PLUGIN_IMPORT const int LF_HASH_OVERHEAD
Definition: lf_hash.cc:71
void * lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx)
Definition: lf_dynarray.cc:114
void * lf_hash_random_match(LF_HASH *hash, LF_PINS *pins, lf_hash_match_func *match, uint rand_val, void *match_arg)
Find random hash element which satisfies condition specified by match function.
Definition: lf_hash.cc:774
int lf_hash_match_func(const uchar *el, void *arg)
Definition: lf.h:239
Some integer typedefs for easier portability.
unsigned char uchar
Definition: my_inttypes.h:51
uint32_t uint32
Definition: my_inttypes.h:66
Some common macros.
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:80
#define MYSQL_PLUGIN_IMPORT
Definition: my_sharedlib.h:70
Instrumentation helpers for statements.
const std::string charset("charset")
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
required string key
Definition: replication_asynchronous_connection_failover.proto:59
Our own string classes, used pervasively throughout the executor.
Definition: m_ctype.h:422
Definition: lf.h:136
lf_allocator_func * destructor
Definition: lf.h:142
uint element_size
Definition: lf.h:139
std::atomic< uint32 > mallocs
Definition: lf.h:140
lf_allocator_func * constructor
Definition: lf.h:141
LF_PINBOX pinbox
Definition: lf.h:137
std::atomic< uchar * > top
Definition: lf.h:138
Definition: lf.h:54
uint size_of_element
Definition: lf.h:56
std::atomic< void * > level[LF_DYNARRAY_LEVELS]
Definition: lf.h:55
Definition: lf.h:186
CHARSET_INFO * charset
Definition: lf.h:190
uint element_size
Definition: lf.h:194
std::atomic< int32 > size
Definition: lf.h:196
hash_get_key_function get_key
Definition: lf.h:189
lf_hash_init_func * initialize
"Initialize" hook - called to finish initialization of object provided by LF_ALLOCATOR (which is poin...
Definition: lf.h:208
lf_hash_func * hash_function
Definition: lf.h:191
uint key_length
Definition: lf.h:193
LF_DYNARRAY array
Definition: lf.h:187
uint key_offset
Definition: lf.h:193
uint flags
Definition: lf.h:195
std::atomic< int32 > count
Definition: lf.h:197
LF_ALLOCATOR alloc
Definition: lf.h:188
lf_cmp_func * cmp_function
Definition: lf.h:192
Definition: lf.h:76
lf_pinbox_free_func * free_func
Definition: lf.h:78
LF_DYNARRAY pinarray
Definition: lf.h:77
void * free_func_arg
Definition: lf.h:79
uint free_ptr_offset
Definition: lf.h:80
std::atomic< uint32 > pins_in_array
Definition: lf.h:82
std::atomic< uint32 > pinstack_top_ver
Definition: lf.h:81
Definition: lf.h:85
char pad[64 - sizeof(uint32) *2 - sizeof(void *) *(LF_PINBOX_PINS+2)]
Definition: lf.h:93
uint32 purgatory_count
Definition: lf.h:89
LF_PINBOX * pinbox
Definition: lf.h:87
std::atomic< void * > pin[LF_PINBOX_PINS]
Definition: lf.h:86
void * purgatory
Definition: lf.h:88
std::atomic< uint32 > link
Definition: lf.h:90