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 "kern_p.h"
00027
00028
00029
00030 #define SKIP_NX_LOCK
00031
00032 namespace eyedbsm {
00033
00034 void
00035 oidCopySlot_(DbHandle const *dbh, Oid::NX nx, const OidLoc &oidloc,
00036 Oid *oid, unsigned int *psize)
00037 {
00038 MmapH hdl;
00039 ObjectHeader *objh;
00040
00041 objh = (ObjectHeader *)
00042 slot2addr(dbh, oidloc.ns, oidloc.datid,
00043 sizeof(ObjectHeader), (char **)&objh, &hdl, 0);
00044 oid->setNX(nx);
00045
00046 oid->setUnique(x2h_u32(objh->unique));
00047
00048 if (psize)
00049 *psize = x2h_u32(objh->size);
00050
00051
00052
00053
00054
00055 hdl_release(&hdl);
00056 OIDDBIDMAKE(oid, dbh->vd->dbid);
00057 }
00058
00059 void oidCopySlot(DbHandle const *dbh, Oid::NX nx, Oid *oid, unsigned int *psize)
00060 {
00061 oidCopySlot_(dbh, nx, oidLocGet_(dbh, nx), oid, psize);
00062 }
00063
00064 NS
00065 oidLastSlotGet(DbHandle const *dbh, const OidLoc &oidloc)
00066 {
00067 MapHeader t_mp = DAT2MP(dbh, oidloc.datid);
00068 MapHeader *mp = &t_mp;
00069
00070 MmapH hdl;
00071 ObjectHeader *objh;
00072
00073 objh = (ObjectHeader *)
00074 slot2addr(dbh, oidloc.ns, oidloc.datid,
00075 sizeof(ObjectHeader), (char **)&objh, &hdl, 0);
00076
00077 NS lastslot = SZ2NS_XDR(x2h_u32(objh->size), mp) - 1 + oidloc.ns;
00078 hdl_release(&hdl);
00079 return lastslot;
00080 }
00081
00082 Status
00083 nxAlloc(DbHandle const *const dbh, const OidLoc &oidloc_, Oid::NX *pnx)
00084 {
00085 Mutex *mt = NX_MTX(dbh);
00086 unsigned int xid = dbh->vd->xid;
00087 Oid::NX i;
00088 Oid::NX start, end;
00089 TransactionContext *trctx = DBH2TRCTX(dbh);
00090
00091 if (NEED_LOCK(trctx))
00092 MUTEX_LOCK_VOID(mt, xid);
00093
00094 start = x2h_u32(CURIDXBUSY(dbh));
00095 end = x2h_u32(DbHeader(DBSADDR(dbh)).__nbobjs());
00096
00097 for (;;) {
00098 void *omp_addr = OIDLOC(dbh->vd->omp_addr, start);
00099 for (i = start; i < end; i++) {
00100 if (i >= x2h_u32(LASTIDXBLKALLOC(dbh))) {
00101 Status se;
00102 if (se = nxFileSizeExtends(dbh, i)) {
00103 if (NEED_LOCK(trctx))
00104 MUTEX_UNLOCK(mt, xid);
00105 return se;
00106 }
00107
00108 }
00109
00110 OidLoc oidloc;
00111 x2h_oidloc(&oidloc, omp_addr);
00112 if (!oidloc.ns) {
00113 oidloc.ns = oidloc_.ns+NS_OFFSET;
00114 oidloc.datid = oidloc_.datid;
00115 #ifdef NX_TRACE
00116 printf("nxAlloc(%d) -> %d %d\n", i, oidloc_.ns, oidloc_.datid);
00117 #endif
00118 assert(oidloc.datid >= 0);
00119 if (x2h_u32(LASTIDXBUSY(dbh)) < i+1) {
00120 LASTIDXBUSY(dbh) = h2x_u32(i+1);
00121 }
00122
00123 CURIDXBUSY(dbh) = h2x_u32(i+1);
00124 h2x_oidloc(omp_addr, &oidloc);
00125
00126 if (NEED_LOCK(trctx))
00127 MUTEX_UNLOCK(mt, xid);
00128
00129 *pnx = i;
00130 return Success;
00131 }
00132 omp_addr = NEXT_OIDLOC(omp_addr);
00133 }
00134
00135 if (!start) {
00136 CURIDXBUSY(dbh) = h2x_u32(i);
00137 if (NEED_LOCK(trctx))
00138 MUTEX_UNLOCK(mt, xid);
00139 *pnx = Oid::INVALID_NX;
00140 return Success;
00141 }
00142
00143
00144
00145
00146 CURIDXBUSY(dbh) = 0;
00147 start = 0;
00148 end = x2h_u32(LASTIDXBUSY(dbh));
00149 }
00150
00151 return Success;
00152 }
00153
00154 void
00155 nxFree(DbHandle const *const dbh, Oid::NX nx)
00156 {
00157 Mutex *mt = NX_MTX(dbh);
00158 unsigned int xid = dbh->vd->xid;
00159 OidLoc oidloc;
00160 TransactionContext *trctx = DBH2TRCTX(dbh);
00161
00162 #ifndef SKIP_NX_LOCK
00163
00164 if (NEED_LOCK(trctx))
00165 MUTEX_LOCK_VOID(mt, xid);
00166 #endif
00167
00168 oidloc.ns = 0;
00169 oidloc.datid = -1;
00170
00171 h2x_oidloc(OIDLOC(dbh->vd->omp_addr, nx), &oidloc);
00172
00173 #ifdef NX_TRACE
00174 printf("nxFree(%d)\n", nx);
00175 #endif
00176
00177 #ifndef SKIP_NX_LOCK
00178 if (NEED_LOCK(trctx))
00179 MUTEX_UNLOCK(mt, xid);
00180 #endif
00181 }
00182
00183 void
00184 nxSet(DbHandle const *const dbh, Oid::NX nx, NS ns, short datid)
00185 {
00186 Mutex *mt = NX_MTX(dbh);
00187 unsigned int xid = dbh->vd->xid;
00188 OidLoc oidloc;
00189 TransactionContext *trctx = DBH2TRCTX(dbh);
00190
00191 #ifndef SKIP_NX_LOCK
00192
00193 if (NEED_LOCK(trctx))
00194 MUTEX_LOCK_VOID(mt, xid);
00195 #endif
00196
00197 oidloc.ns = ns+NS_OFFSET;
00198 oidloc.datid = datid;
00199
00200 h2x_oidloc(OIDLOC(dbh->vd->omp_addr, nx), &oidloc);
00201
00202 #ifdef NX_TRACE
00203 printf("nxSet(%d) -> %d %d\n", nx, ns, datid);
00204 #endif
00205
00206 #ifndef SKIP_NX_LOCK
00207 if (NEED_LOCK(trctx))
00208 MUTEX_UNLOCK(mt, xid);
00209 #endif
00210 }
00211
00212 Oid::NX
00213 nxNextBusyGet(DbHandle const *const dbh, Oid::NX nx)
00214 {
00215 Oid::NX lastidxbusy, i;
00216 Mutex *mt = NX_MTX(dbh);
00217 unsigned int xid = dbh->vd->xid;
00218 TransactionContext *trctx = DBH2TRCTX(dbh);
00219
00220 if (NEED_LOCK(trctx))
00221 MUTEX_LOCK_VOID(mt, xid);
00222
00223 lastidxbusy = x2h_u32(LASTIDXBUSY(dbh));
00224
00225 void *omp_addr = OIDLOC(dbh->vd->omp_addr, nx);
00226 for (i = nx; i < lastidxbusy; i++)
00227 {
00228 OidLoc oidloc;
00229 x2h_oidloc(&oidloc, omp_addr);
00230
00231 if (oidloc.ns)
00232 {
00233 if (NEED_LOCK(trctx))
00234 MUTEX_UNLOCK(mt, xid);
00235 return i;
00236 }
00237 omp_addr = NEXT_OIDLOC(omp_addr);
00238 }
00239
00240 if (NEED_LOCK(trctx))
00241 MUTEX_UNLOCK(mt, xid);
00242 return Oid::INVALID_NX;
00243 }
00244
00245 Status
00246 ESM_objectLocationGet(DbHandle const *dbh, const Oid *oid,
00247 ObjectLocation *objloc)
00248 {
00249 OidLoc oidloc = oidLocGet(dbh, oid);
00250 if (oidloc.ns == INVALID_NS)
00251 return statusMake(INVALID_OID, "oid %s is invalid",
00252 getOidString(oid));
00253 unsigned int size;
00254
00255
00256 Status s = ESM_objectSizeGet(dbh, &size, DefaultLock, oid, OPDefault);
00257 if (s) return s;
00258
00259 DbHeader _dbh(DBSADDR(dbh));
00260 unsigned int sizeslot = x2h_u32(_dbh.dat(oidloc.datid).mp()->sizeslot());
00261 unsigned long long offset = oidloc.ns * sizeslot;
00262
00263 objloc->is_valid = isValidObject(size) ? True : False;
00264
00265 if (!objloc->is_valid)
00266 objloc->size = 0;
00267 else
00268 objloc->size = size;
00269 size += sizeof(ObjectHeader);
00270 objloc->datid = oidloc.datid;
00271 objloc->dspid = getDataspace(&_dbh, oidloc.datid);
00272 objloc->slot_start_num = oidloc.ns;
00273 objloc->slot_end_num = oidloc.ns + (size-1)/sizeslot;
00274 unsigned int nsize = (objloc->slot_end_num - objloc->slot_start_num + 1) * sizeslot;
00275 objloc->dat_start_pagenum = offset>>pgsize_pow2;
00276 objloc->dat_end_pagenum = (offset+nsize-1)>>pgsize_pow2;
00277 if (isPhy(dbh, oid)) {
00278 objloc->omp_start_pagenum = ~0;
00279 objloc->omp_end_pagenum = ~0;
00280 } else {
00281 objloc->omp_start_pagenum = (oid->getNX() * OIDLOCSIZE)>>pgsize_pow2;
00282 objloc->omp_end_pagenum = (((oid->getNX() * OIDLOCSIZE)+OIDLOCSIZE)-1)>>pgsize_pow2;
00283 }
00284 objloc->dmp_start_pagenum = ((objloc->slot_start_num)/8)>>pgsize_pow2;
00285 objloc->dmp_end_pagenum = (((objloc->slot_end_num)/8))>>pgsize_pow2;
00286 return Success;
00287 }
00288
00289 Status
00290 ESM_objectsLocationGet(DbHandle const *dbh, const Oid *oid,
00291 ObjectLocation *objloc, unsigned int oid_cnt)
00292 {
00293 Status s;
00294 for (int i = 0; i < oid_cnt; i++)
00295 if (s = ESM_objectLocationGet(dbh, &oid[i], &objloc[i]))
00296 return s;
00297
00298 return Success;
00299 }
00300
00301 OidLoc
00302 oidLocGet(DbHandle const *const dbh, const Oid *oid)
00303 {
00304 if (isPhy(dbh, oid)) {
00305 OidLoc oidloc;
00306 getPhyInfo(oid, &oidloc.ns, &oidloc.datid);
00307 return oidloc;
00308 }
00309 return oidLocGet_(dbh, oid->getNX());
00310 }
00311
00312 OidLoc
00313 oidLocGet_(DbHandle const *const dbh, Oid::NX nx)
00314 {
00315 Mutex *mt = NX_MTX(dbh);
00316 unsigned int xid = dbh->vd->xid;
00317 NS ns;
00318 TransactionContext *trctx = DBH2TRCTX(dbh);
00319
00320
00321 #ifndef SKIP_NX_LOCK
00322
00323 if (NEED_LOCK(trctx))
00324 MUTEX_LOCK_VOID(mt, xid);
00325 #endif
00326
00327 OidLoc oidloc;
00328 memset(&oidloc, 0, sizeof(oidloc));
00329
00330 if (nx == Oid::INVALID_NX || nx > x2h_u32(LASTIDXBUSY(dbh)))
00331 {
00332 #ifndef SKIP_NX_LOCK
00333 if (NEED_LOCK(trctx))
00334 MUTEX_UNLOCK(mt, xid);
00335 #endif
00336 oidloc.ns = INVALID_NS;
00337 oidloc.datid = -1;
00338 return oidloc;
00339 }
00340
00341 x2h_oidloc(&oidloc, OIDLOC(dbh->vd->omp_addr, nx));
00342
00343 oidloc.ns -= NS_OFFSET;
00344
00345 #ifndef SKIP_NX_LOCK
00346 if (NEED_LOCK(trctx))
00347 MUTEX_UNLOCK(mt, xid);
00348 #endif
00349
00350 #if 0
00351 if (oidloc.datid < 0)
00352 {
00353 printf("very strange oidloc [%p] 0x%x, %d for nx=%d\n",
00354 dbh->vd->omp_addr, oidloc.ns, oidloc.datid, nx);
00355 for (int i = nx-1; i >= nx-40; i--) {
00356 x2h_oidloc(&oidloc, OIDLOC(dbh->vd->omp_addr, i));
00357 if (oidloc.datid < 0)
00358 printf("-> very strange oidloc [%p] 0x%x, %d for nx=%d\n",
00359 dbh->vd->omp_addr, oidloc.ns, oidloc.datid, i);
00360 else
00361 printf("-> ok for nx=%d\n", i);
00362 }
00363 }
00364 else
00365 printf("oidloc [%p] 0x%x, %d for nx=%d\n",
00366 dbh->vd->omp_addr, oidloc.ns, oidloc.datid, nx);
00367 #endif
00368 return oidloc;
00369 }
00370
00371 void
00372 ESM_oidsTrace(DbHandle const *const dbh, ESM_oidsTraceAction action, FILE *fd)
00373 {
00374
00375 void *omp_addr = dbh->vd->omp_addr;
00376 int cnt = 0;
00377 Oid oid, nextoid;
00378 Boolean found;
00379
00380 ESM_firstOidGet_omp(dbh, &oid, &found);
00381
00382 while (found)
00383 {
00384 if (action == ESM_allOids)
00385 fprintf(fd, "%s\n", getOidString(&oid));
00386 cnt++;
00387 ESM_nextOidGet_omp(dbh, &oid, &nextoid, &found);
00388 oid = nextoid;
00389 }
00390
00391 fprintf(fd, "Total Oid Count %d\n", cnt);
00392 }
00393
00394 Status
00395 ESM_nextOidGetDat_omp(DbHandle const *dbh, short datid,
00396 Oid *nextoid, Boolean *found)
00397 {
00398 for (;;) {
00399 OidLoc oidloc = oidLocGet(dbh, nextoid);
00400 if (oidloc.datid == datid) {
00401 *found = True;
00402 return Success;
00403 }
00404
00405 Status s = ESM_nextOidGet_omp(dbh, nextoid, nextoid, found);
00406 if (s || !*found) return s;
00407 }
00408 }
00409
00410 Status
00411 ESM_firstOidDatGet(DbHandle const *dbh, short datid, Oid *oid,
00412 Boolean *found)
00413 {
00414 DbHeader _dbh(DBSADDR(dbh));
00415 if (getDatType(&_dbh, datid) == PhysicalOidType)
00416 return ESM_firstOidGet_map(dbh, datid, oid, found);
00417
00418 Status s = ESM_firstOidGet_omp(dbh, oid, found);
00419 if (s || !*found) return s;
00420 return ESM_nextOidGetDat_omp(dbh, datid, oid, found);
00421 }
00422
00423 Status
00424 ESM_nextOidDatGet(DbHandle const *dbh, short datid,
00425 Oid const *const baseoid,
00426 Oid *nextoid, Boolean *found)
00427 {
00428 DbHeader _dbh(DBSADDR(dbh));
00429 if (getDatType(&_dbh, datid) == PhysicalOidType)
00430 return ESM_nextOidGet_map(dbh, datid, baseoid, nextoid, found);
00431
00432 Status s = ESM_nextOidGet_omp(dbh, baseoid, nextoid, found);
00433 if (s || !*found) return s;
00434 return ESM_nextOidGetDat_omp(dbh, datid, nextoid, found);
00435 }
00436
00437 Status
00438 ESM_firstOidGet_omp(DbHandle const *dbh, Oid *oid, Boolean *found)
00439 {
00440 Oid::NX nx;
00441
00442 *found = False;
00443
00444 if (!check_dbh(dbh))
00445 return statusMake_s(INVALID_DB_HANDLE);
00446
00447 if ((nx = nxNextBusyGet(dbh, 0)) == Oid::INVALID_NX)
00448 return Success;
00449
00450 oidCopySlot(dbh, nx, oid, 0);
00451 *found = True;
00452 return Success;
00453 }
00454
00455 Status
00456 ESM_nextOidGet_omp(DbHandle const *dbh, Oid const *const baseoid,
00457 Oid *nextoid, Boolean *found)
00458 {
00459 Oid::NX nx;
00460
00461 *found = False;
00462 if (!check_dbh(dbh))
00463 return statusMake_s(INVALID_DB_HANDLE);
00464
00465 if (!check_oid(dbh, baseoid))
00466 return statusMake(INVALID_OID, "%s", getOidString(baseoid));
00467
00468 if ((nx = nxNextBusyGet(dbh, baseoid->getNX()+1)) == Oid::INVALID_NX)
00469 return Success;
00470
00471 oidCopySlot(dbh, nx, nextoid, 0);
00472 *found = True;
00473 return Success;
00474 }
00475
00476 static int no_unique_check = getenv("NO_UNIQUE_CHECK") ? 1 : 0;
00477
00478 ObjectHeader *
00479 oid2objh_(const Oid *oid, NS ns, short datid, const DbHandle *dbh,
00480 ObjectHeader **objh, MmapH *hdl, int *up,
00481 Boolean *oid2addr_failed)
00482 {
00483 ObjectHeader *hdr;
00484 ObjectHeader *xobjh = (ObjectHeader *)
00485 oid2addr_(ns, datid, dbh, sizeof(ObjectHeader), objh, hdl, up);
00486
00487 *oid2addr_failed = (xobjh ? False : True);
00488
00489
00490
00491
00492
00493
00494 hdr = (!xobjh || (x2h_u32(xobjh->unique) != oid->getUnique()) ? 0 : xobjh);
00495
00496 if (!hdr) {
00497 #ifdef DSP_INVALID_OID
00498 display_invalid_oid(oid, xobjh);
00499 #endif
00500 if (no_unique_check)
00501 hdr = xobjh;
00502 }
00503
00504 if (!hdr && xobjh)
00505 hdl_release(hdl);
00506 return hdr;
00507 }
00508
00509 ObjectHeader *
00510 oid2objh(const Oid *oid, const DbHandle *dbh, ObjectHeader **objh,
00511 MmapH *hdl, Boolean *oid2addr_failed)
00512 {
00513 ObjectHeader *hdr;
00514 ObjectHeader *xobjh = (ObjectHeader *)
00515 oid2addr(oid, dbh, sizeof(ObjectHeader), objh, hdl);
00516
00517 *oid2addr_failed = (xobjh ? False : True);
00518
00519 hdr = (!xobjh || (x2h_u32(xobjh->unique) != oid->getUnique()) ? 0 : xobjh);
00520
00521 #ifdef DSP_INVALID_OID
00522 if (!hdr)
00523 display_invalid_oid(oid, xobjh);
00524 #endif
00525
00526 if (!hdr && xobjh)
00527 hdl_release(hdl);
00528 return hdr;
00529 }
00530
00531 int
00532 check_oid(const DbHandle *dbh, const Oid *oid)
00533 {
00534 OidLoc oidloc = oidLocGet(dbh, oid);
00535 if (oidloc.ns == INVALID_NS || !isDatValid(dbh, oidloc.datid) ||
00536 OIDDBIDGET(oid) != dbh->vd->dbid)
00537 return 0;
00538 return 1;
00539 }
00540
00541 extern int
00542 oidloc_cmp(const OidLoc &ol1, const OidLoc &ol2)
00543 {
00544 return ol1.ns == ol2.ns && ol1.datid == ol2.datid;
00545 }
00546
00547 }