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