hashtable.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 #include <eyedbconfig.h>
00025 
00026 #include <stdlib.h>
00027 #include <stdarg.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <fcntl.h>
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <errno.h>
00034 #include <sys/mman.h>
00035 
00036 #include <eyedblib/iassert.h>
00037 #include <eyedblib/machtypes.h>
00038 #include <transaction.h>
00039 #include <eyedbsm_p.h>
00040 #include <hashtable.h>
00041 #include <lock.h>
00042 
00043 namespace eyedbsm {
00044 
00045 HashTable *
00046 HashTableCreate(XMHandle *xmh, int count)
00047 {
00048   HashTable *ht;
00049   unsigned int size = HashTableSize(count);
00050 
00051   ht = (HashTable *)XMAlloc(xmh, size);
00052 
00053   if (!ht)
00054     return ht;
00055 
00056   memset(ht, 0, size);
00057 #ifdef TRS_SECURE
00058   ht->magic = HT_MAGIC;
00059 #endif
00060   ht->cnt = 0;
00061   ht->mask = count - 1;
00062 
00063 #ifdef KEEP_ORDER
00064   ht->xfirst = ht->xlast = 0;
00065 #endif
00066   return ht;
00067 }
00068 
00069 /* TRObject HashTable */
00070 int
00071 HashTableTRObjectInsert(XMHandle *xmh, HashTable *ht, TRObject *tro)
00072 {
00073   XMOffset off;
00074   int key = tro->oid.getNX() & ht->mask;
00075 
00076 #ifdef KEEP_ORDER
00077   XMOffset xlast = ht->xlast;
00078 #endif
00079   XMOffset tro_off = XM_OFFSET(xmh, tro);
00080 
00081 #ifdef TRS_SECURE
00082   ESM_ASSERT_ABORT(ht->magic == HT_MAGIC, 0, 0);
00083 #endif
00084   off = ht->offs[key];
00085 
00086   if (off)
00087     {
00088       TRObject *tr = (TRObject *)XM_ADDR(xmh, off);
00089       tr->prev = tro_off;
00090     }
00091 
00092   tro->next = off;
00093   tro->prev = XM_NULLOFFSET;
00094   ht->offs[key] = XM_OFFSET(xmh, tro);
00095 
00096 #ifdef KEEP_ORDER
00097   xlast = ht->xlast;
00098   ht->xlast = tro_off;
00099   tro->xprev = xlast;
00100   tro->xnext = 0;
00101 
00102   if (xlast)
00103     {
00104       TRObject *tr = (TRObject *)XM_ADDR(xmh, xlast);
00105       tr->xnext = tro_off;
00106     }
00107 
00108   if (!ht->xfirst)
00109     ht->xfirst = tro_off;
00110 #endif
00111 
00112   return ++ht->cnt;
00113 }
00114 
00115 int
00116 HashTableTRObjectSuppress(XMHandle *xmh, HashTable *ht, TRObject *tro)
00117 {
00118   TRObject *next, *prev;
00119   XMOffset tro_off = XM_OFFSET(xmh, tro);
00120 
00121   next = (TRObject *)XM_ADDR(xmh, tro->next);
00122   prev = (TRObject *)XM_ADDR(xmh, tro->prev);
00123 
00124   if (next)
00125     next->prev = tro->prev;
00126 
00127   if (prev)
00128     prev->next = tro->next;
00129   else
00130     ht->offs[tro->oid.getNX() & ht->mask] = tro->next;
00131 
00132 #ifdef KEEP_ORDER
00133   if (tro->xprev)
00134     {
00135       TRObject *tr = (TRObject *)XM_ADDR(xmh, tro->xprev);
00136       tr->xnext = tro->xnext;
00137     }
00138 
00139   if (tro->xnext)
00140     {
00141       TRObject *tr = (TRObject *)XM_ADDR(xmh, tro->xnext);
00142       tr->xprev = tro->xprev;
00143     }
00144 
00145   if (ht->xlast == tro_off)
00146     ht->xlast = tro->xprev;
00147 
00148   if (ht->xfirst == tro_off)
00149     ht->xfirst = tro->xnext;
00150 #endif
00151   return --ht->cnt;
00152 }
00153 
00154 XMOffset
00155 HashTableTRObjectLookup(XMHandle *xmh, HashTable *ht,
00156                            const Oid *oid)
00157 {
00158   XMOffset tro_off;
00159 
00160   tro_off = ht->offs[oid->getNX() & ht->mask];
00161 
00162 #ifdef TRS_SECURE
00163   ESM_ASSERT_ABORT(ht->magic == HT_MAGIC, 0, 0);
00164 #endif
00165   while (tro_off)
00166     {
00167       TRObject *tro = (TRObject *)XM_ADDR(xmh, tro_off);
00168 
00169       if (!memcmp(&tro->oid, oid, sizeof(Oid)))
00170         return tro_off;
00171 
00172       tro_off = tro->next;
00173     }
00174 
00175   return XM_NULLOFFSET;
00176 }
00177 
00178 /* PObject HashTable */
00179 int
00180 HashTablePObjectInsert(XMHandle *xmh, HashTable *ht, PObject *po)
00181 {
00182   XMOffset off;
00183   int key = po->oid.getNX() & ht->mask;
00184 
00185 #ifdef TRS_SECURE
00186   ESM_ASSERT_ABORT(ht->magic == HT_MAGIC, 0, 0);
00187 #endif
00188   off = ht->offs[key];
00189 
00190   if (off)
00191     {
00192       PObject *p = (PObject *)XM_ADDR(xmh, off);
00193       p->prev = XM_OFFSET(xmh, po);
00194     }
00195 
00196   po->next = off;
00197   po->prev = XM_NULLOFFSET;
00198   ht->offs[key] = XM_OFFSET(xmh, po);
00199 
00200   return ++ht->cnt;
00201 }
00202 
00203 int
00204 HashTablePObjectSuppress(XMHandle *xmh, HashTable *ht, PObject *po)
00205 {
00206   PObject *next, *prev;
00207 
00208   next = (PObject *)XM_ADDR(xmh, po->next);
00209   prev = (PObject *)XM_ADDR(xmh, po->prev);
00210 
00211   if (next)
00212     next->prev = po->prev;
00213 
00214   if (prev)
00215     prev->next = po->next;
00216   else
00217     ht->offs[po->oid.getNX() & ht->mask] = po->next;
00218 
00219   return --ht->cnt;
00220 }
00221 
00222 XMOffset
00223 HashTablePObjectLookup(XMHandle *xmh, HashTable *ht,
00224                           const Oid *oid)
00225 {
00226   XMOffset po_off;
00227 
00228 #ifdef TRS_SECURE
00229   ESM_ASSERT_ABORT(ht->magic == HT_MAGIC, 0, 0);
00230 #endif
00231 
00232   po_off = ht->offs[oid->getNX() & ht->mask];
00233 
00234   while (po_off)
00235     {
00236       PObject *po = (PObject *)XM_ADDR(xmh, po_off);
00237 
00238       if (!memcmp(&po->oid, oid, sizeof(Oid)))
00239         return po_off;
00240 
00241       po_off = po->next;
00242     }
00243 
00244   return XM_NULLOFFSET;
00245 }
00246 }

Generated on Mon Dec 22 18:15:55 2008 for eyedb by  doxygen 1.5.3