~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/ha/ha0storage.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 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 */