~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-09-09 21:45:53 UTC
  • mto: (1756.1.2 build) (1768.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1757.
  • Revision ID: brian@tangent.org-20100909214553-e687rmf5zk9478on
Force unique to just use memory and let the OS handle paging.

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
 
/*******************************************************************//**
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
 
/*===========*/
45
 
        ha_storage_t*   storage,        /*!< in: hash storage */
46
 
        const void*     data,           /*!< in: data to check for */
47
 
        ulint           data_len)       /*!< in: data length */
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 */
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
 
/*******************************************************************//**
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
 
/*==================*/
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 */
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 */