1 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
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 /* Dynamic hashing of record with different key-length */
24 
25 #ifndef _hash_h
26 #define _hash_h
27 
28 #include "my_global.h"                          /* uchar */
29 #include "my_sys.h"                             /* DYNAMIC_ARRAY */
30 
31 /*
32   This forward declaration is used from C files where the real
33   definition is included before.  Since C does not allow repeated
34   typedef declarations, even when identical, the definition may not be
35   repeated.
36 */
37 #ifndef CHARSET_INFO_DEFINED
38 #define CHARSET_INFO_DEFINED
39 typedef struct charset_info_st CHARSET_INFO;
40 #endif  /* CHARSET_INFO_DEFINED */
41 
42 #ifdef	__cplusplus
43 extern "C" {
44 #endif
45 
46 /*
47   Overhead to store an element in hash
48   Can be used to approximate memory consumption for a hash
49  */
50 #define HASH_OVERHEAD (sizeof(char*)*2)
51 
52 /* flags for hash_init */
53 #define HASH_UNIQUE     1       /* hash_insert fails on duplicate key */
54 
55 struct st_hash;
56 typedef uint my_hash_value_type;
57 typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
58 typedef void (*my_hash_free_key)(void *);
59 /**
60   Function type representing a hash function to be used with the HASH
61   container.
62   Should accept pointer to HASH, pointer to key buffer and key length
63   as parameters.
64 */
65 typedef my_hash_value_type (*my_hash_function)(const struct st_hash *,
66                                                const uchar *,
67                                                size_t);
68 
69 typedef struct st_hash {
70   size_t key_offset,key_length;		/* Length of key if const length */
71   size_t blength;
72   ulong records;
73   uint flags;
74   DYNAMIC_ARRAY array;				/* Place for hash_keys */
75   my_hash_get_key get_key;
76   void (*free)(void *);
77   CHARSET_INFO *charset;
78   my_hash_function hash_function;
79   PSI_memory_key m_psi_key;
80 } HASH;
81 
82 /* A search iterator state */
83 typedef uint HASH_SEARCH_STATE;
84 
85 #define my_hash_init(A,B,C,D,E,F,G,H,I) \
86           _my_hash_init(A,0,B,NULL,C,D,E,F,G,H,I)
87 #define my_hash_init2(A,B,C,D,E,F,G,H,I,J) \
88           _my_hash_init(A,B,C,NULL,D,E,F,G,H,I,J)
89 #define my_hash_init3(A,B,C,D,E,F,G,H,I,J,K) \
90           _my_hash_init(A,B,C,D,E,F,G,H,I,J,K)
91 my_bool _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
92                       my_hash_function hash_function,
93                       ulong default_array_elements, size_t key_offset,
94                       size_t key_length, my_hash_get_key get_key,
95                       void (*free_element)(void*),
96                       uint flags,
97                       PSI_memory_key psi_key);
98 void my_hash_claim(HASH *tree);
99 void my_hash_free(HASH *tree);
100 void my_hash_reset(HASH *hash);
101 uchar *my_hash_element(HASH *hash, ulong idx);
102 uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
103 uchar *my_hash_search_using_hash_value(const HASH *info,
104                                        my_hash_value_type hash_value,
105                                        const uchar *key, size_t length);
106 my_hash_value_type my_calc_hash(const HASH *info,
107                                 const uchar *key, size_t length);
108 uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
109                      HASH_SEARCH_STATE *state);
110 uchar *my_hash_first_from_hash_value(const HASH *info,
111                                      my_hash_value_type hash_value,
112                                      const uchar *key,
113                                      size_t length,
114                                      HASH_SEARCH_STATE *state);
115 uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
116                     HASH_SEARCH_STATE *state);
117 my_bool my_hash_insert(HASH *info, const uchar *data);
118 my_bool my_hash_delete(HASH *hash, uchar *record);
119 my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
120                        size_t old_key_length);
121 void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row);
122 my_bool my_hash_check(HASH *hash); /* Only in debug library */
123 
124 #define my_hash_clear(H) memset((H), 0, sizeof(*(H)))
125 #define my_hash_inited(H) ((H)->blength != 0)
126 #define my_hash_init_opt(A,B,C,D,E,F,G,H,I) \
127           (!my_hash_inited(A) && _my_hash_init(A,0,B,NULL,C,D,E,F,G,H,I))
128 
129 #ifdef	__cplusplus
130 }
131 #endif
132 #endif
133