shelf

Types

Configuration for opening a persistent table.

pub type Config {
  Config(name: String, path: String, write_mode: WriteMode)
}

Constructors

  • Config(name: String, path: String, write_mode: WriteMode)

    Arguments

    name

    Unique name for the ETS table (must not conflict with other ETS tables)

    path

    File path for the DETS backing store

    write_mode

    When to persist writes to disk

Persistent ETS tables backed by DETS.

Shelf combines ETS (fast, in-memory) with DETS (persistent, on-disk) to give you microsecond reads with durable storage. The classic Erlang persistence pattern, wrapped in a type-safe Gleam API.

Quick Start

import shelf
import shelf/set

let assert Ok(table) = set.open("cache", "data/cache.dets")
let assert Ok(Nil) = set.insert(table, "key", "value")
let assert Ok("value") = set.lookup(table, "key")
let assert Ok(Nil) = set.save(table)   // persist to disk
let assert Ok(Nil) = set.close(table)

Write Modes

  • WriteBack (default) — writes go to ETS only; call save() to persist
  • WriteThrough — every write goes to both ETS and DETS immediately

Table Types

  • shelf/set — unique keys, one value per key
  • shelf/bag — multiple distinct values per key
  • shelf/duplicate_bag — multiple values per key (duplicates allowed)

Limitations

  • DETS has a 2 GB maximum file size
  • No ordered set (DETS doesn’t support it)
  • DETS performs disk I/O — save() has real latency

Errors

Operations return Result with ShelfError for failures.

pub type ShelfError {
  NotFound
  KeyAlreadyPresent
  TableClosed
  FileError(String)
  NameConflict
  FileSizeLimitExceeded
  ErlangError(String)
}

Constructors

  • NotFound

    No value found for the given key

  • KeyAlreadyPresent

    Key already exists (for insert_new)

  • TableClosed

    Table has been closed or doesn’t exist

  • FileError(String)

    DETS file could not be found or created

  • NameConflict

    An ETS table with this name already exists

  • FileSizeLimitExceeded

    DETS file exceeds the 2 GB limit

  • ErlangError(String)

    Erlang-level error (catch-all)

Controls when writes are persisted to disk.

pub type WriteMode {
  WriteBack
  WriteThrough
}

Constructors

  • WriteBack

    Writes go to ETS only. Call save() to persist.

    Best for high-throughput writes where you control the save schedule. Data written since the last save() is lost on crash.

  • WriteThrough

    Every write goes to both ETS and DETS immediately.

    Slower writes but no data loss between saves. Reads are still fast (always from ETS).

Values

pub fn config(name name: String, path path: String) -> Config

Create a config with the default write mode (WriteBack).

let conf = shelf.config(name: "users", path: "data/users.dets")
pub fn write_mode(
  config config: Config,
  mode mode: WriteMode,
) -> Config

Set the write mode on a config.

let conf =
  shelf.config(name: "users", path: "data/users.dets")
  |> shelf.write_mode(shelf.WriteThrough)
Search Document