1/*****************************************************************************
2
3Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free Software
7Foundation; version 2 of the License.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License along with
14this program; if not, write to the Free Software Foundation, Inc.,
1551 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
17*****************************************************************************/
18
19/**************************************************//**
20@file include/ha0storage.ic
21Hash storage.
22Provides a data structure that stores chunks of data in
23its own storage, avoiding duplicates.
24
25Created September 24, 2007 Vasil Dimov
26*******************************************************/
27
28#include "univ.i"
29#include "ha0storage.h"
30#include "hash0hash.h"
31#include "mem0mem.h"
32
33/** Hash storage for strings */
34struct ha_storage_t {
35 mem_heap_t* heap; /*!< memory heap from which memory is
36 allocated */
37 hash_table_t* hash; /*!< hash table used to avoid
38 duplicates */
39};
40
41/** Objects of this type are stored in ha_storage_t */
42struct ha_storage_node_t {
43 ulint data_len;/*!< length of the data */
44 const void* data; /*!< pointer to data */
45 ha_storage_node_t* next; /*!< next node in hash chain */
46};
47
48/*******************************************************************//**
49Creates a hash storage. If any of the parameters is 0, then a default
50value is used.
51@return own: hash storage */
52UNIV_INLINE
53ha_storage_t*
54ha_storage_create(
55/*==============*/
56 ulint initial_heap_bytes, /*!< in: initial heap's size */
57 ulint initial_hash_cells) /*!< in: initial number of cells
58 in the hash table */
59{
60 ha_storage_t* storage;
61 mem_heap_t* heap;
62
63 if (initial_heap_bytes == 0) {
64
65 initial_heap_bytes = HA_STORAGE_DEFAULT_HEAP_BYTES;
66 }
67
68 if (initial_hash_cells == 0) {
69
70 initial_hash_cells = HA_STORAGE_DEFAULT_HASH_CELLS;
71 }
72
73 /* we put "storage" within "storage->heap" */
74
75 heap = mem_heap_create(sizeof(ha_storage_t)
76 + initial_heap_bytes);
77
78 storage = (ha_storage_t*) mem_heap_alloc(heap,
79 sizeof(ha_storage_t));
80
81 storage->heap = heap;
82 storage->hash = hash_create(initial_hash_cells);
83
84 return(storage);
85}
86
87/*******************************************************************//**
88Empties a hash storage, freeing memory occupied by data chunks.
89This invalidates any pointers previously returned by ha_storage_put().
90The hash storage is not invalidated itself and can be used again. */
91UNIV_INLINE
92void
93ha_storage_empty(
94/*=============*/
95 ha_storage_t** storage) /*!< in/out: hash storage */
96{
97 ha_storage_t temp_storage;
98
99 temp_storage.heap = (*storage)->heap;
100 temp_storage.hash = (*storage)->hash;
101
102 hash_table_clear(temp_storage.hash);
103 mem_heap_empty(temp_storage.heap);
104
105 *storage = (ha_storage_t*) mem_heap_alloc(temp_storage.heap,
106 sizeof(ha_storage_t));
107
108 (*storage)->heap = temp_storage.heap;
109 (*storage)->hash = temp_storage.hash;
110}
111
112/*******************************************************************//**
113Frees a hash storage and everything it contains, it cannot be used after
114this call.
115This invalidates any pointers previously returned by ha_storage_put(). */
116UNIV_INLINE
117void
118ha_storage_free(
119/*============*/
120 ha_storage_t* storage) /*!< in, own: hash storage */
121{
122 /* order is important because the pointer storage->hash is
123 within the heap */
124 hash_table_free(storage->hash);
125 mem_heap_free(storage->heap);
126}
127
128/*******************************************************************//**
129Gets the size of the memory used by a storage.
130@return bytes used */
131UNIV_INLINE
132ulint
133ha_storage_get_size(
134/*================*/
135 const ha_storage_t* storage) /*!< in: hash storage */
136{
137 ulint ret;
138
139 ret = mem_heap_get_size(storage->heap);
140
141 /* this assumes hash->heap and hash->heaps are NULL */
142 ret += sizeof(hash_table_t);
143 ret += sizeof(hash_cell_t) * hash_get_n_cells(storage->hash);
144
145 return(ret);
146}
147