📄 tcfdb.c
字号:
assert(fdb && kstr); return tcfdbout(fdb, tcfdbkeytoid(kstr, strlen(kstr)));}/* Retrieve a record in a fixed-length database object. */void *tcfdbget(TCFDB *fdb, int64_t id, int *sp){ assert(fdb && sp); if(!FDBLOCKMETHOD(fdb, false)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(id == FDBIDMIN){ id = fdb->min; } else if(id == FDBIDMAX){ id = fdb->max; } if(id < 1 || id > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(!FDBLOCKRECORD(fdb, false, id)){ FDBUNLOCKMETHOD(fdb); return false; } const void *vbuf = tcfdbgetimpl(fdb, id, sp); char *rv = vbuf ? tcmemdup(vbuf, *sp) : NULL; FDBUNLOCKRECORD(fdb, id); FDBUNLOCKMETHOD(fdb); return rv;}/* Retrieve a record with a decimal key in a fixed-length database object. */void *tcfdbget2(TCFDB *fdb, const void *kbuf, int ksiz, int *sp){ assert(fdb && kbuf && ksiz >= 0 && sp); return tcfdbget(fdb, tcfdbkeytoid(kbuf, ksiz), sp);}/* Retrieve a string record with a decimal key in a fixed-length database object. */char *tcfdbget3(TCFDB *fdb, const char *kstr){ assert(fdb && kstr); int vsiz; return tcfdbget(fdb, tcfdbkeytoid(kstr, strlen(kstr)), &vsiz);}/* Retrieve a record in a fixed-length database object and write the value into a buffer. */int tcfdbget4(TCFDB *fdb, int64_t id, void *vbuf, int max){ assert(fdb && vbuf && max >= 0); if(!FDBLOCKMETHOD(fdb, false)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(id == FDBIDMIN){ id = fdb->min; } else if(id == FDBIDMAX){ id = fdb->max; } if(id < 1 || id > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(!FDBLOCKRECORD(fdb, false, id)){ FDBUNLOCKMETHOD(fdb); return false; } int vsiz; const void *rbuf = tcfdbgetimpl(fdb, id, &vsiz); if(rbuf){ if(vsiz > max) vsiz = max; memcpy(vbuf, rbuf, vsiz); } else { vsiz = -1; } FDBUNLOCKRECORD(fdb, id); FDBUNLOCKMETHOD(fdb); return vsiz;}/* Get the size of the value of a record in a fixed-length database object. */int tcfdbvsiz(TCFDB *fdb, int64_t id){ assert(fdb); if(!FDBLOCKMETHOD(fdb, false)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(id == FDBIDMIN){ id = fdb->min; } else if(id == FDBIDMAX){ id = fdb->max; } if(id < 1 || id > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(!FDBLOCKRECORD(fdb, false, id)){ FDBUNLOCKMETHOD(fdb); return false; } int vsiz; const void *vbuf = tcfdbgetimpl(fdb, id, &vsiz); if(!vbuf) vsiz = -1; FDBUNLOCKRECORD(fdb, id); FDBUNLOCKMETHOD(fdb); return vsiz;}/* Get the size of the value with a decimal key in a fixed-length database object. */int tcfdbvsiz2(TCFDB *fdb, const void *kbuf, int ksiz){ assert(fdb && kbuf && ksiz >= 0); return tcfdbvsiz(fdb, tcfdbkeytoid(kbuf, ksiz));}/* Get the size of the string value with a decimal key in a fixed-length database object. */int tcfdbvsiz3(TCFDB *fdb, const char *kstr){ assert(fdb && kstr); return tcfdbvsiz(fdb, tcfdbkeytoid(kstr, strlen(kstr)));}/* Initialize the iterator of a fixed-length database object. */bool tcfdbiterinit(TCFDB *fdb){ assert(fdb); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } bool rv = tcfdbiterinitimpl(fdb); FDBUNLOCKMETHOD(fdb); return rv;}/* Get the next ID number of the iterator of a fixed-length database object. */uint64_t tcfdbiternext(TCFDB *fdb){ assert(fdb); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } uint64_t rv = tcfdbiternextimpl(fdb); FDBUNLOCKMETHOD(fdb); return rv;}/* Get the next decimay key of the iterator of a fixed-length database object. */void *tcfdbiternext2(TCFDB *fdb, int *sp){ assert(fdb && sp); uint64_t id = tcfdbiternextimpl(fdb); if(id < 1) return NULL; char kbuf[TCNUMBUFSIZ]; int ksiz = sprintf(kbuf, "%llu", (unsigned long long)id); *sp = ksiz; return tcmemdup(kbuf, ksiz);}/* Get the next decimay key string of the iterator of a fixed-length database object. */char *tcfdbiternext3(TCFDB *fdb){ assert(fdb); int ksiz; return tcfdbiternext2(fdb, &ksiz);}/* Get range matching decimal keys in a fixed-length database object. */uint64_t *tcfdbrange(TCFDB *fdb, int64_t lower, int64_t upper, int max, int *np){ assert(fdb && np); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); *np = 0; return tcmalloc(1); } if(lower == FDBIDMIN) lower = fdb->min; if(upper == FDBIDMAX) upper = fdb->max; if(lower < 1 || lower > fdb->limid || upper < 1 || upper > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); *np = 0; return tcmalloc(1); } uint64_t *rv = tcfdbrangeimpl(fdb, lower, upper, max, np); FDBUNLOCKMETHOD(fdb); return rv;}/* Get range matching decimal keys in a fixed-length database object. */TCLIST *tcfdbrange2(TCFDB *fdb, const void *lbuf, int lsiz, const void *ubuf, int usiz, int max){ assert(fdb && lbuf && lsiz >= 0 && ubuf && usiz >= 0); int num; uint64_t *ids = tcfdbrange(fdb, tcfdbkeytoid(lbuf, lsiz), tcfdbkeytoid(ubuf, usiz), max, &num); TCLIST *keys = tclistnew2(num); for(int i = 0; i < num; i++){ char kbuf[TCNUMBUFSIZ]; int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]); TCLISTPUSH(keys, kbuf, ksiz); } TCFREE(ids); return keys;}/* Get range matching decimal keys with strings in a fixed-length database object. */TCLIST *tcfdbrange3(TCFDB *fdb, const char *lstr, const char *ustr, int max){ assert(fdb && lstr && ustr); return tcfdbrange2(fdb, lstr, strlen(lstr), ustr, strlen(ustr), max);}/* Get keys with an interval notation in a fixed-length database object. */TCLIST *tcfdbrange4(TCFDB *fdb, const void *ibuf, int isiz, int max){ assert(fdb && ibuf && isiz >= 0); char *expr; TCMEMDUP(expr, ibuf, isiz); char *pv = expr; while(*pv > '\0' && *pv <= ' '){ pv++; } bool linc = false; if(*pv == '['){ linc = true; } else if(*pv != '('){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); TCFREE(expr); return tclistnew(); } pv++; char *sep = strchr(pv, ','); if(!sep){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); TCFREE(expr); return tclistnew(); } *sep = '\0'; tcstrtrim(pv); int64_t lower = tcfdbkeytoid(pv, strlen(pv)); pv = sep + 1; bool uinc = false; if((sep = strchr(pv, ']')) != NULL){ uinc = true; *sep = '\0'; } else if((sep = strchr(pv, ')')) != NULL){ *sep = '\0'; } else { tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); TCFREE(expr); return tclistnew(); } tcstrtrim(pv); int64_t upper = tcfdbkeytoid(pv, strlen(pv)); if(lower == FDBIDMIN){ lower = fdb->min; } else if(lower == FDBIDPREV){ lower = fdb->min - 1; } else if(lower == FDBIDMAX){ lower = fdb->max; } else if(lower == FDBIDNEXT){ lower = fdb->max + 1; } if(!linc) lower++; if(upper == FDBIDMIN){ upper = fdb->min; } else if(upper == FDBIDPREV){ upper = fdb->min - 1; } else if(upper == FDBIDMAX){ upper = fdb->max; } else if(upper == FDBIDNEXT){ upper = fdb->max + 1; } if(!uinc) upper--; TCFREE(expr); int num; uint64_t *ids = tcfdbrange(fdb, lower, upper, max, &num); TCLIST *keys = tclistnew2(num); for(int i = 0; i < num; i++){ char kbuf[TCNUMBUFSIZ]; int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]); TCLISTPUSH(keys, kbuf, ksiz); } TCFREE(ids); return keys;}/* Get keys with an interval notation string in a fixed-length database object. */TCLIST *tcfdbrange5(TCFDB *fdb, const void *istr, int max){ assert(fdb && istr); return tcfdbrange4(fdb, istr, strlen(istr), max);}/* Add an integer to a record in a fixed-length database object. */int tcfdbaddint(TCFDB *fdb, int64_t id, int num){ assert(fdb); if(!FDBLOCKMETHOD(fdb, id < 1)) return INT_MIN; if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return INT_MIN; } if(id == FDBIDMIN){ id = fdb->min; } else if(id == FDBIDPREV){ id = fdb->min - 1; } else if(id == FDBIDMAX){ id = fdb->max; } else if(id == FDBIDNEXT){ id = fdb->max + 1; } if(id < 1 || id > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return INT_MIN; } if(!FDBLOCKRECORD(fdb, true, id)){ FDBUNLOCKMETHOD(fdb); return INT_MIN; } bool rv = tcfdbputimpl(fdb, id, (char *)&num, sizeof(num), FDBPDADDINT); FDBUNLOCKRECORD(fdb, id); FDBUNLOCKMETHOD(fdb); return rv ? num : INT_MIN;}/* Add a real number to a record in a fixed-length database object. */double tcfdbadddouble(TCFDB *fdb, int64_t id, double num){ assert(fdb); if(!FDBLOCKMETHOD(fdb, id < 1)) return nan(""); if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return nan(""); } if(id == FDBIDMIN){ id = fdb->min; } else if(id == FDBIDPREV){ id = fdb->min - 1; } else if(id == FDBIDMAX){ id = fdb->max; } else if(id == FDBIDNEXT){ id = fdb->max + 1; } if(id < 1 || id > fdb->limid){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return nan(""); } if(!FDBLOCKRECORD(fdb, true, id)){ FDBUNLOCKMETHOD(fdb); return nan(""); } bool rv = tcfdbputimpl(fdb, id, (char *)&num, sizeof(num), FDBPDADDDBL); FDBUNLOCKRECORD(fdb, id); FDBUNLOCKMETHOD(fdb); return rv ? num : nan("");}/* Synchronize updated contents of a fixed-length database object with the file and the device. */bool tcfdbsync(TCFDB *fdb){ assert(fdb); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } bool rv = tcfdbmemsync(fdb, true); FDBUNLOCKMETHOD(fdb); return rv;}/* Optimize the file of a fixed-length database object. */bool tcfdboptimize(TCFDB *fdb, int32_t width, int64_t limsiz){ assert(fdb); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } FDBTHREADYIELD(fdb); bool rv = tcfdboptimizeimpl(fdb, width, limsiz); FDBUNLOCKMETHOD(fdb); return rv;}/* Remove all records of a fixed-length database object. */bool tcfdbvanish(TCFDB *fdb){ assert(fdb); if(!FDBLOCKMETHOD(fdb, true)) return false; if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } FDBTHREADYIELD(fdb); bool rv = tcfdbvanishimpl(fdb); FDBUNLOCKMETHOD(fdb); return rv;}/* Copy the database file of a fixed-length database object. */bool tcfdbcopy(TCFDB *fdb, const char *path){ assert(fdb && path); if(!FDBLOCKMETHOD(fdb, false)) return false; if(fdb->fd < 0){ tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__); FDBUNLOCKMETHOD(fdb); return false; } if(!FDBLOCKALLRECORDS(fdb, false)){ FDBUNLOCKMETHOD(fdb); return false; } FDBTHREADYIELD(fdb); bool rv = tcfdbcopyimpl(fdb, path); FDBUNLOCKALLRECORDS(fdb); FDBUNLOCKMETHOD(fdb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -