Tokyo Cabinet


  • CLI
  • String
  • List
  • Map
  • Tree
  • memHashDb
  • memTreeDb
  • HashDb
  • TreeDb

  • Tokyo Cabinet is a library of routines for managing a database. the database is a simple data file containing records, each is a pair of a key and a value. every key and value is serial bytes with variable length. both binary data and character string can be used as a key and a value. there is neither concept of data tables nor data types. records are organized in

    the following access methods are provided to the database:

    as for database of fixed-length array, records are stored with unique natural numbers (thought the keys can contain underscore "_" , defis "-" , comma "," , point "." , questionmark "?" - all of them will be converted into empty). the length of each record is limited by the specified length. provided operations are the same as ones of hash database

    Tokyo Cabinet is written in the C language, and provided as API of C89 (ANSI)/C99, Perl, Ruby, and Lua. Tokyo Cabinet is available on platforms which have API conforming to C99 and POSIX

    like BerkeleyDB, TC gives you low-level database operations and allows you to build your own very fast data access operations. unlike BerkeleyDB, TC has several functional layers on top of TC which provide

    Tokyo Cabinet provides two modes to connect to a database: "reader" and "writer"

    a "reader" can perform retrieving but neither storing nor deleting. a "writer" can perform all access methods

    exclusion control between processes is performed when connecting to a database by file locking

    while a "writer" is connected to a database, neither "readers" nor "writers" can be connected

    while a "reader" is connected to a database, other "readers" can be connect, but "writers" can not


    CLI


    $> ttserver -host 127.0.0.1 -port 9000 /home/user/work/testdb.tch 
    2019-06-23T07:47:40Z  SYSTEM  --------- logging started [7267] --------
    2019-06-23T07:47:40Z  SYSTEM  server configuration: host=127.0.0.1 port=9000
    2019-06-23T07:47:40Z  SYSTEM  maximum connection: 4095
    2019-06-23T07:47:40Z  SYSTEM  opening the database: /home/user/work/testdb.tch
    2019-06-23T07:47:40Z  SYSTEM  service started: 7267
    2019-06-23T07:47:40Z  INFO  timer thread 1 started
    2019-06-23T07:47:40Z  INFO  worker thread 1 started
    2019-06-23T07:47:40Z  INFO  worker thread 2 started
    2019-06-23T07:47:40Z  INFO  worker thread 3 started
    2019-06-23T07:47:40Z  INFO  worker thread 4 started
    2019-06-23T07:47:40Z  INFO  worker thread 5 started
    2019-06-23T07:47:40Z  INFO  worker thread 6 started
    2019-06-23T07:47:40Z  INFO  worker thread 7 started
    2019-06-23T07:47:40Z  INFO  worker thread 8 started
    2019-06-23T07:47:40Z  SYSTEM  listening started
    
    $> tcrmgr version -port 9000 localhost 
    Tokyo Tyrant version 1.1.41 (324:0.91) for Linux
    Copyright (C) 2007-2010 Mikio Hirabayashi
    
    $> tcrmgr get -port 9000 localhost key1
    2019-06-23T07:48:26Z  INFO  connected: 127.0.0.1:38850
    value1 12 3.14 
    2019-06-23T07:48:26Z  INFO  connection finished
    
    $> for y in key1 key2 ; do tcrmgr get -port 9000 localhost $y | cat | while read -a x ; do echo ${x[2]} ; done ; done
    3.14
    2.72
    

    tcrmgr - CLI of the remote database

      $> time for x in {1..2000}; do tcrmgr get localhost somekey ; done
    
      $> ttserver -host 127.0.0.1 -port 9000 /path/to/your/database/yourdbname.tch
      $> tcrmgr get -port 9000 localhost yourkeyid 
    
    you can delete all records of your database via tokyotyrant with the vanish command, e.g
    
      $> tcrmgr vanish [-port num] host
    

    tchmgr - CLI for hash database

    $> tchmgr version
    Tokyo Cabinet version 1.4.48 (911:1.0) for Linux
    Copyright (C) 2006-2012 FAL Labs
    
    
    
    
                tc  - "tokyo cabinet"
                h   - h-hash
                mgr - manager
    
    
            `path'   the path of a database file
            `bnum'   the number of buckets
            `apow'   the power of the alignment
            `key'    the key of a record
            `value'  the value of a record
    
    
     tchmgr create [-tl] [-td|-tb|-tt|-tx] path [bnum [apow [fpow]]]
            Create a database file.
    
     tchmgr put [-nl|-nb] [-sx] [-dk|-dc|-dai|-dad] path key value
            Store a record.
    
     tchmgr out [-nl|-nb] [-sx] path key
            Remove a record.
    
     tchmgr get [-nl|-nb] [-sx] [-px] [-pz] path key
            Print the value of a record.
    
     tchmgr list [-nl|-nb] [-m num] [-pv] [-px] [-fm str] path
            Print keys of all records, separated by line feeds.
    
     tchmgr optimize [-tl] [-td|-tb|-tt|-tx] [-tz] [-nl|-nb] [-df] path [bnum [apow [fpow]]]
            Optimize a database file.
    
    
    options:
                  -tl : enable the option `HDBTLARGE'.
                  -td : enable the option `HDBTDEFLATE'.
                  -tb : enable the option `HDBTBZIP'.
                  -tt : enable the option `HDBTTCBS'.
                  -tx : enable the option `HDBTEXCODEC'.
                  -nl : enable the option `HDBNOLCK'.
                  -nb : enable the option `HDBLCKNB'.
                  -sx : the input data is evaluated as a hexadecimal data string.
                  -dk : use the function `tchdbputkeep' instead of `tchdbput'.
                  -dc : use the function `tchdbputcat' instead of `tchdbput'.
                  -dai : use the function `tchdbaddint' instead of `tchdbput'.
                  -dad : use the function `tchdbadddouble' instead of `tchdbput'.
                  -px : the output data is converted into a hexadecimal data string.
                  -pz : do not append line feed at the end of the output.
                  -m num : specify the maximum number of the output.
                  -pv : print values of records also.
                  -fm str : specify the prefix of keys.
                  -tz : enable the option `UINT8_MAX'.
                  -df : perform defragmentation only.
                  -sc : normalize keys as lower cases.
     

    tcbmgr - CLI for B+ tree database

    $> tcbmgr version
    Tokyo Cabinet version 1.4.48 (911:1.0) for Linux
    Copyright (C) 2006-2012 FAL Labs
    
    
    
                tc  - "tokyo cabinet"
                b   - b-tree
                mgr - manager
    
    
            `path'   the path of a database file
            `lmemb'  the number of members in each leaf page
            `nmemb'  the number of members in each non-leaf page
            `bnum'   the number of buckets
            `apow'   the power of the alignment
            `fpow'   the power of the free block pool
            `key'    the key of a record
            `value'  the value of a record
    
    
    tcbmgr create [-cd|-ci|-cj] [-tl] [-td|-tb|-tt|-tx] path [lmemb [nmemb [bnum [apow [fpow]]]]]
    Create a database file
    
    tcbmgr put [-cd|-ci|-cj] [-nl|-nb] [-sx] [-dk|-dc|-dd|-db|-dai|-dad] path key value
    Store a record
    
    tcbmgr out [-cd|-ci|-cj] [-nl|-nb] [-sx] path key
    Remove a record
    
    tcbmgr get [-cd|-ci|-cj] [-nl|-nb] [-sx] [-px] [-pz] path key
    Print the value of a record
    
    tcbmgr list [-cd|-ci|-cj] [-nl|-nb] [-m num] [-bk] [-pv] [-px] [-j str] [-rb bkey ekey] [-fm str] path
    Print keys of all records, separated by line feeds
    
    tcbmgr optimize [-cd|-ci|-cj] [-tl] [-td|-tb|-tt|-tx] [-tz] [-nl|-nb] [-df] path
       [lmemb [nmemb [bnum [apow [fpow]]]]]
    Optimize a database file
    
    
    options:
            -cd           : use the comparison function `tccmpdecimal'
            -ci           : use the comparison function `tccmpint32'
            -cj           : use the comparison function `tccmpint64'
            -tl           : enable the option `BDBTLARGE'
            -td           : enable the option `BDBTDEFLATE'
            -tb           : enable the option `BDBTBZIP'
            -tt           : enable the option `BDBTTCBS'
            -tx           : enable the option `BDBTEXCODEC'
            -nl           : enable the option `BDBNOLCK'
            -nb           : enable the option `BDBLCKNB'
            -sx           : the input data is evaluated as a hexadecimal data string
            -dk           : use the function `tcbdbputkeep' instead of `tcbdbput'
            -dc           : use the function `tcbdbputcat' instead of `tcbdbput'
            -dd           : use the function `tcbdbputdup' instead of `tcbdbput'
            -db           : use the function `tcbdbputdupback' instead of `tcbdbput'
            -dai          : use the function `tcbdbaddint' instead of `tcbdbput'
            -dad          : use the function `tcbdbadddouble' instead of `tcbdbput'
            -px           : the output data is converted into a hexadecimal data string
            -pz           : do not append line feed at the end of the output
            -m num        : specify the maximum number of the output
            -bk           : perform backword scanning
            -pv           : print values of records also
            -j str        : specify the key where the cursor jump to
            -rb bkey ekey : specify the range of keys
            -fm str       : specify the prefix of keys
            -tz           : enable the option `UINT8_MAX'
            -df           : perform defragmentation only
            -sc           : normalize keys as lower cases
    
    


    C-API


    as the header files of Tokyo Cabinet are provided as 'tcutil.h', 'tchdb.h', and `tcbdb.h', applications should include one of them

    the library is provided as 'libtokyocabinet.a' and `libtokyocabinet.so' and they depends on:
    libz.so
    librt.so
    libpthread.so
    libm.so
    libc.so

    linker options `-ltokyocabinet', `-lz', '-lbz2', `-lrt', `-lpthread', '-lm', and '-lc' are required for build command. A typical build command is the following

      $> gcc -I/usr/local/include tc_example.c -o tc_example /
        -L/usr/local/lib -ltokyocabinet -lz -lbz2 -lrt -lpthread -lm -lc
    

    you can also use Tokyo Cabinet in programs written in C++. because each header is wrapped in C linkage ('extern "C"' block), you can simply include them into your C++ programs


    example:

    /*    gcc -ltokyocabinet treatment.c -o z.out            */
    
    #include <tchdb.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int fold   = 0 ;
    int check  = 0 ;
    int call   = 0 ;
    int bet    = 0 ;
    int allin  = 0 ;
    
    typedef struct {
      char *nick   ;
      char *move ;
    } keyValue ;
    
    typedef keyValue* Step ;
    
    void 
    calcMoves (char* oneMove) 
    {
      if      ( 0 == strcmp ("folds",  oneMove) )        { fold++ ;  } 
      else if ( 0 == strcmp ("checks", oneMove) )        { check++ ; } 
      else if ( 0 == strcmp ("calls",  oneMove) )        { call++ ;  } 
      else if ( 0 == strcmp ("bets",   oneMove) )        { bet++ ;   } 
      else if ( 0 == strcmp ("is all in with", oneMove)) { allin++ ; } 
      else                                               {           } ;
    }
    
    Step 
    split (char* arr) 
    {
      Step x = malloc (sizeof (keyValue)) ; 
    
      x->nick = strtok (arr,  "|") ;
      x->move = strtok (NULL, "|") ;
    
      return x ;
    } ;
    
    /*  the first  arg - name of plain nick|action file  
     *  the second arg - name of plain output file       */
    int 
    main (int argc, char **argv)
    {
      TCMDB *hdb;
      FILE  *fd1, *fd2 ;
    
      hdb = tcmdbnew () ;
      fd1 = fopen (argv[1], "r") ; 
    
      char *buffer = malloc (1024) ;
    
      while ( fgets (buffer, 1024, fd1) ) 
      { 
        Step player = split (buffer) ;
        tcmdbputcat2 (hdb, player->nick, player->move) ; 
      } ;
    
      free (buffer) ;
      fclose (fd1) ;
    
      fd2 = fopen (argv[2], "w") ; 
      tcmdbiterinit (hdb) ;
    
      char *currNick = malloc (1024) ;
    
      while ( currNick = tcmdbiternext2 (hdb) ) 
      {
        char *currMoves = tcmdbget2 (hdb, currNick) ;
        char *oneMove  = malloc (1024) ; 
    
        oneMove = strtok (currMoves, "\n") ; 
        calcMoves (oneMove) ;
        while ( oneMove = strtok (NULL, "\n") ) { calcMoves (oneMove) ; } ;
        
        float sum = fold + check + call + bet + allin ;
    
        if ( sum > 135 ) 
        {
          fprintf (fd2, "%-20s | %5.2f | %5.2f | %5.2f | %5.2f | %5.2f\n", currNick, \
               (float) (fold / sum), (float) (check / sum), (float) (call / sum),   \
               (float) (bet / sum),  (float) (allin / sum) ) ;
        }
        
        fold = check = call = bet = allin = 0 ;
    
        free (currMoves) ;
        free (oneMove)   ;
      } ;
      
      free     (currNick) ;
      fclose   (fd2)      ;
      tcmdbdel (hdb)      ;
      return    0         ;
    }  
    


    utility API


    utility API is a set of routines to handle records on memory easily: extensible string, array list, hash map, and ordered tree

    #include <tcutil.h> 

    objects whose type is pointer to `TCXSTR' are used for extensible string. an extensible string object is created with the function `tcxstrnew' and is deleted with the function `tcxstrdel'

    objects whose type is pointer to `TCLIST' are used for array list. a list object is created with the function `tclistnew' and is deleted with the function `tclistdel'

    objects whose type is pointer to `TCMAP' are used for hash map. a map object is created with the function `tcmapnew' and is deleted with the function `tcmapdel'

    objects whose type is pointer to `TCTREE' are used for ordered tree. a tree object is created with the function `tctreenew' and is deleted with the function `tctreedel'

    TO AVOID MEMORY LEAK, IT IS IMPORTANT TO DELETE EVERY OBJECT WHEN IT IS NO LONGER IN USE


    String

    TCXSTR *tcxstrnew (void) ;
    to create an extensible string object. the return value is the new extensible string object

    TCXSTR *tcxstrnew2 (const char *str) ;
    to create an extensible string object from a character string. `str' specifies the string of the initial content. the return value is the new extensible string object containing the specified string

    void tcxstrdel (TCXSTR *xstr) ;
    to delete an extensible string object. xstr' specifies the extensible string object

    void tcxstrclear (TCXSTR *xstr) ;
    to clear an extensible string object. `xstr' specifies the extensible string object. the internal buffer of the object is cleared and the size is set zero

    void tcxstrcat2 (TCXSTR *xstr, const char *str) ;
    to concatenate a character string to the end of an extensible string object. xstr' specifies the extensible string object. `str' specifies the string to be appended

    void tcxstrprintf (TCXSTR *xstr, const char *format, ...) ;
    to perform formatted output into an extensible string object. xstr' specifies the extensible string object. `format' specifies the printf-like format string. the other arguments are used according to the format string

    #include <tcutil.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main (int argc, char **argv)
    {
        TCXSTR *xstr;
    
        xstr = tcxstrnew () ;
    
        tcxstrcat2 (xstr, "hop") ;
        tcxstrcat2 (xstr, "step") ;
        tcxstrcat2 (xstr, "jump") ;
    
        printf ("%d:%s\n", tcxstrsize (xstr), (char *)tcxstrptr (xstr)) ;
     
        tcxstrdel (xstr) ;
    
        return 0;
    }
    

    List

    TCLIST *tclistnew (void) ;
    to create a list object. the return value is the new list object

    void tclistclear (TCLIST *list) ;
    to clear a list object. list' specifies the list object

    TCLIST *tclistnew2 (int anum) ;
    to create a list object with expecting the number of elements. anum' specifies the number of elements expected to be stored in the list. the return value is the new list object

    TCLIST *tclistnew3 (const char *str, ...) ;
    to create a list object with initial string elements. str' specifies the string of the first element. the other arguments are other elements. they should be trailed by a `NULL' argument. the return value is the new list object

    void tclistdel (TCLIST *list) ;
    to delete a list object. list' specifies the list object

    int tclistnum (const TCLIST *list) ;
    to get the number of elements of a list object

    const char *tclistval2 (const TCLIST *list, int index) ;
    to get the string of an element of a list object. list' specifies the list object. `index' specifies the index of the element. The return value is the string of the value. if `index' is equal to or more than the number of elements, the return value is `NULL'

    void tclistpush2 (TCLIST *list, const char *str) ;
    to add a string element at the end of a list object. list' specifies the list object. `str' specifies the string of the new element

    char *tclistpop2 (TCLIST *list) ;
    to remove a string element of the end of a list object. list' specifies the list object. The return value is the string of the removed element. Because the region of the return value is allocated with the `malloc' call, it should be released with the `free' call when it is no longer in use. if the list is empty, the return value is `NULL'

    void tclistunshift2 (TCLIST *list, const char *str) ;
    to add a string element at the top of a list object. list' specifies the list object. `str' specifies the string of the new element

    char *tclistshift2 (TCLIST *list) ;
    to remove a string element of the top of a list object. list' specifies the list object. The return value is the string of the removed element. Because the region of the return value is allocated with the `malloc' call, it should be released with the `free' call when it is no longer in use. if the list is empty, the return value is `NULL'

    void tclistinsert2 (TCLIST *list, int index, const char *str) ;
    to add a string element at the specified location of a list object. list' specifies the list object. `index' specifies the index of the new element. `str' specifies the string of the new element. if `index' is equal to or more than the number of elements, this function has no effect

    char *tclistremove2 (TCLIST *list, int index) ;
    to remove a string element at the specified location of a list object. list' specifies the list object. `index' specifies the index of the element to be removed. The return value is the string of the removed element. Because the region of the return value is allocated with the `malloc' call, it should be released with the `free' call when it is no longer in use. if `index' is equal to or more than the number of elements, no element is removed and the return value is `NULL'

    void tclistover2 (TCLIST *list, int index, const char *str) ;
    to overwrite a string element at the specified location of a list object. list' specifies the list object. `index' specifies the index of the element to be overwritten. `str' specifies the string of the new content. if `index' is equal to or more than the number of elements, this function has no effect

    void tclistsort (TCLIST *list) ;
    to sort elements of a list object in lexical order. list' specifies the list object

    int tclistlsearch (const TCLIST *list, const void *ptr, int size) ;
    to search a list object for an element using liner search. list' specifies the list object. `ptr' specifies the pointer to the region of the key. `size' specifies the size of the region. The return value is the index of a corresponding element or -1 if there is no corresponding element. if two or more elements correspond, the former returns

    int tclistbsearch (const TCLIST *list, const void *ptr, int size) ;
    to search a list object for an element using binary search. list' specifies the list object. It should be sorted in lexical order. `ptr' specifies the pointer to the region of the key. `size' specifies the size of the region. The return value is the index of a corresponding element or -1 if there is no corresponding element. if two or more elements correspond, which returns is not defined

    #include <tcutil.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main (int argc, char **argv)
    {
        TCLIST *list;
        int i;
    
        list = tclistnew () ;
    
        tclistpush2 (list, "hop") ;
        tclistpush2 (list, "step") ;
        tclistpush2 (list, "jump") ;
    
        for (i = 0; i < tclistnum (list) ; i++){
          printf ("%d:%s\n", i, tclistval2 (list, i)) ;
        }
     
        tclistdel (list) ;
    
        return 0;
    }
    

    Map

    TCMAP *tcmapnew (void) ;
    to create a map object. the return value is the new map object

    TCMAP *tcmapnew2 (uint32_t bnum) ;
    to create a map object with specifying the number of the buckets. bnum' specifies the number of the buckets. The return value is the new map object

    TCMAP *tcmapnew3 (const char *str, ...) ;
    to create a map object with initial string elements. str' specifies the string of the first element. The other arguments are other elements. They should be trailed by a `NULL' argument. The return value is the new map object. The key and the value of each record are situated one after the other

    void tcmapdel (TCMAP *map) ;
    to delete a map object. map' specifies the map object. Note that the deleted object and its derivatives can not be used anymore

    void tcmapclear (TCMAP *map) ;
    to clear a map object. map' specifies the map object. All records are removed

    void tcmapput2 (TCMAP *map, const char *kstr, const char *vstr) ;
    to store a string record into a map object. map' specifies the map object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if a record with the same key exists in the map, it is overwritten

    bool tcmapputkeep2 (TCMAP *map, const char *kstr, const char *vstr) ;
    to store a new string record into a map object. map' specifies the map object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the map, this function has no effect

    void tcmapputcat2 (TCMAP *map, const char *kstr, const char *vstr) ;
    to concatenate a string value at the end of the value of the existing record in a map object. map' specifies the map object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if there is no corresponding record, a new record is created

    bool tcmapout2 (TCMAP *map, const char *kstr) ;
    to remove a string record of a map object. map' specifies the map object. `kstr' specifies the string of the key. if successful, the return value is true. False is returned when no record corresponds to the specified key

    const char *tcmapget2 (const TCMAP *map, const char *kstr) ;
    to retrieve a string record in a map object. map' specifies the map object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned when no record corresponds

    void tcmapiterinit (TCMAP *map) ;
    to initialize the iterator of a map object. map' specifies the map object. The iterator - to access the key of every record stored in the map object

    const char *tcmapiternext2 (TCMAP *map) ;
    to get the next key string of the iterator of a map object. map' specifies the map object. if successful, the return value is the pointer to the region of the next key, else, it is `NULL'. `NULL' is returned when no record can be fetched from the iterator. The order of iteration is assured to be the same as the stored order

    uint64_t tcmaprnum (const TCMAP *map) ;
    to get the number of records stored in a map object. map' specifies the map object. The return value is the number of the records stored in the map object

    TCLIST *tcmapkeys (const TCMAP *map) ;
    to create a list object containing all keys in a map object. map' specifies the map object. The return value is the new list object containing all keys in the map object. Because the object of the return value is created with the function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer in use

    TCLIST *tcmapvals (const TCMAP *map) ;
    to create a list object containing all values in a map object. map' specifies the map object. The return value is the new list object containing all values in the map object. Because the object of the return value is created with the function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer in use

    int tcmapaddint (TCMAP *map, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in a map object. map' specifies the map object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. The return value is the summation value. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tcmapadddouble (TCMAP *map, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in a map object. map' specifies the map object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. The return value is the summation value. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    #include <tcutil.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main (int argc, char **argv)
    {
        TCMAP *map;
        const char *key;
    
        map = tcmapnew () ;
        
        tcmapput2 (map, "foo", "hop") ;
        tcmapput2 (map, "bar", "step") ;
        tcmapput2 (map, "baz", "jump") ;
        
        tcmapiterinit (map) ;
    
        while ( (key = tcmapiternext2 (map)) != NULL){
          printf ("%s:%s\n", key, tcmapget2 (map, key)) ;
        }
        
        tcmapdel (map) ;
    
        return 0;
    }
    

    Tree

    TCTREE *tctreenew (void) ;
    to create a tree object. the return value is the new tree object

    TCTREE *tctreenew2 (TCCMP cmp, void *cmpop) ;
    to create a tree object with specifying the custom comparison function. cmp' specifies the pointer to the custom comparison function. It receives five parameters. The first parameter is the pointer to the region of one key. The second parameter is the size of the region of one key. The third parameter is the pointer to the region of the other key. The fourth parameter is the size of the region of the other key. The fifth parameter is the pointer to the optional opaque object. It returns positive if the former is big, negative if the latter is big, 0 if both are equivalent. `cmpop' specifies an arbitrary pointer to be given as a parameter of the comparison function. if it is not needed, `NULL' can be specified. The return value is the new tree object. The default comparison function compares keys of two records by lexical order. The functions `tccmplexical' (dafault), `tccmpdecimal', `tccmpint32', and `tccmpint64' are built-in

    void tctreeclear (TCTREE *tree) ;
    to clear a tree object. tree' specifies the tree object. All records are removed

    void tctreeput2 (TCTREE *tree, const char *kstr, const char *vstr) ;
    to store a string record into a tree object. tree' specifies the tree object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if a record with the same key exists in the tree, it is overwritten

    bool tctreeout2 (TCTREE *tree, const char *kstr) ;
    to remove a string record of a tree object. tree' specifies the tree object. `kstr' specifies the string of the key. if successful, the return value is true. False is returned when no record corresponds to the specified key

    const char *tctreeget2 (TCTREE *tree, const char *kstr) ;
    to retrieve a string record in a tree object. tree' specifies the tree object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned when no record corresponds

    void tctreeiterinit (TCTREE *tree) ;
    to initialize the iterator of a tree object. tree' specifies the tree object. The iterator - to access the key of every record stored in the tree object

    const char *tctreeiternext2 (TCTREE *tree) ;
    to get the next key string of the iterator of a tree object. tree' specifies the tree object. if successful, the return value is the pointer to the region of the next key, else, it is `NULL'. `NULL' is returned when no record can be fetched from the iterator. The order of iteration is assured to be ascending of the keys

    uint64_t tctreernum (const TCTREE *tree) ;
    to get the number of records stored in a tree object. tree' specifies the tree object. The return value is the number of the records stored in the tree object

    TCLIST *tctreekeys (const TCTREE *tree) ;
    to create a list object containing all keys in a tree object. tree' specifies the tree object. The return value is the new list object containing all keys in the tree object. Because the object of the return value is created with the function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer in use

    TCLIST *tctreevals (const TCTREE *tree) ;
    to create a list object containing all values in a tree object. tree' specifies the tree object. The return value is the new list object containing all values in the tree object. Because the object of the return value is created with the function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer in use

    int tctreeaddint (TCTREE *tree, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in a tree object. tree' specifies the tree object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. The return value is the summation value. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tctreeadddouble (TCTREE *tree, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in a tree object. tree' specifies the tree object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. The return value is the summation value. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    #include <tcutil.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main (int argc, char **argv)
    {
        TCTREE *tree;
        const char *key;
    
        tree = tctreenew () ;
    
        tctreeput2 (tree, "foo", "hop") ;
        tctreeput2 (tree, "bar", "step") ;
        tctreeput2 (tree, "baz", "jump") ;
    
        tctreeiterinit (tree) ;
    
        while ( (key = tctreeiternext2 (tree)) != NULL){
          printf ("%s:%s\n", key, tctreeget2 (tree, key)) ;
        }
    
        tctreedel (tree) ;
    
        return 0;
    }
    

    memory Hash Database

    TCMDB *tcmdbnew (void) ;
    to create an on-memory hash database object. the return value is the new on-memory hash database object. the object can be shared by plural threads because of the internal mutex

    void tcmdbdel (TCMDB *mdb) ;
    to delete an on-memory hash database object

    void tcmdbput2 (TCMDB *mdb, const char *kstr, const char *vstr) ;
    to store a string record into an on-memory hash database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if a record with the same key exists in the database, it is overwritten

    bool tcmdbout2 (TCMDB *mdb, const char *kstr) ;
    to remove a string record of an on-memory hash database object. `kstr' specifies the string of the key. if successful, the return value is true. false is returned when no record corresponds to the specified key

    char *tcmdbget2 (TCMDB *mdb, const char *kstr) ;
    to retrieve a string record in an on-memory hash database object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned when no record corresponds. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    void tcmdbiterinit (TCMDB *mdb) ;
    to initialize the iterator of an on-memory hash database object

    char *tcmdbiternext2 (TCMDB *mdb) ;
    to get the next key string of the iterator of an on-memory hash database object. if successful, the return value is the pointer to the region of the next key, else, it is `NULL'. `NULL' is returned when no record can be fetched from the iterator. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    uint64_t tcmdbrnum (TCMDB *mdb) ;
    to get the number of records stored in an on-memory hash database object

    int tcmdbaddint (TCMDB *mdb, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in an on-memory hash database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. the return value is the summation value. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tcmdbadddouble (TCMDB *mdb, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in an on-memory hash database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. the return value is the summation value. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    void tcmdbvanish (TCMDB *mdb) ;
    to clear an on-memory hash database object

    memory Tree Database

    TCNDB *tcndbnew (void) ;
    to create an on-memory tree database object. he return value is the new on-memory tree database object. the object can be shared by plural threads because of the internal mutex

    TCNDB *tcndbnew2 (TCCMP cmp, void *cmpop) ;
    to create an on-memory tree database object with specifying the custom comparison function. cmp' specifies the pointer to the custom comparison function. `cmpop' specifies an arbitrary pointer to be given as a parameter of the comparison function. if it is not needed, `NULL' can be specified. the return value is the new on-memory tree database object. the default comparison function compares keys of two records by lexical order. the functions `tccmplexical' (default), `tccmpdecimal', `tccmpint32', and `tccmpint64' are built-in. the object can be shared by plural threads because of the internal mutex

    void tcndbdel (TCNDB *ndb) ;
    to delete an on-memory tree database object

    void tcndbput2 (TCNDB *ndb, const char *kstr, const char *vstr) ;
    to store a string record into an on-memory tree database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if a record with the same key exists in the database, it is overwritten

    bool tcndbputkeep2 (TCNDB *ndb, const char *kstr, const char *vstr) ;
    to store a new string record into an on-memory tree database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, this function has no effect

    void tcndbputcat2 (TCNDB *ndb, const char *kstr, const char *vstr) ;
    to concatenate a string at the end of the existing record in an on-memory tree database. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if there is no corresponding record, a new record is created

    bool tcndbout2 (TCNDB *ndb, const char *kstr) ;
    to remove a string record of an on-memory tree database object. `kstr' specifies the string of the key. if successful, the return value is true. false is returned when no record corresponds to the specified key

    char *tcndbget2 (TCNDB *ndb, const char *kstr) ;
    to retrieve a string record in an on-memory tree database object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned when no record corresponds. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    int tcndbvsiz2 (TCNDB *ndb, const char *kstr) ;
    to get the size of the value of a string record in an on-memory tree database object. `kstr' specifies the string of the key. if successful, the return value is the size of the value of the corresponding record, else, it is -1

    void tcndbiterinit (TCNDB *ndb) ;
    to initialize the iterator of an on-memory tree database object

    char *tcndbiternext2 (TCNDB *ndb) ;
    to get the next key string of the iterator of an on-memory tree database object. if successful, the return value is the pointer to the region of the next key, else, it is `NULL'. `NULL' is returned when no record can be fetched from the iterator. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    TCLIST *tcndbfwmkeys2 (TCNDB *ndb, const char *pstr, int max) ;
    to get forward matching string keys in an on-memory tree database object. `pstr' specifies the string of the prefix. `max' specifies the maximum number of keys to be fetched. if it is negative, no limit is specified. the return value is a list object of the corresponding keys. this function does never fail. it returns an empty list even if no key corresponds. BECAUSE THE OBJECT OF THE RETURN VALUE IS CREATED WITH THE FUNCTION `TCLISTNEW', IT SHOULD BE DELETED WITH THE FUNCTION `TCLISTDEL' WHEN IT IS NO LONGER IN USE

    uint64_t tcndbrnum (TCNDB *ndb) ;
    to get the number of records stored in an on-memory tree database object. the return value is the number of the records stored in the database

    int tcndbaddint (TCNDB *ndb, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in an on-memory tree database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. the return value is the summation value. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tcndbadddouble (TCNDB *ndb, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in an on-memory tree database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. the return value is the summation value. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    The Hash Database API


    #include <tchdb.h>  
    

    objects whose type is pointer to `TCHDB' are used to handle hash databases

    a hash database object is created with the function `tchdbnew' and is deleted with the function `tchdbdel'. TO AVOID MEMORY LEAK, IT IS IMPORTANT TO DELETE EVERY OBJECT WHEN IT IS NO LONGER IN USE

    before operations to store or retrieve records, it is necessary to open a database file and connect the hash database object to it. the function `tchdbopen' is used to open a database file and the function `tchdbclose' is used to close the database file. TO AVOID DATA MISSING OR CORRUPTION, IT IS IMPORTANT TO CLOSE EVERY DATABASE FILE WHEN IT IS NO LONGER IN USE

    it is forbidden for multible database objects in a process to open the same database at the same time

    TCHDB *tchdbnew (void) ;
    to create a hash database object

    void tchdbdel (TCHDB *hdb) ;
    to delete a hash database object

    const char *tchdberrmsg (int ecode) ;
    to get the message string corresponding to an error code

    int tchdbecode (TCHDB *hdb) ;
    to get the last happened error code of a hash database object. hdb' specifies the hash database object. the following error codes are defined:
  • `TCESUCCESS' for success,
  • `TCETHREAD' for threading error,
  • `TCEINVALID' for invalid operation,
  • `TCENOFILE' for file not found,
  • `TCENOPERM' for no permission,
  • `TCEMETA' for invalid meta data,
  • `TCERHEAD' for invalid record header,
  • `TCEOPEN' for open error,
  • `TCECLOSE' for close error,
  • `TCETRUNC' for trunc error,
  • `TCESYNC' for sync error,
  • `TCESTAT' for stat error,
  • `TCESEEK' for seek error,
  • `TCEREAD' for read error,
  • `TCEWRITE' for write error,
  • `TCEMMAP' for mmap error,
  • `TCELOCK' for lock error,
  • `TCEUNLINK' for unlink error,
  • `TCERENAME' for rename error,
  • `TCEMKDIR' for mkdir error,
  • `TCERMDIR' for rmdir error,
  • `TCEKEEP' for existing record,
  • `TCENOREC' for no record found,
  • `TCEMISC' for miscellaneous error
  • bool tchdbsetmutex (TCHDB *hdb) ;
    to set mutual exclusion control of a hash database object for threading. if successful, the return value is true, else, it is false. note that the mutual exclusion control of the database should be set before the database is opened

    bool tchdbopen (TCHDB *hdb, const char *path, int omode) ;
    `path' specifies the path of the database file. `omode' specifies the connection mode:
  • `HDBOWRITER' as a writer
  • `HDBOREADER' as a reader

  • if the mode is `HDBOWRITER', the following may be added by bitwise-or:
  • `HDBOCREAT' creates a new database if not exist
  • `HDBOTRUNC' creates a new database regardless if one exists
  • `HDBOTSYNC', every transaction synchronizes updated contents with the device
  • both of `HDBOREADER' and `HDBOWRITER' can be added to by bitwise-or:
  • `HDBONOLCK' opens the database file without file locking
  • `HDBOLCKNB', locking is performed without blocking
  • if successful, the return value is true, else, it is false

    bool tchdbclose (TCHDB *hdb) ;
    if successful, the return value is true, else, it is false. IF A WRITER OPENS A DATABASE BUT DOES NOT CLOSE IT APPROPRIATELY, THE DATABASE WILL BE BROKEN

    bool tchdbput2 (TCHDB *hdb, const char *kstr, const char *vstr) ;
    to store a string record into a hash database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, it is overwritten

    bool tchdbputkeep2 (TCHDB *hdb, const char *kstr, const char *vstr) ;
    `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, this function has no effect

    bool tchdbputcat2 (TCHDB *hdb, const char *kstr, const char *vstr) ;
    to concatenate a string value at the end of the existing record in a hash database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if there is no corresponding record, a new record is created

    bool tchdbputasync2 (TCHDB *hdb, const char *kstr, const char *vstr) ;
    to store a string record into a hash database object in asynchronous fashion. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, it is overwritten. records passed to this function are accumulated into the inner buffer and wrote into the file at a blast

    bool tchdbout2 (TCHDB *hdb, const char *kstr) ;
    to remove a string record of a hash database object. `kstr' specifies the string of the key. if successful, the return value is true, else, it is false

    char *tchdbget2 (TCHDB *hdb, const char *kstr) ;
    to retrieve a string record in a hash database object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned if no record corresponds. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    int tchdbvsiz2 (TCHDB *hdb, const char *kstr) ;
    to get the size of the value of a string record in a hash database object. `kstr' specifies the string of the key. if successful, the return value is the size of the value of the corresponding record, else, it is -1

    bool tchdbiterinit (TCHDB *hdb) ;
    to initialize the iterator of a hash database object. if successful, the return value is true, else, it is false. THE ITERATOR - TO ACCESS THE KEY OF EVERY RECORD STORED IN A DATABASE

    char *tchdbiternext2 (TCHDB *hdb) ;
    to get the next key string of the iterator of a hash database object. if successful, the return value is the string of the next key, else, it is `NULL'. `NULL' is returned when no record is to be get out of the iterator. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    TCLIST *tchdbfwmkeys2 (TCHDB *hdb, const char *pstr, int max) ;
    to get forward matching string keys in a hash database object. `pstr' specifies the string of the prefix. `max' specifies the maximum number of keys to be fetched. if it is negative, no limit is specified. the return value is a list object of the corresponding keys. this function does never fail. it returns an empty list even if no key corresponds. BECAUSE THE OBJECT OF THE RETURN VALUE IS CREATED WITH THE FUNCTION `TCLISTNEW', IT SHOULD BE DELETED WITH THE FUNCTION `TCLISTDEL' WHEN IT IS NO LONGER IN USE

    int tchdbaddint (TCHDB *hdb, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in a hash database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. if successful, the return value is the summation value, else, it is `INT_MIN'. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tchdbadddouble (TCHDB *hdb, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in a hash database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. if successful, the return value is the summation value, else, it is NaN. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    bool tchdbtranbegin (TCHDB *hdb) ;
    to begin the transaction of a hash database object. if successful, the return value is true, else, it is false. the database is locked by the thread while the transaction so that only one transaction can be activated with a database object at the same time. thus, the serializable isolation level is assumed if every database operation is performed in the transaction. all updated regions are kept track of by write ahead logging while the transaction. if the database is closed during transaction, the transaction is aborted implicitly

    bool tchdbtrancommit (TCHDB *hdb) ;
    to commit the transaction of a hash database object. if successful, the return value is true, else, it is false. update in the transaction is fixed when it is committed successfully

    bool tchdbtranabort (TCHDB *hdb) ;
    to abort the transaction of a hash database object. if successful, the return value is true, else, it is false. update in the transaction is discarded when it is aborted. the state of the database is rollbacked to before transaction

    uint64_t tchdbrnum (TCHDB *hdb) ;
    to get the number of records of a hash database object. the return value is the number of records or 0 if the object does not connect to any database file
    #include <tchdb.h>
    #include <stdlib.h>
    
    int 
    main (int argc, char **argv)
    {
      TCHDB *hdb;
      int ecode;
      char *key, *value;
    
      hdb = tchdbnew () ;
    
      if (!tchdbopen (hdb, "casket.tch", HDBOWRITER | HDBOCREAT)){
        ecode = tchdbecode (hdb) ;
        fprintf (stderr, "open error: %s\n", tchdberrmsg (ecode)) ;
      }
    
      if (!tchdbput2 (hdb, "foo", "hop") ||
         !tchdbput2 (hdb, "bar", "step") ||
         !tchdbput2 (hdb, "baz", "jump")){
        ecode = tchdbecode (hdb) ;
        fprintf (stderr, "put error: %s\n", tchdberrmsg (ecode)) ;
      }
    
      value = tchdbget2 (hdb, "foo") ;
      if (value)
      {
        printf ("%s\n", value) ;
        free (value) ;
      } 
      else 
      {
        ecode = tchdbecode (hdb) ;
        fprintf (stderr, "get error: %s\n", tchdberrmsg (ecode)) ;
      }
    
      tchdbiterinit (hdb) ;
      while ( (key = tchdbiternext2 (hdb)) != NULL )
      {
        value = tchdbget2 (hdb, key) ;
        if (value)
        {
          printf ("%s:%s\n", key, value) ;
          free (value) ;
        }
        free (key) ;
      }
    
      if (!tchdbclose (hdb))
      {
        ecode = tchdbecode (hdb) ;
        fprintf (stderr, "close error: %s\n", tchdberrmsg (ecode)) ;
      }
    
      tchdbdel (hdb) ;
    
      return 0;
    }
    

    The B+ Tree Database API


    #include <tcbdb.h>
    

    objects whose type is pointer to `TCBDB' are used to handle B+ tree databases. a B+ tree database object is created with the function `tcbdbnew' and is deleted with the function `tcbdbdel'. TO AVOID MEMORY LEAK, IT IS IMPORTANT TO DELETE EVERY OBJECT WHEN IT IS NO LONGER IN USE

    before operations to store or retrieve records, it is necessary to open a database file and connect the B+ tree database object to it. the function `tcbdbopen' is used to open a database file and the function `tcbdbclose' is used to close the database file. TO AVOID DATA MISSING OR CORRUPTION, IT IS IMPORTANT TO CLOSE EVERY DATABASE FILE WHEN IT IS NO LONGER IN USE

    it is forbidden for multible database objects in a process to open the same database at the same time

    TCBDB *tcbdbnew (void) ;
    to create a B+ tree database object. he return value is the new B+ tree database object

    void tcbdbdel (TCBDB *bdb) ;
    to delete a B+ tree database object

    const char *tcbdberrmsg (int ecode) ;
    to get the message string corresponding to an error code. ecode' specifies the error code. the return value is the message string of the error code

    int tcbdbecode (TCBDB *bdb) ;
    to get the last happened error code of a B+ tree database object. the return value is the last happened error code. the following error codes are defined:
  • `TCESUCCESS' for success
  • `TCETHREAD' for threading error
  • `TCEINVALID' for invalid operation
  • `TCENOFILE' for file not found
  • `TCENOPERM' for no permission
  • `TCEMETA' for invalid meta data
  • `TCERHEAD' for invalid record header
  • `TCEOPEN' for open error
  • `TCECLOSE' for close error
  • `TCETRUNC' for trunc error
  • `TCESYNC' for sync error
  • `TCESTAT' for stat error
  • `TCESEEK' for seek error
  • `TCEREAD' for read error
  • `TCEWRITE' for write error
  • `TCEMMAP' for mmap error
  • `TCELOCK' for lock error
  • `TCEUNLINK' for unlink error
  • `TCERENAME' for rename error
  • `TCEMKDIR' for mkdir error
  • `TCERMDIR' for rmdir error
  • `TCEKEEP' for existing record
  • `TCENOREC' for no record found
  • and
  • `TCEMISC' for miscellaneous error
  • bool tcbdbsetmutex (TCBDB *bdb) ;
    to set mutual exclusion control of a B+ tree database object for threading. bdb' specifies the B+ tree database object which is not opened. if successful, the return value is true, else, it is false. note that the mutual exclusion control of the database should be set before the database is opened

    bool tcbdbsetcmpfunc (TCBDB *bdb, TCCMP cmp, void *cmpop) ;
    to set the custom comparison function of a B+ tree database object. bdb' specifies the B+ tree database object which is not opened. `cmp' specifies the pointer to the custom comparison function. it receives five parameters:
    the first parameter is the pointer to the region of one key
    the second parameter is the size of the region of one key
    the third parameter is the pointer to the region of the other key
    the fourth parameter is the size of the region of the other key
    the fifth parameter is the pointer to the optional opaque object
    it returns positive if the former is big, negative if the latter is big, 0 if both are equivalent
    `cmpop' specifies an arbitrary pointer to be given as a parameter of the comparison function. if it is not needed, `NULL' can be specified
    if successful, the return value is true, else, it is false
    the default comparison function compares keys of two records by lexical order. the functions `tccmplexical' (default), `tccmpdecimal', `tccmpint32', and `tccmpint64' are built-in. note that the comparison function should be set before the database is opened. moreover, user-defined comparison functions should be set every time the database is being opened

    bool tcbdbopen (TCBDB *bdb, const char *path, int omode) ;
    to open a database file and connect a B+ tree database object. bdb' specifies the B+ tree database object which is not opened. `path' specifies the path of the database file. `omode' specifies the connection mode: `BDBOWRITER' as a writer, `BDBOREADER' as a reader. if the mode is `BDBOWRITER', the following may be added by bitwise-or: `BDBOCREAT', which means it creates a new database if not exist, `BDBOTRUNC', which means it creates a new database regardless if one exists, `BDBOTSYNC', which means every transaction synchronizes updated contents with the device. Both of `BDBOREADER' and `BDBOWRITER' can be added to by bitwise-or: `BDBONOLCK', which means it opens the database file without file locking, or `BDBOLCKNB', which means locking is performed without blocking. if successful, the return value is true, else, it is false

    bool tcbdbclose (TCBDB *bdb) ;
    to close a B+ tree database object. if successful, the return value is true, else, it is false. Update of a database is assured to be written when the database is closed. if a writer opens a database but does not close it appropriately, the database will be broken

    bool tcbdbput2 (TCBDB *bdb, const char *kstr, const char *vstr) ;
    to store a string record into a B+ tree database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, it is overwritten

    bool tcbdbputkeep2 (TCBDB *bdb, const char *kstr, const char *vstr) ;
    to store a new string record into a B+ tree database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if a record with the same key exists in the database, this function has no effect

    bool tcbdbputcat2 (TCBDB *bdb, const char *kstr, const char *vstr) ;
    to concatenate a string value at the end of the existing record in a B+ tree database object. `kstr' specifies the string of the key. `vstr' specifies the string of the value. if successful, the return value is true, else, it is false. if there is no corresponding record, a new record is created

    bool tcbdbout2 (TCBDB *bdb, const char *kstr) ;
    to remove a string record of a B+ tree database object. `kstr' specifies the string of the key. if successful, the return value is true, else, it is false. if the key of duplicated records is specified, the first one is selected

    char *tcbdbget2 (TCBDB *bdb, const char *kstr) ;
    to retrieve a string record in a B+ tree database object. `kstr' specifies the string of the key. if successful, the return value is the string of the value of the corresponding record. `NULL' is returned if no record corresponds. if the key of duplicated records is specified, the first one is selected. Because the region of the return value is allocated with the `malloc' call, it should be released with the `free' call when it is no longer in use

    int tcbdbvnum2 (TCBDB *bdb, const char *kstr) ;
    to get the number of records corresponding a string key in a B+ tree database object. `kstr' specifies the string of the key. if successful, the return value is the number of the corresponding records, else, it is 0

    TCLIST *tcbdbrange2 (TCBDB *bdb, const char *bkstr, bool binc, const char *ekstr, bool einc, int max) ;
    to get string keys of ranged records in a B+ tree database object. `bkstr' specifies the string of the key of the beginning border. if it is `NULL', the first record is specified. `binc' specifies whether the beginning border is inclusive or not. `ekstr' specifies the string of the key of the ending border. if it is `NULL', the last record is specified. `einc' specifies whether the ending border is inclusive or not. `max' specifies the maximum number of keys to be fetched. if it is negative, no limit is specified. the return value is a list object of the keys of the corresponding records. this function does never fail. it returns an empty list even if no record corresponds. BECAUSE THE OBJECT OF THE RETURN VALUE IS CREATED WITH THE FUNCTION `TCLISTNEW', IT SHOULD BE DELETED WITH THE FUNCTION `TCLISTDEL' WHEN IT IS NO LONGER IN USE

    TCLIST *tcbdbfwmkeys2 (TCBDB *bdb, const char *pstr, int max) ;
    to get forward matching string keys in a B+ tree database object. `pstr' specifies the string of the prefix. `max' specifies the maximum number of keys to be fetched. if it is negative, no limit is specified. the return value is a list object of the corresponding keys. this function does never fail. it returns an empty list even if no key corresponds. BECAUSE THE OBJECT OF THE RETURN VALUE IS CREATED WITH THE FUNCTION `TCLISTNEW', IT SHOULD BE DELETED WITH THE FUNCTION `TCLISTDEL' WHEN IT IS NO LONGER IN USE

    int tcbdbaddint (TCBDB *bdb, const void *kbuf, int ksiz, int num) ;
    to add an integer to a record in a B+ tree database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. if successful, the return value is the summation value, else, it is `INT_MIN'. if the corresponding record exists, the value is treated as an integer and is added to. if no record corresponds, a new record of the additional value is stored

    double tcbdbadddouble (TCBDB *bdb, const void *kbuf, int ksiz, double num) ;
    to add a real number to a record in a B+ tree database object. `kbuf' specifies the pointer to the region of the key. `ksiz' specifies the size of the region of the key. `num' specifies the additional value. if successful, the return value is the summation value, else, it is Not-a-Number. if the corresponding record exists, the value is treated as a real number and is added to. if no record corresponds, a new record of the additional value is stored

    bool tcbdbtranbegin (TCBDB *bdb) ;
    to begin the transaction of a B+ tree database object. if successful, the return value is true, else, it is false. the database is locked by the thread while the transaction so that only one transaction can be activated with a database object at the same time. thus, the serializable isolation level is assumed if every database operation is performed in the transaction. because all pages are cached on memory while the transaction, the amount of referred records is limited by the memory capacity. if the database is closed during transaction, the transaction is aborted implicitly

    bool tcbdbtrancommit (TCBDB *bdb) ;
    to commit the transaction of a B+ tree database object. if successful, the return value is true, else, it is false. Update in the transaction is fixed when it is committed successfully

    bool tcbdbtranabort (TCBDB *bdb) ;
    to abort the transaction of a B+ tree database object. if successful, the return value is true, else, it is false. Update in the transaction is discarded when it is aborted. the state of the database is rollbacked to before transaction

    uint64_t tcbdbrnum (TCBDB *bdb) ;
    to get the number of records of a B+ tree database object. the return value is the number of records or 0 if the object does not connect to any database file

    BDBCUR *tcbdbcurnew (TCBDB *bdb) ;
    to create a cursor object. the return value is the new cursor object. note that the cursor is available only after initialization with the `tcbdbcurfirst' or the `tcbdbcurjump' functions and so on. Moreover, the position of the cursor will be indefinite when the database is updated after the initialization of the cursor

    void tcbdbcurdel (BDBCUR *cur) ;
    to delete a cursor object. cur' specifies the cursor object

    bool tcbdbcurfirst (BDBCUR *cur) ;
    to move a cursor object to the first record. cur' specifies the cursor object. if successful, the return value is true, else, it is false. false is returned if there is no record in the database

    bool tcbdbcurlast (BDBCUR *cur) ;
    to move a cursor object to the last record. cur' specifies the cursor object. if successful, the return value is true, else, it is false. false is returned if there is no record in the database

    bool tcbdbcurjump2 (BDBCUR *cur, const char *kstr) ;
    to move a cursor object to the front of records corresponding a key string. cur' specifies the cursor object. `kstr' specifies the string of the key. if successful, the return value is true, else, it is false. false is returned if there is no record corresponding the condition. the cursor is set to the first record corresponding the key or the next substitute if completely matching record does not exist

    bool tcbdbcurprev (BDBCUR *cur) ;
    to move a cursor object to the previous record. cur' specifies the cursor object. if successful, the return value is true, else, it is false. false is returned if there is no previous record

    bool tcbdbcurnext (BDBCUR *cur) ;
    to move a cursor object to the next record. cur' specifies the cursor object. if successful, the return value is true, else, it is false. false is returned if there is no next record

    char *tcbdbcurkey2 (BDBCUR *cur) ;
    to get the key string of the record where the cursor object is. cur' specifies the cursor object. if successful, the return value is the string of the key, else, it is `NULL'. `NULL' is returned when the cursor is at invalid position. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    char *tcbdbcurval2 (BDBCUR *cur) ;
    to get the value string of the record where the cursor object is. cur' specifies the cursor object. if successful, the return value is the string of the value, else, it is `NULL'. `NULL' is returned when the cursor is at invalid position. BECAUSE THE REGION OF THE RETURN VALUE IS ALLOCATED WITH THE `MALLOC' CALL, IT SHOULD BE RELEASED WITH THE `FREE' CALL WHEN IT IS NO LONGER IN USE

    bool tcbdbcurrec (BDBCUR *cur, TCXSTR *kxstr, TCXSTR *vxstr) ;
    to get the key and the value of the record where the cursor object is. cur' specifies the cursor object. `kxstr' specifies the object into which the key is wrote down. `vxstr' specifies the object into which the value is wrote down. if successful, the return value is true, else, it is false. false is returned when the cursor is at invalid position
    #include <tcbdb.h>
    #include <stdlib.h>
    
    int main (int argc, char **argv)
    {
      TCBDB *bdb;
      BDBCUR *cur;
      int ecode;
      char *key, *value;
    
      bdb = tcbdbnew () ;
    
      if (!tcbdbopen (bdb, "casket.tcb", BDBOWRITER | BDBOCREAT)){
        ecode = tcbdbecode (bdb) ;
        fprintf (stderr, "open error: %s\n", tcbdberrmsg (ecode)) ;
      }
    
      if (!tcbdbput2 (bdb, "foo", "hop") ||
         !tcbdbput2 (bdb, "bar", "step") ||
         !tcbdbput2 (bdb, "baz", "jump")){
        ecode = tcbdbecode (bdb) ;
        fprintf (stderr, "put error: %s\n", tcbdberrmsg (ecode)) ;
      }
    
      value = tcbdbget2 (bdb, "foo") ;
      if (value){
        printf ("%s\n", value) ;
        free (value) ;
      } else {
        ecode = tcbdbecode (bdb) ;
        fprintf (stderr, "get error: %s\n", tcbdberrmsg (ecode)) ;
      }
    
      /* traverse records */
      cur = tcbdbcurnew (bdb) ;
      tcbdbcurfirst (cur) ;
      while ( (key = tcbdbcurkey2 (cur)) != NULL){
        value = tcbdbcurval2 (cur) ;
        if (value){
          printf ("%s:%s\n", key, value) ;
          free (value) ;
        }
        free (key) ;
        tcbdbcurnext (cur) ;
      }
      tcbdbcurdel (cur) ;
    
      if (!tcbdbclose (bdb)){
        ecode = tcbdbecode (bdb) ;
        fprintf (stderr, "close error: %s\n", tcbdberrmsg (ecode)) ;
      }
    
      tcbdbdel (bdb) ;
    
      return 0;
    }