📄 tctdb.c
字号:
} getnum++; int flags = proc(pkbuf, pksiz, cols, op); if(flags & TDBQPPUT){ if(tctdbputimpl(tdb, pkbuf, pksiz, cols, TDBPDOVER)){ putnum++; } else { err = true; } } else if(flags & TDBQPOUT){ if(tctdboutimpl(tdb, pkbuf, pksiz)){ outnum++; } else { err = true; } } tcmapdel(cols); if(flags & TDBQPSTOP) break; } tclistdel(res); tcxstrprintf(qry->hint, "post treatment: get=%lld, put=%lld, out=%lld\n", (long long)getnum, (long long)putnum, (long long)outnum); TDBUNLOCKMETHOD(tdb); return !err;}/* Get the hint of a query object. */const char *tctdbqryhint(TDBQRY *qry){ assert(qry); return tcxstrptr(qry->hint);}/************************************************************************************************* * features for experts *************************************************************************************************//* Set the error code of a table database object. */void tctdbsetecode(TCTDB *tdb, int ecode, const char *filename, int line, const char *func){ assert(tdb && filename && line >= 1 && func); tchdbsetecode(tdb->hdb, ecode, filename, line, func);}/* Set the file descriptor for debugging output. */void tctdbsetdbgfd(TCTDB *tdb, int fd){ assert(tdb && fd >= 0); tchdbsetdbgfd(tdb->hdb, fd);}/* Get the file descriptor for debugging output. */int tctdbdbgfd(TCTDB *tdb){ assert(tdb); return tchdbdbgfd(tdb->hdb);}/* Check whether mutual exclusion control is set to a table database object. */bool tctdbhasmutex(TCTDB *tdb){ assert(tdb); return tdb->mmtx != NULL;}/* Synchronize updating contents on memory of a table database object. */bool tctdbmemsync(TCTDB *tdb, bool phys){ assert(tdb); if(!tdb->open || !tdb->wmode){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bool err = false; if(!tchdbmemsync(tdb->hdb, phys)) err = true; TDBIDX *idxs = tdb->idxs; int inum = tdb->inum; for(int i = 0; i < inum; i++){ TDBIDX *idx = idxs + i; switch(idx->type){ case TDBITLEXICAL: case TDBITDECIMAL: if(!tcbdbmemsync(idx->db, phys)){ tctdbsetecode(tdb, tcbdbecode(idx->db), __FILE__, __LINE__, __func__); err = true; } break; } } return !err;}/* Get the number of elements of the bucket array of a table database object. */uint64_t tctdbbnum(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbbnum(tdb->hdb);}/* Get the record alignment of a table database object. */uint32_t tctdbalign(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbalign(tdb->hdb);}/* Get the maximum number of the free block pool of a table database object. */uint32_t tctdbfbpmax(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbfbpmax(tdb->hdb);}/* Get the inode number of the database file of a table database object. */uint64_t tctdbinode(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbinode(tdb->hdb);}/* Get the modification time of the database file of a table database object. */time_t tctdbmtime(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbmtime(tdb->hdb);}/* Get the additional flags of a table database object. */uint8_t tctdbflags(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbflags(tdb->hdb);}/* Get the options of a table database object. */uint8_t tctdbopts(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tdb->opts;}/* Get the pointer to the opaque field of a table database object. */char *tctdbopaque(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return NULL; } return tchdbopaque(tdb->hdb) + TDBOPAQUESIZ;}/* Get the number of used elements of the bucket array of a table database object. */uint64_t tctdbbnumused(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbbnumused(tdb->hdb);}/* Get the number of column indices of a table database object. */int tctdbinum(TCTDB *tdb){ assert(tdb); if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tdb->inum;}/* Get the seed of unique ID unumbers of a table database object. */int64_t tctdbuidseed(TCTDB *tdb){ assert(tdb); if(!TDBLOCKMETHOD(tdb, false)) return -1; if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); TDBUNLOCKMETHOD(tdb); return -1; } int64_t rv = tctdbgenuidimpl(tdb, 0); TDBUNLOCKMETHOD(tdb); return rv;}/* Set the seed of unique ID unumbers of a table database object. */bool tctdbsetuidseed(TCTDB *tdb, int64_t seed){ assert(tdb && seed >= 0); if(!TDBLOCKMETHOD(tdb, true)) return -1; if(!tdb->open || !tdb->wmode){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); TDBUNLOCKMETHOD(tdb); return false; } tctdbgenuidimpl(tdb, -seed - 1); TDBUNLOCKMETHOD(tdb); return true;}/* Set the custom codec functions of a table database object. */bool tctdbsetcodecfunc(TCTDB *tdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop){ assert(tdb && enc && dec); if(!TDBLOCKMETHOD(tdb, true)) return false; if(tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); TDBUNLOCKMETHOD(tdb); return false; } bool rv = tchdbsetcodecfunc(tdb->hdb, enc, encop, dec, decop); TDBUNLOCKMETHOD(tdb); return rv;}/* Process each record atomically of a table database object. */bool tctdbforeach(TCTDB *tdb, TCITER iter, void *op){ assert(tdb && iter); if(!TDBLOCKMETHOD(tdb, false)) return false; if(!tdb->open){ tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__); TDBUNLOCKMETHOD(tdb); return false; } TDBTHREADYIELD(tdb); bool rv = tctdbforeachimpl(tdb, iter, op); TDBUNLOCKMETHOD(tdb); return rv;}/* Convert a string into the index type number. */int tctdbstrtoindextype(const char *str){ assert(str); int type = -1; int flags = 0; if(*str == '+'){ flags |= TDBITKEEP; str++; } if(!tcstricmp(str, "LEX") || !tcstricmp(str, "LEXICAL") || !tcstricmp(str, "STR")){ type = TDBITLEXICAL; } else if(!tcstricmp(str, "DEC") || !tcstricmp(str, "DECIMAL") || !tcstricmp(str, "NUM")){ type = TDBITDECIMAL; } else if(!tcstricmp(str, "OPT") || !tcstricmp(str, "OPTIMIZE")){ type = TDBITOPT; } else if(!tcstricmp(str, "VOID") || !tcstricmp(str, "NULL")){ type = TDBITVOID; } else if(tcstrisnum(str)){ type = tcatoi(str); } return type | flags;}/* Get the count of corresponding records of a query object. */int tctdbqrycount(TDBQRY *qry){ assert(qry); return qry->count;}/* Convert a string into the query operation number. */int tctdbqrystrtocondop(const char *str){ assert(str); int op = -1; int flags = 0; if(*str == '~' || *str == '!'){ flags |= TDBQCNEGATE; str++; } if(*str == '+'){ flags |= TDBQCNOIDX; str++; } if(!tcstricmp(str, "STREQ")){ op = TDBQCSTREQ; } else if(!tcstricmp(str, "STRINC")){ op = TDBQCSTRINC; } else if(!tcstricmp(str, "STRBW")){ op = TDBQCSTRBW; } else if(!tcstricmp(str, "STREW")){ op = TDBQCSTREW; } else if(!tcstricmp(str, "STRAND")){ op = TDBQCSTRAND; } else if(!tcstricmp(str, "STROR")){ op = TDBQCSTROR; } else if(!tcstricmp(str, "STROREQ")){ op = TDBQCSTROREQ; } else if(!tcstricmp(str, "STRRX")){ op = TDBQCSTRRX; } else if(!tcstricmp(str, "NUMEQ")){ op = TDBQCNUMEQ; } else if(!tcstricmp(str, "NUMGT")){ op = TDBQCNUMGT; } else if(!tcstricmp(str, "NUMGE")){ op = TDBQCNUMGE; } else if(!tcstricmp(str, "NUMLT")){ op = TDBQCNUMLT; } else if(!tcstricmp(str, "NUMLE")){ op = TDBQCNUMLE; } else if(!tcstricmp(str, "NUMBT")){ op = TDBQCNUMBT; } else if(!tcstricmp(str, "NUMOREQ")){ op = TDBQCNUMOREQ; } else if(tcstrisnum(str)){ op = tcatoi(str); } return op | flags;}/* Convert a string into the query order type number. */int tctdbqrystrtoordertype(const char *str){ assert(str); int type = -1; if(!tcstricmp(str, "STRASC") || !tcstricmp(str, "STR")){ type = TDBQOSTRASC; } else if(!tcstricmp(str, "STRDESC")){ type = TDBQOSTRDESC; } else if(!tcstricmp(str, "NUMASC") || !tcstricmp(str, "NUM")){ type = TDBQONUMASC; } else if(!tcstricmp(str, "NUMDESC")){ type = TDBQONUMDESC; } else if(tcstrisnum(str)){ type = tcatoi(str); } return type;}/************************************************************************************************* * private features *************************************************************************************************//* Clear all members. `tdb' specifies the table database object. */static void tctdbclear(TCTDB *tdb){ assert(tdb); tdb->mmtx = NULL; tdb->hdb = NULL; tdb->open = false; tdb->wmode = false; tdb->opts = 0; tdb->lcnum = TDBDEFLCNUM; tdb->ncnum = TDBDEFNCNUM; tdb->idxs = NULL; tdb->inum = 0; tdb->tran = false;}/* Open a database file and connect a table database object. `tdb' specifies the table database object. `path' specifies the path of the internal database file. `omode' specifies the connection mode. If successful, the return value is true, else, it is false. */static bool tctdbopenimpl(TCTDB *tdb, const char *path, int omode){ assert(tdb && path); TCCODEC enc, dec; void *encop, *decop; tchdbcodecfunc(tdb->hdb, &enc, &encop, &dec, &decop); int homode = HDBOREADER; int bomode = BDBOREADER; if(omode & TDBOWRITER){ homode = HDBOWRITER; bomode = BDBOWRITER; if(omode & TDBOCREAT){ homode |= HDBOCREAT; bomode |= BDBOCREAT; } if(omode & TDBOTRUNC){ homode |= HDBOTRUNC; bomode |= BDBOTRUNC; } tdb->wmode = true; } else { tdb->wmode = false; } if(omode & TDBONOLCK){ homode |= HDBONOLCK; bomode |= BDBONOLCK; } if(omode & TDBOLCKNB){ homode |= HDBOLCKNB; bomode |= BDBOLCKNB; } if(omode & TDBOTSYNC){ homode |= HDBOTSYNC; bomode |= BDBOTSYNC; } tchdbsettype(tdb->hdb, TCDBTTABLE); if(!tchdbopen(tdb->hdb, path, homode)) return false; char *tpath = tcsprintf("%s%c%s%c*", path, MYEXTCHR, TDBIDXSUFFIX, MYEXTCHR); if((omode & TDBOWRITER) && (omode & TDBOTRUNC)){ TCLIST *paths = tcglobpat(tpath); int pnum = TCLISTNUM(paths); for(int i = 0; i < pnum; i++){ unlink(TCLISTVALPTR(paths, i));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -