00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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 }