~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/ha/ha0storage.cc

  • Committer: Mark Atwood
  • Date: 2008-10-03 01:39:40 UTC
  • mto: This revision was merged to the branch mainline in revision 437.
  • Revision ID: mark@fallenpegasus.com-20081003013940-mvefjo725dltz41h
rename logging_noop to logging_query

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file ha/ha0storage.c
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
 
 
38
 
#include <cassert>
39
 
 
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. */
43
 
static
44
 
const void*
45
 
ha_storage_get(
46
 
/*===========*/
47
 
        ha_storage_t*   storage,        /*!< in: hash storage */
48
 
        const void*     data,           /*!< in: data to check for */
49
 
        ulint           data_len)       /*!< in: data length */
50
 
{
51
 
        ha_storage_node_t*      node;
52
 
        ulint                   fold;
53
 
 
54
 
        /* avoid repetitive calls to ut_fold_binary() in the HASH_SEARCH
55
 
        macro */
56
 
        fold = ut_fold_binary(static_cast<const unsigned char*>(data), data_len);
57
 
 
58
 
#define IS_FOUND        \
59
 
        node->data_len == data_len && memcmp(node->data, data, data_len) == 0
60
 
 
61
 
        HASH_SEARCH(
62
 
                next,                   /* node->"next" */
63
 
                storage->hash,          /* the hash table */
64
 
                fold,                   /* key */
65
 
                ha_storage_node_t*,     /* type of node->next */
66
 
                node,                   /* auxiliary variable */
67
 
                assert(true),                   /* assertion */
68
 
                IS_FOUND);              /* search criteria */
69
 
 
70
 
        if (node == NULL) {
71
 
 
72
 
                return(NULL);
73
 
        }
74
 
        /* else */
75
 
 
76
 
        return(node->data);
77
 
}
78
 
 
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
87
 
"no limit". */
88
 
UNIV_INTERN
89
 
const void*
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 */
96
 
{
97
 
        void*                   raw;
98
 
        ha_storage_node_t*      node;
99
 
        const void*             data_copy;
100
 
        ulint                   fold;
101
 
 
102
 
        /* check if data chunk is already present */
103
 
        data_copy = ha_storage_get(storage, data, data_len);
104
 
        if (data_copy != NULL) {
105
 
 
106
 
                return(data_copy);
107
 
        }
108
 
 
109
 
        /* not present */
110
 
 
111
 
        /* check if we are allowed to allocate data_len bytes */
112
 
        if (memlim > 0
113
 
            && ha_storage_get_size(storage) + data_len > memlim) {
114
 
 
115
 
                return(NULL);
116
 
        }
117
 
 
118
 
        /* we put the auxiliary node struct and the data itself in one
119
 
        continuous block */
120
 
        raw = mem_heap_alloc(storage->heap,
121
 
                             sizeof(ha_storage_node_t) + data_len);
122
 
 
123
 
        node = (ha_storage_node_t*) raw;
124
 
        data_copy = (byte*) raw + sizeof(*node);
125
 
 
126
 
        memcpy((byte*) raw + sizeof(*node), data, data_len);
127
 
 
128
 
        node->data_len = data_len;
129
 
        node->data = data_copy;
130
 
 
131
 
        /* avoid repetitive calls to ut_fold_binary() in the HASH_INSERT
132
 
        macro */
133
 
        fold = ut_fold_binary(static_cast<const unsigned char *>(data), data_len);
134
 
 
135
 
        HASH_INSERT(
136
 
                ha_storage_node_t,      /* type used in the hash chain */
137
 
                next,                   /* node->"next" */
138
 
                storage->hash,          /* the hash table */
139
 
                fold,                   /* key */
140
 
                node);                  /* add this data to the hash */
141
 
 
142
 
        /* the output should not be changed because it will spoil the
143
 
        hash table */
144
 
        return(data_copy);
145
 
}
146
 
 
147
 
#ifdef UNIV_COMPILE_TEST_FUNCS
148
 
 
149
 
void
150
 
test_ha_storage()
151
 
{
152
 
        ha_storage_t*   storage;
153
 
        char            buf[1024];
154
 
        int             i;
155
 
        const void*     stored[256];
156
 
        const void*     p;
157
 
 
158
 
        storage = ha_storage_create(0, 0);
159
 
 
160
 
        for (i = 0; i < 256; i++) {
161
 
 
162
 
                memset(buf, i, sizeof(buf));
163
 
                stored[i] = ha_storage_put(storage, buf, sizeof(buf));
164
 
        }
165
 
 
166
 
        //ha_storage_empty(&storage);
167
 
 
168
 
        for (i = 255; i >= 0; i--) {
169
 
 
170
 
                memset(buf, i, sizeof(buf));
171
 
                p = ha_storage_put(storage, buf, sizeof(buf));
172
 
 
173
 
                if (p != stored[i]) {
174
 
 
175
 
                        fprintf(stderr, "ha_storage_put() returned %p "
176
 
                                "instead of %p, i=%d\n", p, stored[i], i);
177
 
                        return;
178
 
                }
179
 
        }
180
 
 
181
 
        fprintf(stderr, "all ok\n");
182
 
 
183
 
        ha_storage_free(storage);
184
 
}
185
 
 
186
 
#endif /* UNIV_COMPILE_TEST_FUNCS */