Drizzled Public API Documentation

ha0storage.cc

00001 /*****************************************************************************
00002 
00003 Copyright (C) 2007, 2009, Innobase Oy. All Rights Reserved.
00004 
00005 This program is free software; you can redistribute it and/or modify it under
00006 the terms of the GNU General Public License as published by the Free Software
00007 Foundation; version 2 of the License.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT
00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00012 
00013 You should have received a copy of the GNU General Public License along with
00014 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
00015 St, Fifth Floor, Boston, MA 02110-1301 USA
00016 
00017 *****************************************************************************/
00018 
00019 /**************************************************/
00028 #include "univ.i"
00029 #include "ha0storage.h"
00030 #include "hash0hash.h"
00031 #include "mem0mem.h"
00032 #include "ut0rnd.h"
00033 
00034 #ifdef UNIV_NONINL
00035 #include "ha0storage.ic"
00036 #endif
00037 
00038 #include <cassert>
00039 
00040 /*******************************************************************/
00043 static
00044 const void*
00045 ha_storage_get(
00046 /*===========*/
00047   ha_storage_t* storage,  
00048   const void* data,   
00049   ulint   data_len) 
00050 {
00051   ha_storage_node_t*  node;
00052   ulint     fold;
00053 
00054   /* avoid repetitive calls to ut_fold_binary() in the HASH_SEARCH
00055   macro */
00056   fold = ut_fold_binary(static_cast<const unsigned char*>(data), data_len);
00057 
00058 #define IS_FOUND  \
00059   node->data_len == data_len && memcmp(node->data, data, data_len) == 0
00060 
00061   HASH_SEARCH(
00062     next,     /* node->"next" */
00063     storage->hash,    /* the hash table */
00064     fold,     /* key */
00065     ha_storage_node_t*, /* type of node->next */
00066     node,     /* auxiliary variable */
00067                 assert(true),     /* assertion */
00068     IS_FOUND);    /* search criteria */
00069 
00070   if (node == NULL) {
00071 
00072     return(NULL);
00073   }
00074   /* else */
00075 
00076   return(node->data);
00077 }
00078 
00079 /*******************************************************************/
00088 UNIV_INTERN
00089 const void*
00090 ha_storage_put_memlim(
00091 /*==================*/
00092   ha_storage_t* storage,  
00093   const void* data,   
00094   ulint   data_len, 
00095   ulint   memlim)   
00096 {
00097   void*     raw;
00098   ha_storage_node_t*  node;
00099   const void*   data_copy;
00100   ulint     fold;
00101 
00102   /* check if data chunk is already present */
00103   data_copy = ha_storage_get(storage, data, data_len);
00104   if (data_copy != NULL) {
00105 
00106     return(data_copy);
00107   }
00108 
00109   /* not present */
00110 
00111   /* check if we are allowed to allocate data_len bytes */
00112   if (memlim > 0
00113       && ha_storage_get_size(storage) + data_len > memlim) {
00114 
00115     return(NULL);
00116   }
00117 
00118   /* we put the auxiliary node struct and the data itself in one
00119   continuous block */
00120   raw = mem_heap_alloc(storage->heap,
00121            sizeof(ha_storage_node_t) + data_len);
00122 
00123   node = (ha_storage_node_t*) raw;
00124   data_copy = (byte*) raw + sizeof(*node);
00125 
00126   memcpy((byte*) raw + sizeof(*node), data, data_len);
00127 
00128   node->data_len = data_len;
00129   node->data = data_copy;
00130 
00131   /* avoid repetitive calls to ut_fold_binary() in the HASH_INSERT
00132   macro */
00133   fold = ut_fold_binary(static_cast<const unsigned char *>(data), data_len);
00134 
00135   HASH_INSERT(
00136     ha_storage_node_t,  /* type used in the hash chain */
00137     next,     /* node->"next" */
00138     storage->hash,    /* the hash table */
00139     fold,     /* key */
00140     node);      /* add this data to the hash */
00141 
00142   /* the output should not be changed because it will spoil the
00143   hash table */
00144   return(data_copy);
00145 }
00146 
00147 #ifdef UNIV_COMPILE_TEST_FUNCS
00148 
00149 void
00150 test_ha_storage()
00151 {
00152   ha_storage_t* storage;
00153   char    buf[1024];
00154   int   i;
00155   const void* stored[256];
00156   const void* p;
00157 
00158   storage = ha_storage_create(0, 0);
00159 
00160   for (i = 0; i < 256; i++) {
00161 
00162     memset(buf, i, sizeof(buf));
00163     stored[i] = ha_storage_put(storage, buf, sizeof(buf));
00164   }
00165 
00166   //ha_storage_empty(&storage);
00167 
00168   for (i = 255; i >= 0; i--) {
00169 
00170     memset(buf, i, sizeof(buf));
00171     p = ha_storage_put(storage, buf, sizeof(buf));
00172 
00173     if (p != stored[i]) {
00174 
00175       fprintf(stderr, "ha_storage_put() returned %p "
00176         "instead of %p, i=%d\n", p, stored[i], i);
00177       return;
00178     }
00179   }
00180 
00181   fprintf(stderr, "all ok\n");
00182 
00183   ha_storage_free(storage);
00184 }
00185 
00186 #endif /* UNIV_COMPILE_TEST_FUNCS */