📄 tcadb.c
字号:
/************************************************************************************************* * The abstract database API of Tokyo Cabinet * Copyright (C) 2006-2008 Mikio Hirabayashi * This file is part of Tokyo Cabinet. * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of * the GNU Lesser General Public License as published by the Free Software Foundation; either * version 2.1 of the License or any later version. Tokyo Cabinet is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * You should have received a copy of the GNU Lesser General Public License along with Tokyo * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA. *************************************************************************************************/#include "tcutil.h"#include "tchdb.h"#include "tcbdb.h"#include "tcadb.h"#include "myconf.h"enum { // enumeration for open modes ADBOVOID, // not opened ADBOMDB, // on-memory hash database ADBONDB, // on-memory tree database ADBOHDB, // hash database ADBOBDB, // B+ tree database ADBOFDB // fixed-length database};/************************************************************************************************* * API *************************************************************************************************//* Create an abstract database object. */TCADB *tcadbnew(void){ TCADB *adb; TCMALLOC(adb, sizeof(*adb)); adb->name = NULL; adb->omode = ADBOVOID; adb->mdb = NULL; adb->ndb = NULL; adb->hdb = NULL; adb->bdb = NULL; adb->fdb = NULL; adb->capnum = -1; adb->capsiz = -1; adb->capcnt = 0; adb->cur = NULL; return adb;}/* Delete an abstract database object. */void tcadbdel(TCADB *adb){ assert(adb); if(adb->name) tcadbclose(adb); TCFREE(adb);}/* Open an abstract database. */bool tcadbopen(TCADB *adb, const char *name){ assert(adb && name); if(adb->name) return false; TCLIST *elems = tcstrsplit(name, "#"); char *path = tclistshift2(elems); if(!path){ tclistdel(elems); return false; } int64_t bnum = -1; int64_t capnum = -1; int64_t capsiz = -1; bool owmode = true; bool ocmode = true; bool otmode = false; bool onlmode = false; bool onbmode = false; int8_t apow = -1; int8_t fpow = -1; bool tlmode = false; bool tdmode = false; bool tbmode = false; bool ttmode = false; int32_t rcnum = -1; int64_t xmsiz = -1; int32_t lmemb = -1; int32_t nmemb = -1; int32_t lcnum = -1; int32_t ncnum = -1; int32_t width = -1; int64_t limsiz = -1; int ln = TCLISTNUM(elems); for(int i = 0; i < ln; i++){ const char *elem = TCLISTVALPTR(elems, i); char *pv = strchr(elem, '='); if(!pv) continue; *(pv++) = '\0'; if(!tcstricmp(elem, "bnum")){ bnum = tcatoi(pv); } else if(!tcstricmp(elem, "capnum")){ capnum = tcatoi(pv); } else if(!tcstricmp(elem, "capsiz")){ capsiz = tcatoi(pv); } else if(!tcstricmp(elem, "mode")){ owmode = strchr(pv, 'w') || strchr(pv, 'W'); ocmode = strchr(pv, 'c') || strchr(pv, 'C'); otmode = strchr(pv, 't') || strchr(pv, 'T'); onlmode = strchr(pv, 'e') || strchr(pv, 'E'); onbmode = strchr(pv, 'f') || strchr(pv, 'F'); } else if(!tcstricmp(elem, "apow")){ apow = tcatoi(pv); } else if(!tcstricmp(elem, "fpow")){ fpow = tcatoi(pv); } else if(!tcstricmp(elem, "opts")){ if(strchr(pv, 'l') || strchr(pv, 'L')) tlmode = true; if(strchr(pv, 'd') || strchr(pv, 'D')) tdmode = true; if(strchr(pv, 'b') || strchr(pv, 'B')) tbmode = true; if(strchr(pv, 't') || strchr(pv, 'T')) ttmode = true; } else if(!tcstricmp(elem, "rcnum")){ rcnum = tcatoi(pv); } else if(!tcstricmp(elem, "xmsiz")){ xmsiz = tcatoi(pv); } else if(!tcstricmp(elem, "lmemb")){ lmemb = tcatoi(pv); } else if(!tcstricmp(elem, "nmemb")){ nmemb = tcatoi(pv); } else if(!tcstricmp(elem, "lcnum")){ lcnum = tcatoi(pv); } else if(!tcstricmp(elem, "ncnum")){ ncnum = tcatoi(pv); } else if(!tcstricmp(elem, "width")){ width = tcatoi(pv); } else if(!tcstricmp(elem, "limsiz")){ limsiz = tcatoi(pv); } } tclistdel(elems); if(!tcstricmp(path, "*")){ adb->mdb = bnum > 0 ? tcmdbnew2(bnum) : tcmdbnew(); adb->capnum = capnum; adb->capsiz = capsiz; adb->capcnt = 0; adb->omode = ADBOMDB; } else if(!tcstricmp(path, "+")){ adb->ndb = tcndbnew(); adb->capnum = capnum; adb->capsiz = capsiz; adb->capcnt = 0; adb->omode = ADBONDB; } else if(tcstribwm(path, ".tch")){ TCHDB *hdb = tchdbnew(); tchdbsetmutex(hdb); int opts = 0; if(tlmode) opts |= HDBTLARGE; if(tdmode) opts |= HDBTDEFLATE; if(tbmode) opts |= HDBTBZIP; if(ttmode) opts |= HDBTTCBS; tchdbtune(hdb, bnum, apow, fpow, opts); tchdbsetcache(hdb, rcnum); if(xmsiz >= 0) tchdbsetxmsiz(hdb, xmsiz); int omode = owmode ? HDBOWRITER : HDBOREADER; if(ocmode) omode |= HDBOCREAT; if(otmode) omode |= HDBOTRUNC; if(onlmode) omode |= HDBONOLCK; if(onbmode) omode |= HDBOLCKNB; if(!tchdbopen(hdb, path, omode)){ tchdbdel(hdb); TCFREE(path); return false; } adb->hdb = hdb; adb->omode = ADBOHDB; } else if(tcstribwm(path, ".tcb")){ TCBDB *bdb = tcbdbnew(); tcbdbsetmutex(bdb); int opts = 0; if(tlmode) opts |= BDBTLARGE; if(tdmode) opts |= BDBTDEFLATE; if(tbmode) opts |= BDBTBZIP; if(ttmode) opts |= BDBTTCBS; tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts); tcbdbsetcache(bdb, lcnum, ncnum); if(xmsiz >= 0) tcbdbsetxmsiz(bdb, xmsiz); if(capnum > 0) tcbdbsetcapnum(bdb, capnum); int omode = owmode ? BDBOWRITER : BDBOREADER; if(ocmode) omode |= BDBOCREAT; if(otmode) omode |= BDBOTRUNC; if(onlmode) omode |= BDBONOLCK; if(onbmode) omode |= BDBOLCKNB; if(!tcbdbopen(bdb, path, omode)){ tcbdbdel(bdb); TCFREE(path); return false; } adb->bdb = bdb; adb->cur = tcbdbcurnew(bdb); adb->omode = ADBOBDB; } else if(tcstribwm(path, ".tcf")){ TCFDB *fdb = tcfdbnew(); tcfdbsetmutex(fdb); tcfdbtune(fdb, width, limsiz); int omode = owmode ? FDBOWRITER : FDBOREADER; if(ocmode) omode |= FDBOCREAT; if(otmode) omode |= FDBOTRUNC; if(onlmode) omode |= FDBONOLCK; if(onbmode) omode |= FDBOLCKNB; if(!tcfdbopen(fdb, path, omode)){ tcfdbdel(fdb); TCFREE(path); return false; } adb->fdb = fdb; adb->omode = ADBOFDB; } else { TCFREE(path); return false; } TCFREE(path); adb->name = tcstrdup(name); return true;}/* Close an abstract database object. */bool tcadbclose(TCADB *adb){ assert(adb); int err = false; if(!adb->name) return false; switch(adb->omode){ case ADBOMDB: tcmdbdel(adb->mdb); adb->mdb = NULL; break; case ADBONDB: tcndbdel(adb->ndb); adb->ndb = NULL; break; case ADBOHDB: if(!tchdbclose(adb->hdb)) err = true; tchdbdel(adb->hdb); adb->hdb = NULL; break; case ADBOBDB: tcbdbcurdel(adb->cur); if(!tcbdbclose(adb->bdb)) err = true; tcbdbdel(adb->bdb); adb->bdb = NULL; break; case ADBOFDB: if(!tcfdbclose(adb->fdb)) err = true; tcfdbdel(adb->fdb); adb->fdb = NULL; break; default: err = true; break; } TCFREE(adb->name); adb->name = NULL; return !err;}/* Store a record into an abstract database object. */bool tcadbput(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); bool err = false; switch(adb->omode){ case ADBOMDB: tcmdbput(adb->mdb, kbuf, ksiz, vbuf, vsiz); if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); } } break; case ADBONDB: tcndbput(adb->ndb, kbuf, ksiz, vbuf, vsiz); if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcndbrnum(adb->ndb) > adb->capnum) tcndbcutfringe(adb->ndb, 0x100); if(adb->capsiz > 0 && tcndbmsiz(adb->ndb) > adb->capsiz) tcndbcutfringe(adb->ndb, 0x200); } } break; case ADBOHDB: if(!tchdbput(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOBDB: if(!tcbdbput(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOFDB: if(!tcfdbput2(adb->fdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; default: err = true; break; } return !err;}/* Store a string record into an abstract object. */bool tcadbput2(TCADB *adb, const char *kstr, const char *vstr){ assert(adb && kstr && vstr); return tcadbput(adb, kstr, strlen(kstr), vstr, strlen(vstr));}/* Store a new record into an abstract database object. */bool tcadbputkeep(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); bool err = false; switch(adb->omode){ case ADBOMDB: if(tcmdbputkeep(adb->mdb, kbuf, ksiz, vbuf, vsiz)){ if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); } } } else { err = true; } break; case ADBONDB: if(tcndbputkeep(adb->ndb, kbuf, ksiz, vbuf, vsiz)){ if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcndbrnum(adb->ndb) > adb->capnum) tcndbcutfringe(adb->ndb, 0x100); if(adb->capsiz > 0 && tcndbmsiz(adb->ndb) > adb->capsiz) tcndbcutfringe(adb->ndb, 0x200); } } } else { err = true; } break; case ADBOHDB: if(!tchdbputkeep(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOBDB: if(!tcbdbputkeep(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOFDB: if(!tcfdbputkeep2(adb->fdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; default: err = true; break; } return !err;}/* Store a new string record into an abstract database object. */bool tcadbputkeep2(TCADB *adb, const char *kstr, const char *vstr){ assert(adb && kstr && vstr); return tcadbputkeep(adb, kstr, strlen(kstr), vstr, strlen(vstr));}/* Concatenate a value at the end of the existing record in an abstract database object. */bool tcadbputcat(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); bool err = false; switch(adb->omode){ case ADBOMDB: tcmdbputcat(adb->mdb, kbuf, ksiz, vbuf, vsiz); if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); } } break; case ADBONDB: tcndbputcat(adb->ndb, kbuf, ksiz, vbuf, vsiz); if(adb->capnum > 0 || adb->capsiz > 0){ adb->capcnt++; if((adb->capcnt & 0xff) == 0){ if(adb->capnum > 0 && tcndbrnum(adb->ndb) > adb->capnum) tcndbcutfringe(adb->ndb, 0x100); if(adb->capsiz > 0 && tcndbmsiz(adb->ndb) > adb->capsiz) tcndbcutfringe(adb->ndb, 0x200); } } break; case ADBOHDB: if(!tchdbputcat(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOBDB: if(!tcbdbputcat(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; case ADBOFDB: if(!tcfdbputcat2(adb->fdb, kbuf, ksiz, vbuf, vsiz)) err = true; break; default: err = true; break; } return !err;}/* Concatenate a string value at the end of the existing record in an abstract database object. */bool tcadbputcat2(TCADB *adb, const char *kstr, const char *vstr){ assert(adb && kstr && vstr); return tcadbputcat(adb, kstr, strlen(kstr), vstr, strlen(vstr));}/* Remove a record of an abstract database object. */bool tcadbout(TCADB *adb, const void *kbuf, int ksiz){ assert(adb && kbuf && ksiz >= 0); bool err = false; switch(adb->omode){ case ADBOMDB: if(!tcmdbout(adb->mdb, kbuf, ksiz)) err = true; break; case ADBONDB: if(!tcndbout(adb->ndb, kbuf, ksiz)) err = true; break; case ADBOHDB: if(!tchdbout(adb->hdb, kbuf, ksiz)) err = true; break; case ADBOBDB: if(!tcbdbout(adb->bdb, kbuf, ksiz)) err = true; break; case ADBOFDB: if(!tcfdbout2(adb->fdb, kbuf, ksiz)) err = true; break; default: err = true; break; } return !err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -