00001 // -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 //////////////////////////////////////////////////////////////////// 00003 // 00004 // Filename : TinyTable.h 00005 // 00006 // This file is a part of the UPPAAL toolkit. 00007 // Copyright (c) 1995 - 2003, Uppsala University and Aalborg University. 00008 // All right reserved. 00009 // 00010 // $Id: TinyTable.h,v 1.1 2005/04/22 15:20:10 adavid Exp $ 00011 // 00012 //////////////////////////////////////////////////////////////////// 00013 00014 #ifndef INCLUDE_HASH_TINYTABLE_H 00015 #define INCLUDE_HASH_TINYTABLE_H 00016 00017 #include "base/intutils.h" 00018 #include "base/bitstring.h" 00019 00020 /** @file 00021 * This is a template for tiny hash tables that are: 00022 * - tiny 00023 * - allocated on the stack 00024 * - very fast 00025 * - not resizable 00026 * - bounded in the number of elements they can accept 00027 * when instantiated 00028 * - able to store only void* or uint32_t 00029 * The trick is to allocate on the stack a int[something] 00030 * and instantiate TinyTable with this int[..] 00031 * The tiny hash table is a uint32_t[] managed by a few 00032 * simple functions. 00033 */ 00034 00035 namespace hash 00036 { 00037 class TinyTable 00038 { 00039 public: 00040 /** Constructor: 00041 * @param max: size of the table 00042 * @param mem: the table itself. 00043 * @pre max is a power of 2 00044 */ 00045 TinyTable(uint32_t *mem, size_t max) 00046 : table(mem), mask(max-1) 00047 { 00048 base_resetSmall(mem, max); 00049 } 00050 00051 /** @return size needed in uint32_t to store n items. 00052 * Use a power of 2 for speed, and use larger table to 00053 * reduce collisions. 00054 * @pre n != 0 00055 */ 00056 static size_t intsizeFor(size_t n) 00057 { 00058 assert(n); 00059 n = base_fmsb32(n); 00060 return (1 << (n+3)); 00061 } 00062 00063 /** Add a pointer = wrap for int. */ 00064 bool add(const void* ptr) 00065 { 00066 // 32 bits pointers -> lower bits == 0 so >>2 gives a good hash 00067 return add(((uintptr_t)ptr) >> 2); 00068 } 00069 00070 /** Add an int. You should add at max n items as 00071 * used in hash_sizeofTinyTable(n). 00072 * @return true if it was accepted, or false 00073 * if it was refused, ie, already present in the table. 00074 * @param val: int to add. 00075 * @pre val != 0 -- special value. 00076 */ 00077 bool add(uint32_t val) 00078 { 00079 assert(val); 00080 // no collision list -> use next entry in table 00081 for(uint32_t index = val; table[index & mask] != val; ++index) 00082 { 00083 if (table[index & mask] == 0) 00084 { 00085 table[index & mask] = val; 00086 return true; 00087 } 00088 } 00089 return false; 00090 } 00091 00092 private: 00093 uint32_t *table; ///< hash table 00094 uint32_t mask; ///< binary mask = size-1 where size is a power of 2 00095 }; 00096 } 00097 00098 #endif // INCLUDE_HASH_TINYTABLE_H