1
/*****************************************************************************
3
Copyright (C) 2007, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
22
Provides a data structure that stores chunks of data in
23
its own storage, avoiding duplicates.
25
Created September 22, 2007 Vasil Dimov
26
*******************************************************/
29
#include "ha0storage.h"
30
#include "hash0hash.h"
35
#include "ha0storage.ic"
40
/*******************************************************************//**
41
Retrieves a data from a storage. If it is present, a pointer to the
42
stored copy of data is returned, otherwise NULL is returned. */
47
ha_storage_t* storage, /*!< in: hash storage */
48
const void* data, /*!< in: data to check for */
49
ulint data_len) /*!< in: data length */
51
ha_storage_node_t* node;
54
/* avoid repetitive calls to ut_fold_binary() in the HASH_SEARCH
56
fold = ut_fold_binary(static_cast<const unsigned char*>(data), data_len);
59
node->data_len == data_len && memcmp(node->data, data, data_len) == 0
62
next, /* node->"next" */
63
storage->hash, /* the hash table */
65
ha_storage_node_t*, /* type of node->next */
66
node, /* auxiliary variable */
67
assert(true), /* assertion */
68
IS_FOUND); /* search criteria */
79
/*******************************************************************//**
80
Copies data into the storage and returns a pointer to the copy. If the
81
same data chunk is already present, then pointer to it is returned.
82
Data chunks are considered to be equal if len1 == len2 and
83
memcmp(data1, data2, len1) == 0. If "data" is not present (and thus
84
data_len bytes need to be allocated) and the size of storage is going to
85
become more than "memlim" then "data" is not added and NULL is returned.
86
To disable this behavior "memlim" can be set to 0, which stands for
90
ha_storage_put_memlim(
91
/*==================*/
92
ha_storage_t* storage, /*!< in/out: hash storage */
93
const void* data, /*!< in: data to store */
94
ulint data_len, /*!< in: data length */
95
ulint memlim) /*!< in: memory limit to obey */
98
ha_storage_node_t* node;
99
const void* data_copy;
102
/* check if data chunk is already present */
103
data_copy = ha_storage_get(storage, data, data_len);
104
if (data_copy != NULL) {
111
/* check if we are allowed to allocate data_len bytes */
113
&& ha_storage_get_size(storage) + data_len > memlim) {
118
/* we put the auxiliary node struct and the data itself in one
120
raw = mem_heap_alloc(storage->heap,
121
sizeof(ha_storage_node_t) + data_len);
123
node = (ha_storage_node_t*) raw;
124
data_copy = (byte*) raw + sizeof(*node);
126
memcpy((byte*) raw + sizeof(*node), data, data_len);
128
node->data_len = data_len;
129
node->data = data_copy;
131
/* avoid repetitive calls to ut_fold_binary() in the HASH_INSERT
133
fold = ut_fold_binary(static_cast<const unsigned char *>(data), data_len);
136
ha_storage_node_t, /* type used in the hash chain */
137
next, /* node->"next" */
138
storage->hash, /* the hash table */
140
node); /* add this data to the hash */
142
/* the output should not be changed because it will spoil the
147
#ifdef UNIV_COMPILE_TEST_FUNCS
152
ha_storage_t* storage;
155
const void* stored[256];
158
storage = ha_storage_create(0, 0);
160
for (i = 0; i < 256; i++) {
162
memset(buf, i, sizeof(buf));
163
stored[i] = ha_storage_put(storage, buf, sizeof(buf));
166
//ha_storage_empty(&storage);
168
for (i = 255; i >= 0; i--) {
170
memset(buf, i, sizeof(buf));
171
p = ha_storage_put(storage, buf, sizeof(buf));
173
if (p != stored[i]) {
175
fprintf(stderr, "ha_storage_put() returned %p "
176
"instead of %p, i=%d\n", p, stored[i], i);
181
fprintf(stderr, "all ok\n");
183
ha_storage_free(storage);
186
#endif /* UNIV_COMPILE_TEST_FUNCS */