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"
38
/*******************************************************************//**
39
Retrieves a data from a storage. If it is present, a pointer to the
40
stored copy of data is returned, otherwise NULL is returned. */
45
ha_storage_t* storage, /*!< in: hash storage */
46
const void* data, /*!< in: data to check for */
47
ulint data_len) /*!< in: data length */
49
ha_storage_node_t* node;
52
/* avoid repetitive calls to ut_fold_binary() in the HASH_SEARCH
54
fold = ut_fold_binary(data, data_len);
57
node->data_len == data_len && memcmp(node->data, data, data_len) == 0
60
next, /* node->"next" */
61
storage->hash, /* the hash table */
63
ha_storage_node_t*, /* type of node->next */
64
node, /* auxiliary variable */
66
IS_FOUND); /* search criteria */
77
/*******************************************************************//**
78
Copies data into the storage and returns a pointer to the copy. If the
79
same data chunk is already present, then pointer to it is returned.
80
Data chunks are considered to be equal if len1 == len2 and
81
memcmp(data1, data2, len1) == 0. If "data" is not present (and thus
82
data_len bytes need to be allocated) and the size of storage is going to
83
become more than "memlim" then "data" is not added and NULL is returned.
84
To disable this behavior "memlim" can be set to 0, which stands for
88
ha_storage_put_memlim(
89
/*==================*/
90
ha_storage_t* storage, /*!< in/out: hash storage */
91
const void* data, /*!< in: data to store */
92
ulint data_len, /*!< in: data length */
93
ulint memlim) /*!< in: memory limit to obey */
96
ha_storage_node_t* node;
97
const void* data_copy;
100
/* check if data chunk is already present */
101
data_copy = ha_storage_get(storage, data, data_len);
102
if (data_copy != NULL) {
109
/* check if we are allowed to allocate data_len bytes */
111
&& ha_storage_get_size(storage) + data_len > memlim) {
116
/* we put the auxiliary node struct and the data itself in one
118
raw = mem_heap_alloc(storage->heap,
119
sizeof(ha_storage_node_t) + data_len);
121
node = (ha_storage_node_t*) raw;
122
data_copy = (byte*) raw + sizeof(*node);
124
memcpy((byte*) raw + sizeof(*node), data, data_len);
126
node->data_len = data_len;
127
node->data = data_copy;
129
/* avoid repetitive calls to ut_fold_binary() in the HASH_INSERT
131
fold = ut_fold_binary(data, data_len);
134
ha_storage_node_t, /* type used in the hash chain */
135
next, /* node->"next" */
136
storage->hash, /* the hash table */
138
node); /* add this data to the hash */
140
/* the output should not be changed because it will spoil the
145
#ifdef UNIV_COMPILE_TEST_FUNCS
150
ha_storage_t* storage;
153
const void* stored[256];
156
storage = ha_storage_create(0, 0);
158
for (i = 0; i < 256; i++) {
160
memset(buf, i, sizeof(buf));
161
stored[i] = ha_storage_put(storage, buf, sizeof(buf));
164
//ha_storage_empty(&storage);
166
for (i = 255; i >= 0; i--) {
168
memset(buf, i, sizeof(buf));
169
p = ha_storage_put(storage, buf, sizeof(buf));
171
if (p != stored[i]) {
173
fprintf(stderr, "ha_storage_put() returned %p "
174
"instead of %p, i=%d\n", p, stored[i], i);
179
fprintf(stderr, "all ok\n");
181
ha_storage_free(storage);
184
#endif /* UNIV_COMPILE_TEST_FUNCS */