storage

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package storage provides the底层 storage layer for gograph using Pebble as the underlying key-value store. It handles data marshaling, key generation, and basic CRUD operations.

Package storage provides the底层 storage layer for gograph using Pebble as the underlying key-value store.

Package storage provides a key-value storage layer for gograph using PebbleDB. It wraps the Pebble database to provide a simplified interface for storing and retrieving graph data including nodes, relationships, and indices.

The storage layer uses the following key prefixes:

  • "n:" - Node data
  • "r:" - Relationship data
  • "i:" - Index data
  • "a:" - Adjacency list data

Basic Usage:

db, err := storage.Open("/path/to/db")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

// Store data
err = db.Put([]byte("key"), []byte("value"))

// Retrieve data
value, err := db.Get([]byte("key"))

Thread Safety:

DB is safe for concurrent use by multiple goroutines.

Index

Constants

View Source
const (
	// KeyPrefixNode is the prefix for node data keys.
	// Format: "node:<nodeID>"
	KeyPrefixNode = "node:"

	// KeyPrefixRel is the prefix for relationship data keys.
	// Format: "rel:<relID>"
	KeyPrefixRel = "rel:"

	// KeyPrefixLabel is the prefix for label index keys.
	// Format: "label:<labelName>:<nodeID>"
	KeyPrefixLabel = "label:"

	// KeyPrefixProp is the prefix for property index keys.
	// Format: "prop:<labelName>:<propName>:<propValue>:<nodeID>"
	KeyPrefixProp = "prop:"

	// KeyPrefixAdj is the prefix for adjacency list keys.
	// Format: "adj:<nodeID>:<relType>:<direction>:<relID>"
	KeyPrefixAdj = "adj:"

	// KeyPrefixMeta is the prefix for metadata keys.
	KeyPrefixMeta = "meta:"

	// KeyPrefixIndexCount is the key for storing the index count.
	KeyPrefixIndexCount = "meta:index_count"
)

Key prefixes for different types of data in the storage layer. These prefixes ensure that different data types are stored in separate key ranges for efficient iteration and querying.

Variables

This section is empty.

Functions

func AdjKey

func AdjKey(nodeID, relType, direction, relID string) []byte

AdjKey returns the storage key for an adjacency entry.

Parameters:

  • nodeID: The ID of the node
  • relType: The type of relationship
  • direction: The direction ("out" or "in")
  • relID: The ID of the relationship

Returns the storage key as a byte slice.

Example:

key := storage.AdjKey("node:a1", "KNOWS", "out", "rel:b2")
// key = []byte("adj:node:a1:KNOWS:out:rel:b2")

func AdjKeyPrefix

func AdjKeyPrefix(nodeID string) []byte

AdjKeyPrefix returns the key prefix for all adjacency entries of a node. This is used for finding all relationships connected to a node.

Parameters:

  • nodeID: The ID of the node

Returns the key prefix as a byte slice.

Example:

prefix := storage.AdjKeyPrefix("node:a1")
// prefix = []byte("adj:node:a1:")

func AdjKeyPrefixNodeAndType

func AdjKeyPrefixNodeAndType(nodeID, relType string) []byte

AdjKeyPrefixNodeAndType returns the key prefix for all adjacency entries of a node with a specific relationship type. This is used for finding all relationships of a specific type connected to a node.

Parameters:

  • nodeID: The ID of the node
  • relType: The type of relationship

Returns the key prefix as a byte slice.

Example:

prefix := storage.AdjKeyPrefixNodeAndType("node:a1", "KNOWS")
// prefix = []byte("adj:node:a1:KNOWS:")

func AdjKeyPrefixNodeAndTypeAndDir

func AdjKeyPrefixNodeAndTypeAndDir(nodeID, relType, direction string) []byte

AdjKeyPrefixNodeAndTypeAndDir returns the key prefix for all adjacency entries of a node with a specific relationship type and direction. This is used for finding relationships in a specific direction.

Parameters:

  • nodeID: The ID of the node
  • relType: The type of relationship
  • direction: The direction ("out" or "in")

Returns the key prefix as a byte slice.

Example:

prefix := storage.AdjKeyPrefixNodeAndTypeAndDir("node:a1", "KNOWS", "out")
// prefix = []byte("adj:node:a1:KNOWS:out:")

func LabelKey

func LabelKey(labelName, nodeID string) []byte

LabelKey returns the storage key for a label index entry.

Parameters:

  • labelName: The name of the label
  • nodeID: The ID of the node with this label

Returns the storage key as a byte slice.

Example:

key := storage.LabelKey("Person", "node:a1")
// key = []byte("label:Person:node:a1")

func LabelKeyPrefix

func LabelKeyPrefix(labelName string) []byte

LabelKeyPrefix returns the key prefix for all entries with the given label. This is used for iterating over all nodes with a specific label.

Parameters:

  • labelName: The name of the label

Returns the key prefix as a byte slice.

Example:

prefix := storage.LabelKeyPrefix("Person")
// prefix = []byte("label:Person:")

func Marshal

func Marshal(v interface{}) ([]byte, error)

Marshal encodes a value to bytes using Gob encoding.

func NodeKey

func NodeKey(nodeID string) []byte

NodeKey returns the storage key for a node with the given ID.

Parameters:

  • nodeID: The unique identifier of the node

Returns the storage key as a byte slice.

Example:

key := storage.NodeKey("node:a1")
// key = []byte("node:node:a1")

func PropertyKey

func PropertyKey(labelName, propName, propValue string) []byte

PropertyKey returns the storage key for a property index entry.

Parameters:

  • labelName: The name of the label
  • propName: The name of the property
  • propValue: The value of the property (encoded as string)

Returns the storage key as a byte slice.

Example:

key := storage.PropertyKey("Person", "name", "Alice")
// key = []byte("prop:Person:name:Alice")

func PropertyKeyPrefix

func PropertyKeyPrefix(labelName, propName string) []byte

PropertyKeyPrefix returns the key prefix for all entries with the given label and property name. This is used for iterating over all nodes with a specific label and property.

Parameters:

  • labelName: The name of the label
  • propName: The name of the property

Returns the key prefix as a byte slice.

Example:

prefix := storage.PropertyKeyPrefix("Person", "name")
// prefix = []byte("prop:Person:name:")

func RelKey

func RelKey(relID string) []byte

RelKey returns the storage key for a relationship with the given ID.

Parameters:

  • relID: The unique identifier of the relationship

Returns the storage key as a byte slice.

Example:

key := storage.RelKey("rel:b2")
// key = []byte("rel:rel:b2")

func Unmarshal

func Unmarshal(data []byte, v interface{}) error

Unmarshal decodes bytes to a value using Gob encoding.

Types

type Batch

type Batch struct {
	// contains filtered or unexported fields
}

Batch represents a collection of write operations that can be committed atomically. Use NewBatch to create a batch, add operations to it, then call Commit.

func (*Batch) Close

func (b *Batch) Close() error

Close releases resources associated with the batch. This should be called after the batch is no longer needed.

Returns an error if closing fails.

func (*Batch) Commit

func (b *Batch) Commit() error

Commit applies all operations in the batch atomically. If any operation fails, none of the operations will be applied.

Returns an error if the commit fails.

func (*Batch) Delete

func (b *Batch) Delete(key []byte) error

Delete adds a delete operation to the batch. The operation will not be applied until Commit is called.

Parameters:

  • key: The key to delete

Returns an error if the operation cannot be added to the batch.

func (*Batch) Put

func (b *Batch) Put(key, value []byte) error

Put adds a put operation to the batch. The operation will not be applied until Commit is called.

Parameters:

  • key: The key to store
  • value: The value to store

Returns an error if the operation cannot be added to the batch.

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB wraps a Pebble database instance. It provides a simplified interface for key-value operations and manages the underlying Pebble database lifecycle.

DB is safe for concurrent use by multiple goroutines.

func Open

func Open(path string) (*DB, error)

Open opens a database at the given path and returns a DB instance.

Parameters:

  • path: The directory path where the database files will be stored. If the directory doesn't exist, it will be created.

Returns a new DB instance or an error if the database cannot be opened.

Example:

db, err := storage.Open("/var/lib/gograph/mydb")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

func (*DB) Close

func (db *DB) Close() error

Close closes the database and releases all associated resources. Any pending writes will be flushed before closing.

Returns an error if the close operation fails.

func (*DB) Delete

func (db *DB) Delete(key []byte) error

Delete removes the value for the given key. If the key doesn't exist, this is a no-op.

Parameters:

  • key: The key to delete

Returns an error if the operation fails.

Example:

err := db.Delete([]byte("mykey"))
if err != nil {
    log.Fatal(err)
}

func (*DB) DumpAll added in v0.2.0

func (db *DB) DumpAll() (map[string][]byte, error)

DumpAll returns all key-value pairs in the database. This is primarily useful for debugging and testing.

Returns a map of all keys to their values, or an error if the operation fails.

Warning: This method loads all data into memory and should not be used on large databases.

Example:

data, err := db.DumpAll()
if err != nil {
    log.Fatal(err)
}
for key, value := range data {
    fmt.Printf("%s: %s\n", key, value)
}

func (*DB) Get

func (db *DB) Get(key []byte) ([]byte, error)

Get retrieves the value for the given key.

Parameters:

  • key: The key to look up

Returns the value as a byte slice, or an error if the key is not found or if a database error occurs.

Example:

value, err := db.Get([]byte("mykey"))
if err != nil {
    log.Printf("Key not found: %v", err)
} else {
    fmt.Printf("Value: %s\n", value)
}

func (*DB) NewBatch

func (db *DB) NewBatch() *Batch

NewBatch creates a new batch for atomic write operations. Batches allow multiple operations to be committed atomically.

Returns a new Batch instance.

Example:

batch := db.NewBatch()
batch.Put([]byte("key1"), []byte("value1"))
batch.Put([]byte("key2"), []byte("value2"))
batch.Delete([]byte("key3"))
err := batch.Commit()

func (*DB) NewIter

func (db *DB) NewIter(opts *pebble.IterOptions) (*Iterator, error)

NewIter creates a new iterator for scanning the database.

Parameters:

  • opts: Iterator options. Pass nil for default options.

Returns a new Iterator or an error if creation fails.

Example:

iter, err := db.NewIter(nil)
if err != nil {
    log.Fatal(err)
}
defer iter.Close()

for iter.SeekGE([]byte("prefix")); iter.Valid(); iter.Next() {
    fmt.Printf("%s: %s\n", iter.Key(), iter.Value())
}

func (*DB) Put

func (db *DB) Put(key, value []byte) error

Put stores a key-value pair in the database. If the key already exists, its value will be overwritten.

Parameters:

  • key: The key to store
  • value: The value to store

Returns an error if the operation fails.

Example:

err := db.Put([]byte("mykey"), []byte("myvalue"))
if err != nil {
    log.Fatal(err)
}

type Iterator

type Iterator struct {
	// contains filtered or unexported fields
}

Iterator provides ordered iteration over the database. Iterators must be closed when no longer needed to release resources.

func (*Iterator) Close

func (i *Iterator) Close() error

Close releases resources associated with the iterator. This must be called when the iterator is no longer needed.

Returns an error if closing fails.

func (*Iterator) Error

func (i *Iterator) Error() error

Error returns any accumulated error during iteration.

func (*Iterator) Key

func (i *Iterator) Key() []byte

Key returns the current key. The returned slice is only valid until the next iterator operation.

func (*Iterator) Next

func (i *Iterator) Next() bool

Next advances the iterator to the next key.

Returns true if a valid key was found, false if the iterator is exhausted.

func (*Iterator) Prev

func (i *Iterator) Prev() bool

Prev moves the iterator to the previous key.

Returns true if a valid key was found, false if the iterator is exhausted.

func (*Iterator) SeekGE

func (i *Iterator) SeekGE(key []byte) bool

SeekGE positions the iterator at the first key that is greater than or equal to the given key.

Parameters:

  • key: The key to seek to

Returns true if a valid key was found, false otherwise.

func (*Iterator) SeekLT

func (i *Iterator) SeekLT(key []byte) bool

SeekLT positions the iterator at the last key that is less than the given key.

Parameters:

  • key: The key to seek to

Returns true if a valid key was found, false otherwise.

func (*Iterator) Valid

func (i *Iterator) Valid() bool

Valid returns true if the iterator is positioned at a valid key.

func (*Iterator) Value

func (i *Iterator) Value() []byte

Value returns the current value. The returned slice is only valid until the next iterator operation.

type MemoryBatch added in v0.2.1

type MemoryBatch struct {
	// contains filtered or unexported fields
}

MemoryBatch represents a batch of operations for MemoryDB.

func (*MemoryBatch) Close added in v0.2.1

func (b *MemoryBatch) Close() error

Close closes the batch.

func (*MemoryBatch) Commit added in v0.2.1

func (b *MemoryBatch) Commit() error

Commit applies the batch operations to the MemoryDB.

func (*MemoryBatch) Delete added in v0.2.1

func (b *MemoryBatch) Delete(key []byte) error

Delete adds a delete operation to the batch.

func (*MemoryBatch) Put added in v0.2.1

func (b *MemoryBatch) Put(key, value []byte) error

Put adds a put operation to the batch.

type MemoryDB added in v0.2.1

type MemoryDB struct {
	// contains filtered or unexported fields
}

MemoryDB is an in-memory key-value store.

func NewMemoryDB added in v0.2.1

func NewMemoryDB() *MemoryDB

NewMemoryDB creates a new MemoryDB.

func (*MemoryDB) Delete added in v0.2.1

func (db *MemoryDB) Delete(key []byte) error

Delete removes a key-value pair from the MemoryDB.

func (*MemoryDB) Get added in v0.2.1

func (db *MemoryDB) Get(key []byte) ([]byte, error)

Get retrieves a value from the MemoryDB.

func (*MemoryDB) NewMemoryBatch added in v0.2.1

func (db *MemoryDB) NewMemoryBatch() *MemoryBatch

NewMemoryBatch creates a new MemoryBatch.

func (*MemoryDB) Put added in v0.2.1

func (db *MemoryDB) Put(key, value []byte) error

Put stores a key-value pair in the MemoryDB.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL