Skip to content

ddtdanilo/LMDB-wrapper-MISRA-C

Repository files navigation

LMDB Wrapper - MISRA C

CI License: MIT Release vcpkg Buy Me A Coffee

A MISRA C compliant wrapper for LMDB (Lightning Memory-Mapped Database).

Purpose

This library provides a safe, validated API layer over LMDB that enforces MISRA C coding standards. It serves as a base component for systems that require reliable key-value storage with strict error handling — such as blockchain-like block management architectures.

Features

  • Full MISRA C parameter validation on every function call
  • Specific error codes for null parameters, invalid parameters, and LMDB errors
  • All return values validated (no unchecked calls)
  • Read API copies values into caller-owned buffers
  • Simple API: create environment, put/get/delete records, close
  • Automatic LMDB download via CMake (no manual dependency setup)

API

Function Description
lmdbWrapperEnvCreate() Create and open a database environment
lmdbWrapperEnvClose() Close and destroy an environment
lmdbWrapperPut() Store a key-value record
lmdbWrapperGet() Copy a value by key into a caller buffer
lmdbWrapperDel() Delete a record by key
lmdbWrapperStrerror() Convert error code to string

Use Cases

LMDB is an ultra-fast embedded key-value database with memory-mapped I/O. This MISRA C wrapper adds the safety layer required for critical environments:

  • Blockchain & cryptocurrency — Monero uses LMDB for its entire blockchain storage. The zero-copy reads and lock-free concurrent readers make it ideal for distributed ledger systems.
  • Safety-critical embedded systems — Automotive (AUTOSAR), medical devices (IEC 62304), and industrial controllers (IEC 61508) that need persistent key-value storage with MISRA C guarantees.
  • IoT & firmware — Persistent configuration, structured logs, and state management on resource-constrained devices. LMDB's minimal footprint (~30KB) is well-suited for embedded targets.
  • Infrastructure & servers — OpenLDAP (LMDB's origin), Postfix mail maps, and session/cache storage in server applications.
  • AI/ML pipelines — Caffe and Caffe2 use LMDB to store image datasets for deep learning training, leveraging zero-copy reads for high throughput.
  • Desktop & mobile apps — Local key-value cache as a lightweight alternative to SQLite when relational queries are not needed.

Installation

vcpkg (recommended)

This library is available as an official vcpkg port:

vcpkg install ddtdanilo-lmdb-wrapper

Then in your CMakeLists.txt:

find_package(lmdb_wrapper CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE lmdb_wrapper::lmdb_wrapper)

Build from source

Prerequisites

  • C compiler (GCC or Clang)
  • CMake >= 3.14
  • Git (for LMDB download)

Build

cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build

Run Tests

cd build && ctest --output-on-failure

Or run the test executable directly for verbose output:

./build/test_lmdb_wrapper

Example Usage

#include "lmdb_wrapper.h"
#include <sys/stat.h>
#include <string.h>

int main(void) {
    lmdbWrapperEnv_t *env = NULL;
    lmdbWrapperConfig_t config = {
        .path = "./my_database",
        .mapSize = 0,  /* wrapper default 10MB */
        .maxDbs = 0    /* default 1 */
    };
    char readVal[64] = {0};
    size_t readSize = 0;

    (void)mkdir("./my_database", 0755);

    lmdbWrapperErr_t err = lmdbWrapperEnvCreate(&env, &config);
    if (err != LMDB_WRAPPER_SUCCESS) {
        return 1;
    }

    /* Write */
    const char *key = "block_001";
    const char *val = "data...";
    err = lmdbWrapperPut(env, key, strlen(key), val, strlen(val));

    /* Read */
    err = lmdbWrapperGet(env, key, strlen(key),
                         readVal, sizeof(readVal), &readSize);

    /* Delete */
    err = lmdbWrapperDel(env, key, strlen(key));

    lmdbWrapperEnvClose(env);
    return 0;
}

Project Structure

├── CLAUDE.md          # AI/development rules
├── CMakeLists.txt     # Build configuration
├── README.md          # This file
├── LICENSE            # MIT License
├── CONTRIBUTING.md    # Contribution guidelines
├── cmake/             # CMake modules
│   └── FetchLMDB.cmake
├── docs/              # Documentation
│   ├── architecture.md
│   └── context.md
├── examples/          # Example programs
│   └── basic_usage.c
├── include/           # Public headers
│   └── lmdb_wrapper.h
├── src/               # Implementation
│   └── lmdb_wrapper.c
├── tests/             # Tests
│   └── test_lmdb_wrapper.c
├── vcpkg-port/        # vcpkg port files (reference copy)
│   ├── portfile.cmake
│   └── vcpkg.json
└── todo/              # Task tracking
    └── plan.md

Error Codes

Code Meaning
LMDB_WRAPPER_SUCCESS Operation succeeded
LMDB_WRAPPER_ERR_NULL_PARAM A required parameter was NULL
LMDB_WRAPPER_ERR_INVALID_PARAM A parameter had an invalid value
LMDB_WRAPPER_ERR_NOT_FOUND Record not found
LMDB_WRAPPER_ERR_ENV_CREATE Failed to create LMDB environment
LMDB_WRAPPER_ERR_ENV_OPEN Failed to open LMDB environment
LMDB_WRAPPER_ERR_TXN_BEGIN Failed to begin transaction
LMDB_WRAPPER_ERR_DBI_OPEN Failed to open database handle
LMDB_WRAPPER_ERR_PUT Failed to write record
LMDB_WRAPPER_ERR_GET Failed to read record
LMDB_WRAPPER_ERR_DEL Failed to delete record
LMDB_WRAPPER_ERR_TXN_COMMIT Failed to commit transaction
LMDB_WRAPPER_ERR_MAP_FULL Database map is full
LMDB_WRAPPER_ERR_BUFFER_TOO_SMALL Output buffer is too small

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines on how to build, test, and submit changes.

License

This project is licensed under the MIT License.

About

MISRA C compliant wrapper for LMDB (Lightning Memory-Mapped Database)

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors