LevelDB

Language: C

Database / Storage

LevelDB was developed by Google to offer a high-performance key-value store optimized for SSDs and large datasets. It is widely used in applications requiring efficient storage and retrieval of key-value pairs, such as databases, caches, and embedded systems.

LevelDB is a fast, lightweight, single-purpose key-value storage library written in C++. It provides ordered mapping from string keys to string values with support for batch writes, snapshots, and iterators.

Installation

linux: sudo apt install libleveldb-dev
mac: brew install leveldb
windows: Build from source: https://github.com/google/leveldb

Usage

LevelDB allows storing arbitrary byte arrays as keys and values, iterating over keys in sorted order, performing batch writes, and creating snapshots of the database state.

Opening a database and writing a key-value pair

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::Status status = leveldb::DB::Open(options, "testdb", &db);
    if (!status.ok()) std::cerr << status.ToString() << std::endl;

    status = db->Put(leveldb::WriteOptions(), "key1", "value1");
    if (!status.ok()) std::cerr << status.ToString() << std::endl;

    delete db;
    return 0;
}

Opens (or creates) a LevelDB database, writes a key-value pair, and closes the database.

Reading a value from the database

#include <leveldb/db.h>
#include <iostream>

int main() {
    leveldb::DB* db;
    leveldb::Options options;
    options.create_if_missing = false;
    leveldb::DB::Open(options, "testdb", &db);

    std::string value;
    leveldb::Status status = db->Get(leveldb::ReadOptions(), "key1", &value);
    if (status.ok()) std::cout << "Value: " << value << std::endl;
    else std::cerr << status.ToString() << std::endl;

    delete db;
    return 0;
}

Reads the value associated with a key from the database and prints it.

Batch writes

#include <leveldb/db.h>
#include <leveldb/write_batch.h>

leveldb::DB* db; // assume opened
leveldb::WriteBatch batch;
batch.Put("key2", "value2");
batch.Delete("key1");
db->Write(leveldb::WriteOptions(), &batch);

Performs multiple writes/deletes atomically using a WriteBatch.

Iterating over keys

#include <leveldb/db.h>
#include <iostream>

leveldb::DB* db; // assume opened
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {
    std::cout << it->key().ToString() << " => " << it->value().ToString() << std::endl;
}
delete it;

Iterates through all key-value pairs in sorted order.

Using snapshots

// leveldb::Snapshot* snapshot = db->GetSnapshot(); // read consistent view
// db->ReleaseSnapshot(snapshot);

Allows reading a consistent snapshot of the database while writes may continue.

Error Handling

leveldb::Status::IOError: Indicates a file system or permission error. Check database path and permissions.
leveldb::Status::NotFound: Key does not exist in the database. Handle missing keys gracefully.
leveldb::Status::Corruption: Database corruption detected. Consider backup and restore or repair procedures.

Best Practices

Always check the return status of operations.

Use batch writes for better performance.

Close the database properly to ensure data integrity.

Use snapshots for consistent reads in concurrent scenarios.

Avoid storing very large values; LevelDB is optimized for many small key-value pairs.