~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1
/*****************************************************************************
2
3
Copyright (c) 2007, 2009, Innobase Oy. 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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
16
17
*****************************************************************************/
18
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
19
/**************************************************//**
20
@file ha/ha0storage.c
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
21
Hash storage.
22
Provides a data structure that stores chunks of data in
23
its own storage, avoiding duplicates.
24
25
Created September 22, 2007 Vasil Dimov
26
*******************************************************/
27
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
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
38
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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. */
41
static
42
const void*
43
ha_storage_get(
44
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
45
	ha_storage_t*	storage,	/*!< in: hash storage */
46
	const void*	data,		/*!< in: data to check for */
47
	ulint		data_len)	/*!< in: data length */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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(data, data_len);
55
56
#define IS_FOUND	\
57
	node->data_len == data_len && memcmp(node->data, data, data_len) == 0
58
59
	HASH_SEARCH(
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 */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
65
		,			/* assertion */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
66
		IS_FOUND);		/* search criteria */
67
68
	if (node == NULL) {
69
70
		return(NULL);
71
	}
72
	/* else */
73
74
	return(node->data);
75
}
76
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
77
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
85
"no limit". */
86
UNIV_INTERN
87
const void*
88
ha_storage_put_memlim(
89
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
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 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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(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 */