January 23, 2021
Hot Topics:

Hamsterdb: a Small, Fast Database That Won't Weigh You Down

  • By Victor Volkman
  • Send Email »
  • More Articles »

Even more goodies are available through ham_new_ex(). These let you tune the cache size, page size, and B+tree index key size.

27    for (i=0; i<LOOP; i++) {    //demonstrate insert functions
28       key.size=sizeof(i);
29       key.data=&i;
30       record.size=sizeof(i);
31       record.data=&i;
32       st=ham_insert(db, 0, &key, &record, 0);
33       if (st!=HAM_SUCCESS)
34          error("ham_insert", st);
35    }

In the next section (lines 26-36), you simply insert about 10 records with the datavalues 1 thru 10. The ham_insert() used on line #32 is the standard method of getting data into the database. The second parameter is a transaction handle (or null if you don't care to use transactions). The next parameter is the primary key you will associate with the record data. If you open the database with the HAM_RECORD_NUMBER flag, the system will generate this for you. The fourth parameter is nothing but a pointer to the data you're going to insert (note the size was set on line #30). Last, a set of insertion flags that can be HAM_OVERWRITE to replace a record with a matching key or HAM_DUPLICATE to force an additional record if the key already existed.

37    for (i=0; i<LOOP; i++) {    // retrieve the data
38       key.size=sizeof(i);
39       key.data=&i;
41       st=ham_find(db, 0, &key, &record, 0);
42       if (st!=HAM_SUCCESS)
43          error("ham_find", st);
45       if (*(int *)record.data!=i) {
46          printf("ham_find() ok, but returned bad value\n");
47          return (-1);
48       }
49    }

The next thing you try is to query the database to find those records you just inserted. Because you're not using SQL, you are limited to matching exact records 1-for-1 based on keys. If youwanted to do some type of query and scan the database closely, you would have used the cursor functions (which are outside the scope of this limited introduction). The first two parameters to ham_find() are the database handle and transaction handle (or null). The function returns either HAM_SUCCESS or HAM_KEY_NOT_FOUND depending on how it went and fills up the record data if it worked.

51    st=ham_close(db, 0);
52    if (st!=HAM_SUCCESS)
53       error("ham_close", st);
54    st=ham_open(db, "test.db", 0);
55    if (st!=HAM_SUCCESS)
56       error("ham_open", st);
58    for (i=0; i<LOOP; i++) {    // delete the data
59       key.size=sizeof(i);
60       key.data=&i;
61       st=ham_erase(db, 0, &key, 0);
62       if (st!=HAM_SUCCESS)
63          error("ham_erase", st);
64    }

In lines 51-64, you're showing off that you can close and reopen the database and pick up right where you left off. The ham_erase() function works about like you think it would, being an implicit search-and-destroy in one step. It returns HAM_SUCCESS or HAM_KEY_NOT_FOUND.

66    for (i=0; i<LOOP; i++) {
67       key.size=sizeof(i);
68       key.data=&i;
70       st=ham_find(db, 0, &key, &record, 0);
71       if (st!=HAM_KEY_NOT_FOUND)
72          error("ham_find", st);
73    }
75    st=ham_close(db, 0);
76    if (st!=HAM_SUCCESS)
77       error("ham_close", st);
79    ham_delete(db);
80    printf("success!\n");
81    return (0);
82 }
84 void error(const char *foo, ham_status_t st)
85 {
86    printf("%s() returned error %d: %s\n", foo, st,
87    exit(-1);
88 }

In this last segment, lines #66-74, you try to find those records you just deleted. Normally, you wouldn't do things exactly this way, but it's just a demo so you're trying lots of variations on a theme. Finally, you close down the database file with ham_close() and delete the instance with ham_delete() on line #79.


Well, if hamsterdb isn't the simplest record-manager API I've seen in the past 30 years, I don't know what is. Certainly, it has the easiest learning curve of any B+tree system I've ever used. There are a ton of features that I didn't even get very near in this demo, including:

  • Cursors for navigating the data
  • Encryption support
  • Custom-comparison functions for sorting
  • Zlib-based compression of record data
  • Transaction and rollback

If you're developing a lean-and-mean application, hamsterdb may be the small and fast addition that you need for simple database needs.

About the Author

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for the Washtenaw Community College CIS department. Volkman is the editor of numerous books including, C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries; just send an email to sysop@HAL9K.com

Page 2 of 2

This article was originally published on July 14, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date