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, Fifth Floor, 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 "hash0hash.h"
29#include "mem0mem.h"
30
31/** Hash storage for strings */
32struct ha_storage_t {
33	mem_heap_t*	heap;	/*!< memory heap from which memory is
34				allocated */
35	hash_table_t	hash;	/*!< hash table used to avoid
36				duplicates */
37};
38
39/** Objects of this type are stored in ha_storage_t */
40struct ha_storage_node_t {
41	ulint			data_len;/*!< length of the data */
42	const void*		data;	/*!< pointer to data */
43	ha_storage_node_t*	next;	/*!< next node in hash chain */
44};
45
46/*******************************************************************//**
47Creates a hash storage. If any of the parameters is 0, then a default
48value is used.
49@return own: hash storage */
50UNIV_INLINE
51ha_storage_t*
52ha_storage_create(
53/*==============*/
54	ulint	initial_heap_bytes,	/*!< in: initial heap's size */
55	ulint	initial_hash_cells)	/*!< in: initial number of cells
56					in the hash table */
57{
58	ha_storage_t*	storage;
59	mem_heap_t*	heap;
60
61	if (initial_heap_bytes == 0) {
62
63		initial_heap_bytes = HA_STORAGE_DEFAULT_HEAP_BYTES;
64	}
65
66	if (initial_hash_cells == 0) {
67
68		initial_hash_cells = HA_STORAGE_DEFAULT_HASH_CELLS;
69	}
70
71	/* we put "storage" within "storage->heap" */
72
73	heap = mem_heap_create(sizeof(ha_storage_t)
74			       + initial_heap_bytes);
75
76	storage = (ha_storage_t*) mem_heap_alloc(heap,
77						 sizeof(ha_storage_t));
78
79	storage->heap = heap;
80	storage->hash.create(initial_hash_cells);
81
82	return(storage);
83}
84
85/*******************************************************************//**
86Empties a hash storage, freeing memory occupied by data chunks.
87This invalidates any pointers previously returned by ha_storage_put().
88The hash storage is not invalidated itself and can be used again. */
89UNIV_INLINE
90void
91ha_storage_empty(
92/*=============*/
93	ha_storage_t**	storage)	/*!< in/out: hash storage */
94{
95	ha_storage_t	temp_storage;
96
97	temp_storage.heap = (*storage)->heap;
98	temp_storage.hash = (*storage)->hash;
99
100	temp_storage.hash.clear();
101	mem_heap_empty(temp_storage.heap);
102
103	*storage = (ha_storage_t*) mem_heap_alloc(temp_storage.heap,
104						  sizeof(ha_storage_t));
105
106	(*storage)->heap = temp_storage.heap;
107	(*storage)->hash = temp_storage.hash;
108}
109
110/*******************************************************************//**
111Frees a hash storage and everything it contains, it cannot be used after
112this call.
113This invalidates any pointers previously returned by ha_storage_put(). */
114UNIV_INLINE
115void
116ha_storage_free(
117/*============*/
118	ha_storage_t*	storage)	/*!< in, own: hash storage */
119{
120	storage->hash.free();
121	mem_heap_free(storage->heap);
122}
123
124/*******************************************************************//**
125Gets the size of the memory used by a storage.
126@return bytes used */
127UNIV_INLINE
128ulint
129ha_storage_get_size(
130/*================*/
131	const ha_storage_t*	storage)	/*!< in: hash storage */
132{
133	ulint	ret;
134
135	ret = mem_heap_get_size(storage->heap);
136
137	/* this assumes hash->heap and hash->heaps are NULL */
138	ret += sizeof(hash_table_t);
139	ret += sizeof(hash_cell_t) * storage->hash.n_cells;
140
141	return(ret);
142}
143