MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ha0storage.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
28 #include "univ.i"
29 #include "ha0storage.h"
30 #include "hash0hash.h"
31 #include "mem0mem.h"
32 #include "ut0rnd.h"
33 
34 #ifdef UNIV_NONINL
35 #include "ha0storage.ic"
36 #endif
37 
38 /*******************************************************************/
41 static
42 const void*
43 ha_storage_get(
44 /*===========*/
45  ha_storage_t* storage,
46  const void* data,
47  ulint data_len)
48 {
49  ha_storage_node_t* node;
50  ulint fold;
51 
52  /* avoid repetitive calls to ut_fold_binary() in the HASH_SEARCH
53  macro */
54  fold = ut_fold_binary(static_cast<const byte*>(data), data_len);
55 
56 #define IS_FOUND \
57  node->data_len == data_len && memcmp(node->data, data, data_len) == 0
58 
60  next, /* node->"next" */
61  storage->hash, /* the hash table */
62  fold, /* key */
63  ha_storage_node_t*, /* type of node->next */
64  node, /* auxiliary variable */
65  , /* assertion */
66  IS_FOUND); /* search criteria */
67 
68  if (node == NULL) {
69 
70  return(NULL);
71  }
72  /* else */
73 
74  return(node->data);
75 }
76 
77 /*******************************************************************/
86 UNIV_INTERN
87 const void*
89 /*==================*/
90  ha_storage_t* storage,
91  const void* data,
92  ulint data_len,
93  ulint memlim)
94 {
95  void* raw;
96  ha_storage_node_t* node;
97  const void* data_copy;
98  ulint fold;
99 
100  /* check if data chunk is already present */
101  data_copy = ha_storage_get(storage, data, data_len);
102  if (data_copy != NULL) {
103 
104  return(data_copy);
105  }
106 
107  /* not present */
108 
109  /* check if we are allowed to allocate data_len bytes */
110  if (memlim > 0
111  && ha_storage_get_size(storage) + data_len > memlim) {
112 
113  return(NULL);
114  }
115 
116  /* we put the auxiliary node struct and the data itself in one
117  continuous block */
118  raw = mem_heap_alloc(storage->heap,
119  sizeof(ha_storage_node_t) + data_len);
120 
121  node = (ha_storage_node_t*) raw;
122  data_copy = (byte*) raw + sizeof(*node);
123 
124  memcpy((byte*) raw + sizeof(*node), data, data_len);
125 
126  node->data_len = data_len;
127  node->data = data_copy;
128 
129  /* avoid repetitive calls to ut_fold_binary() in the HASH_INSERT
130  macro */
131  fold = ut_fold_binary(static_cast<const byte*>(data), data_len);
132 
133  HASH_INSERT(
134  ha_storage_node_t, /* type used in the hash chain */
135  next, /* node->"next" */
136  storage->hash, /* the hash table */
137  fold, /* key */
138  node); /* add this data to the hash */
139 
140  /* the output should not be changed because it will spoil the
141  hash table */
142  return(data_copy);
143 }
144 
145 #ifdef UNIV_COMPILE_TEST_FUNCS
146 
147 void
148 test_ha_storage()
149 {
150  ha_storage_t* storage;
151  char buf[1024];
152  int i;
153  const void* stored[256];
154  const void* p;
155 
156  storage = ha_storage_create(0, 0);
157 
158  for (i = 0; i < 256; i++) {
159 
160  memset(buf, i, sizeof(buf));
161  stored[i] = ha_storage_put(storage, buf, sizeof(buf));
162  }
163 
164  //ha_storage_empty(&storage);
165 
166  for (i = 255; i >= 0; i--) {
167 
168  memset(buf, i, sizeof(buf));
169  p = ha_storage_put(storage, buf, sizeof(buf));
170 
171  if (p != stored[i]) {
172 
173  fprintf(stderr, "ha_storage_put() returned %p "
174  "instead of %p, i=%d\n", p, stored[i], i);
175  return;
176  }
177  }
178 
179  fprintf(stderr, "all ok\n");
180 
181  ha_storage_free(storage);
182 }
183 
184 #endif /* UNIV_COMPILE_TEST_FUNCS */