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 <eyedblib/thread.h>
00027 #include <eyedbsm/eyedbsm.h>
00028 #include <eyedbsm/Idx.h>
00029 #include <stdlib.h>
00030 #include <eyedblib/xdr.h>
00031 #include <eyedbsm/xdr.h>
00032 #include <assert.h>
00033
00034 #include <iostream>
00035 #include <eyedblib/log.h>
00036 #include <eyedblib/machtypes.h>
00037 #include <eyedblib/rpc_lib.h>
00038 #include <eyedblib/m_mem.h>
00039 #include "lib/m_mem_p.h"
00040
00041 #include <fstream>
00042
00043 namespace eyedbsm {
00044
00045 Idx::Idx(Boolean _opened,
00046 Boolean (*_precmp)(void const * p, void const * q,
00047 KeyType const * type, int & r))
00048 {
00049 opened = _opened;
00050 precmp = _precmp;
00051 }
00052
00053 Status
00054 Idx::make(DbHandle *dbh, const Oid &oid, Idx *&idx)
00055 {
00056 unsigned int idxtype;
00057 idx = 0;
00058 Status s = objectRead(dbh, 0, sizeof(unsigned int), &idxtype,
00059 DefaultLock, 0, 0, &oid);
00060 if (s) return s;
00061
00062 idxtype = x2h_u32(idxtype);
00063
00064 if (idxtype == HashType) {
00065 idx = new HIdx(dbh, &oid);
00066 return Success;
00067 }
00068
00069 if (idxtype == BTreeType) {
00070 idx = new BIdx(dbh, oid);
00071 return Success;
00072 }
00073
00074 return statusMake(ERROR, "object %s is not a valid index [%x]",
00075 getOidString(&oid), idxtype);
00076 }
00077
00078 Status
00079 Idx::checkOpened() const
00080 {
00081 if (!opened)
00082 return statusMake(ERROR, "index %s is not opened",
00083 getOidString(&oid()));
00084 return Success;
00085 }
00086
00087 Idx::Key::Key(int sz)
00088 {
00089 size = sz;
00090 key = (size ? m_malloc(size) : 0);
00091 }
00092
00093 void Idx::Key::setKey(void *k, int sz, const KeyType &keyType)
00094 {
00095 #if 1
00096 Boolean no_x2h;
00097 if (sz < 0) {no_x2h = True; sz = -sz;}
00098 else no_x2h = False;
00099 #endif
00100 if (sz > size) {
00101 free(key);
00102 size = sz;
00103 key = m_malloc(sz);
00104 assert(key);
00105 }
00106
00107 #if 1
00108 if (no_x2h)
00109 memcpy(key, k, sz);
00110 else
00111 #endif
00112 x2h(key, k, keyType, sz);
00113 }
00114
00115 Idx::Key::~Key()
00116 {
00117 free(key);
00118 }
00119
00120 unsigned int
00121 Idx::computeCount()
00122 {
00123 IdxCursor *curs;
00124
00125 if (asHIdx())
00126 curs = new HIdxCursor(asHIdx(), 0, 0, False, False);
00127 else
00128 curs = new BIdxCursor(asBIdx(), 0, 0, False, False);
00129
00130 unsigned int count = 0;
00131
00132 for (;;)
00133 {
00134 Boolean found;
00135 Oid oid;
00136 curs->next(&found, &oid, 0);
00137
00138 if (!found)
00139 break;
00140
00141 count++;
00142 }
00143
00144 delete curs;
00145 return count;
00146 }
00147
00148 using namespace std;
00149
00150 static ofstream DEVNULL("/dev/null");
00151
00152 #define mkcmp(type, x2h) \
00153 inline static int \
00154 cmp(type const * p, type const * q, unsigned i, unsigned char bswap) \
00155 { \
00156 for (; i-- > 0; p++, q++) { \
00157 type _p, _q; \
00158 eyedblib_mcp(&_p, p, sizeof(_p)); \
00159 eyedblib_mcp(&_q, q, sizeof(_q)); \
00160 if (bswap & OP1_SWAP) _p = x2h(_p); \
00161 if (bswap & OP2_SWAP) _q = x2h(_q); \
00162 if (_p > _q) \
00163 return 1; \
00164 else if (_p < _q) \
00165 return -1; \
00166 } \
00167 return 0; \
00168 }
00169
00170 mkcmp(unsigned char, x2h_nop)
00171 mkcmp(signed char, x2h_nop)
00172 mkcmp(eyedblib::int16, x2h_16)
00173 mkcmp(eyedblib::uint16, x2h_u16)
00174 mkcmp(eyedblib::int32, x2h_32)
00175 mkcmp(eyedblib::uint32, x2h_u32)
00176 mkcmp(eyedblib::int64, x2h_64)
00177 mkcmp(eyedblib::uint64, x2h_u64)
00178 mkcmp(eyedblib::float32, x2h_f32)
00179 mkcmp(eyedblib::float64, x2h_f64)
00180
00181 #undef mkcmp
00182
00183
00184 static inline void const *
00185 fpos_(void const * p, int offset)
00186 {
00187 return (char const *)p + offset;
00188 }
00189
00190 static inline void *
00191 fpos_(void * p, int offset)
00192 {
00193 return (char *)p + offset;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203 static Boolean offset_cmp = getenv("EYEDBNOIDXOFF") ? True : False;
00204
00205 int
00206 Idx::compare(void const * p, void const * q, KeyType const * type,
00207 unsigned char bswap) const
00208 {
00209
00210 if (!offset_cmp && precmp) {
00211 int r;
00212 if (precmp(p, q, type, r))
00213 return r;
00214 }
00215
00216
00217 p = fpos_(p, type->offset);
00218 q = fpos_(q, type->offset);
00219
00220 switch (type->type)
00221 {
00222 case tChar:
00223 return memcmp(p, q, type->count);
00224
00225 case tInt32:
00226 return cmp((eyedblib::int32 const *)p, (eyedblib::int32 const *)q, type->count, bswap);
00227
00228 case tInt64:
00229 return cmp((eyedblib::int64 const *)p, (eyedblib::int64 const *)q, type->count, bswap);
00230
00231 case tInt16:
00232 return cmp((eyedblib::int16 const *)p, (eyedblib::int16 const *)q, type->count, bswap);
00233
00234 case tFloat32:
00235 return cmp((eyedblib::float32 const *)p, (eyedblib::float32 const *)q, type->count, bswap);
00236
00237 case tFloat64:
00238 return cmp((eyedblib::float64 const *)p, (eyedblib::float64 const *)q, type->count, bswap);
00239
00240 case tSignedChar:
00241 return cmp((signed char const *)p, (signed char const *)q, type->count, bswap);
00242
00243 case tUnsignedChar:
00244 return cmp((unsigned char const *)p, (unsigned char const *)q, type->count, bswap);
00245
00246 case tUnsignedInt16:
00247 return cmp((eyedblib::uint16 const *)p, (eyedblib::uint16 const *)q, type->count, bswap);
00248
00249 case tUnsignedInt32:
00250 return cmp((eyedblib::uint32 const *)p, (eyedblib::uint32 const *)q, type->count, bswap);
00251
00252 case tUnsignedInt64:
00253 return cmp((eyedblib::uint64 const *)p, (eyedblib::uint64 const *)q, type->count, bswap);
00254
00255 case tOid:
00256 if (!bswap)
00257 return memcmp(p, q, type->count * sizeof(Oid));
00258 else {
00259 assert(type->count == 1);
00260 Oid poid, qoid;
00261 eyedblib_mcp(&poid, p, sizeof(poid));
00262 eyedblib_mcp(&qoid, q, sizeof(qoid));
00263 if (bswap & OP1_SWAP) x2h_oid(&poid, &poid);
00264 if (bswap & OP2_SWAP) x2h_oid(&qoid, &qoid);
00265 return memcmp(&poid, &qoid, sizeof(Oid));
00266 }
00267
00268 case tString:
00269 return strncmp((char const *)p, (char const *)q, type->count);
00270
00271 default:
00272 assert(0);
00273 }
00274 return 0;
00275 }
00276
00277 void
00278 Idx::h2x(void *xkey, const void *hkey, const KeyType &type)
00279 {
00280 if (type.offset)
00281 memcpy((char *)xkey, (char *)hkey, type.offset);
00282
00283 xkey = fpos_(xkey, type.offset);
00284 hkey = fpos_(hkey, type.offset);
00285
00286
00287 switch (type.type)
00288 {
00289 case tInt32:
00290 case tFloat32:
00291 case tUnsignedInt32:
00292 h2x_32_cpy(xkey, hkey);
00293 break;
00294
00295 case tInt64:
00296 case tFloat64:
00297 case tUnsignedInt64:
00298 h2x_64_cpy(xkey, hkey);
00299 break;
00300
00301 case tInt16:
00302 case tUnsignedInt16:
00303 h2x_16_cpy(xkey, hkey);
00304 break;
00305
00306 case tOid:
00307 {
00308 Oid hoid;
00309 memcpy(&hoid, hkey, sizeof(hoid));
00310 h2x_oid((Oid *)xkey, &hoid);
00311 }
00312 break;
00313
00314 default:
00315 printf("ERROR TYPE = %d\n", type.type);
00316 assert(0);
00317 }
00318 }
00319
00320 void
00321 Idx::x2h(void *hkey, const void *xkey, const KeyType &type,
00322 unsigned int size)
00323 {
00324 if (type.offset)
00325 memcpy((char *)hkey, (char *)xkey, type.offset);
00326
00327 hkey = fpos_(hkey, type.offset);
00328 xkey = fpos_(xkey, type.offset);
00329
00330
00331 Oid hoid;
00332 switch (type.type)
00333 {
00334 case tInt32:
00335 case tFloat32:
00336 case tUnsignedInt32:
00337 x2h_32_cpy(hkey, xkey);
00338 break;
00339
00340 case tInt64:
00341 case tFloat64:
00342 case tUnsignedInt64:
00343 x2h_64_cpy(hkey, xkey);
00344 break;
00345
00346 case tInt16:
00347 case tUnsignedInt16:
00348 x2h_16_cpy(hkey, xkey);
00349 break;
00350
00351 case tOid:
00352 x2h_oid(&hoid, (const Oid *)xkey);
00353 memcpy(hkey, &hoid, sizeof(hoid));
00354 break;
00355
00356 default:
00357 memcpy(hkey, xkey, size - type.offset);
00358 break;
00359 }
00360 }
00361
00362 const char *
00363 Idx::typeString(Type type)
00364 {
00365 switch (type) {
00366 case tChar:
00367 return "tChar";
00368
00369 case tUnsignedChar:
00370 return "tUnsignedChar";
00371
00372 case tSignedChar:
00373 return "tSignedChar";
00374
00375 case tInt16:
00376 return "tInt16";
00377
00378 case tUnsignedInt16:
00379 return "tUnsignedInt16";
00380
00381 case tInt32:
00382 return "tInt32";
00383
00384 case tUnsignedInt32:
00385 return "tUnsignedInt32";
00386
00387 case tInt64:
00388 return "tInt64";
00389
00390 case tUnsignedInt64:
00391 return "tUnsignedInt64";
00392
00393 case tFloat32:
00394 return "tFloat32";
00395
00396 case tFloat64:
00397 return "tFloat64";
00398
00399 case tOid:
00400 return "tOid";
00401
00402 case tString:
00403 return "tString";
00404
00405 default:
00406 fprintf(stderr, "%s line %d: unknown index type %d\n", __FILE__, __LINE__, int(type));
00407 abort();
00408 return 0;
00409 }
00410 }
00411
00412 size_t
00413 Idx::typeSize(Type type)
00414 {
00415 switch (type) {
00416 case tChar:
00417 return sizeof(char);
00418
00419 case tUnsignedChar:
00420 return sizeof(unsigned char);
00421
00422 case tSignedChar:
00423 return sizeof(signed char);
00424
00425 case tInt16:
00426 return sizeof(eyedblib::int16);
00427
00428 case tUnsignedInt16:
00429 return sizeof(eyedblib::uint16);
00430
00431 case tInt32:
00432 return sizeof(eyedblib::int32);
00433
00434 case tUnsignedInt32:
00435 return sizeof(eyedblib::uint32);
00436
00437 case tInt64:
00438 return sizeof(eyedblib::int64);
00439
00440 case tUnsignedInt64:
00441 return sizeof(eyedblib::uint64);
00442
00443 case tFloat32:
00444 return sizeof(eyedblib::float32);
00445
00446 case tFloat64:
00447 return sizeof(eyedblib::float64);
00448
00449 case tOid:
00450 return sizeof(Oid);
00451
00452 case tString:
00453 return sizeof(char);
00454
00455
00456
00457
00458
00459
00460 default:
00461 fprintf(stderr, "%s line %d: unknown index type %d\n", __FILE__, __LINE__, int(type));
00462 abort();
00463 return 0;
00464 }
00465 }
00466
00467 void DataBuffer::setData(void *_data, unsigned int _datasz)
00468 {
00469 static const unsigned int INCRSZ = 512;
00470 datasz = _datasz;
00471
00472 if (datasz > allocsz) {
00473 allocsz = datasz + INCRSZ;
00474 delete [] data;
00475 data = new unsigned char[allocsz];
00476 }
00477
00478 memcpy(data, _data, datasz);
00479 }
00480 }