Documentation
¶
Index ¶
- Constants
- Variables
- func Get[T any](s *Store, key string) (T, error)
- func ValidateKey(key string) error
- type PersistMap
- func (pm *PersistMap[T]) Delete(key string) (existed bool)
- func (pm *PersistMap[T]) DeleteAsync(key string) (existed bool)
- func (pm *PersistMap[T]) DeleteFSync(key string) error
- func (pm *PersistMap[T]) Get(key string) (T, bool)
- func (pm *PersistMap[T]) Range(f func(key string, value T) bool)
- func (pm *PersistMap[T]) Set(key string, value T)
- func (pm *PersistMap[T]) SetAsync(key string, value T)
- func (pm *PersistMap[T]) SetFSync(key string, value T) error
- func (pm *PersistMap[T]) SetInMemory(key string, value T)
- func (pm *PersistMap[T]) Size() int
- func (pm *PersistMap[T]) Sync()
- func (pm *PersistMap[T]) Update(key string, updater func(upd *Update[T])) (newValue T, exists bool)
- func (pm *PersistMap[T]) UpdateAsync(key string, updater func(upd *Update[T])) (newValue T, exists bool)
- func (pm *PersistMap[T]) UpdateFSync(key string, updater func(upd *Update[T])) (newValue T, exists bool, err error)
- func (pm *PersistMap[T]) UpdateInMemory(key string, updater func(upd *Update[T])) T
- type Store
- func (s *Store) Close() error
- func (s *Store) Delete(key string) error
- func (s *Store) FSyncAll() error
- func (s *Store) GetSyncInterval() time.Duration
- func (s *Store) Open(path string) error
- func (s *Store) Set(key string, value interface{}) error
- func (s *Store) SetSyncInterval(interval time.Duration)
- func (s *Store) Shrink() error
- func (s *Store) StartAutoShrink(checkInterval time.Duration, shrinkRatio float64) error
- func (s *Store) Stats() (activeKeys int32, walRecords int32)
- type Update
Constants ¶
const DefaultSyncInterval = time.Second
Default value for store.syncInterval
const WalHeader = "go-persist 1"
Identification string written at the beginning of each WAL file to validate file format and version compatibility
Variables ¶
var ( ErrMapAlreadyExists = errors.New("persist map with the given name already exists in store") ErrTooLate = errors.New("cannot register new map after store has been loaded") )
Functions ¶
func Get ¶ added in v1.7.0
Get retrieves a typed value from orphaned records. Returns ErrKeyNotFound if the key doesn't exist or was deleted in the most recent operation.
func ValidateKey ¶ added in v1.5.0
ValidateKey validates the provided key ensuring it is not empty and that it does not include forbidden characters: ASCII (0x00–0x1F, 0x7F) and additional ones in the extended control range (0x80–0x9F).
Types ¶
type PersistMap ¶
type PersistMap[T any] struct { Store *Store // underlying WAL store // contains filtered or unexported fields }
func Map ¶
func Map[T any](store *Store, mapName string) (*PersistMap[T], error)
Map creates or loads PersistMap from store.
PersistMap represents a thread-safe persistent key-value store with type-safe values. It maintains an in-memory map for fast access while ensuring durability through the WAL.
The mapName parameter is used as a namespace: keys will be stored as "mapName:key" in the WAL.
func OpenSingleMap ¶ added in v1.5.0
func OpenSingleMap[T any](path string) (*PersistMap[T], error)
OpenSingleMap is the simplest way to get started with a persistent map when you need just one map per file. It opens the store, compacts the WAL, and initializes the map in a single operation.
It returns a PersistMap that represents a thread-safe persistent key-value store with type-safe values of type T. This map maintains an in-memory representation for fast access while ensuring durability through the WAL.
func (*PersistMap[T]) Delete ¶
func (pm *PersistMap[T]) Delete(key string) (existed bool)
Delete immediately deletes the key from both WAL and in-memory map Returns true if the key existed and was deleted
func (*PersistMap[T]) DeleteAsync ¶
func (pm *PersistMap[T]) DeleteAsync(key string) (existed bool)
DeleteAsync removes the key from the in-memory map and marks it as dirty for background flush Returns true if the key existed and was deleted
func (*PersistMap[T]) DeleteFSync ¶
func (pm *PersistMap[T]) DeleteFSync(key string) error
DeleteFSync writes a delete record to WAL immediately, flushes to disk (fsync), and updates the in-memory map.
func (*PersistMap[T]) Get ¶
func (pm *PersistMap[T]) Get(key string) (T, bool)
Get retrieves the value associated with the key from the in-memory map.
Returns the value and true if the key exists, or a zero value and false otherwise.
func (*PersistMap[T]) Range ¶ added in v1.2.0
func (pm *PersistMap[T]) Range(f func(key string, value T) bool)
Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
Range does not necessarily correspond to any consistent snapshot of the Map's contents: no key will be visited more than once, but if the value for any key is stored or deleted concurrently, Range may reflect any mapping for that key from any point during the Range call.
It is safe to modify the map while iterating it, including entry creation, modification and deletion. However, the concurrent modification rule apply, i.e. the changes may be not reflected in the subsequently iterated entries.
func (*PersistMap[T]) Set ¶
func (pm *PersistMap[T]) Set(key string, value T)
Set updates both in-memory data and WAL file immediately, but without fsync.
Safe for application crashes, as WAL ensures recovery, but may lose updates during system crashes if data remains in OS cache.
func (*PersistMap[T]) SetAsync ¶
func (pm *PersistMap[T]) SetAsync(key string, value T)
SetAsync updates the in-memory map and marks the key as dirty.
Its actual persistence is deferred to a background flush, providing higher performance at the cost of delayed durability.
func (*PersistMap[T]) SetFSync ¶
func (pm *PersistMap[T]) SetFSync(key string, value T) error
SetFSync updates in-memory data, WAL file, and forces physical disk write with fsync.
Most durable option that protects against both application and system crashes, but with highest performance cost.
func (*PersistMap[T]) SetInMemory ¶ added in v1.9.0
func (pm *PersistMap[T]) SetInMemory(key string, value T)
SetInMemory updates the value in memory only without explicitly writing to WAL or marking the key as dirty. This change won't trigger immediate persistence, but it may be persisted if:
- This key is later modified with Set/Update/etc.
- A Shrink operation occurs
Useful for non-exported, derived, or cached fields.
func (*PersistMap[T]) Size ¶ added in v1.2.0
func (pm *PersistMap[T]) Size() int
Size returns current size of the map
func (*PersistMap[T]) Sync ¶ added in v1.3.0
func (pm *PersistMap[T]) Sync()
Sync writes all pending changes made by Async methods to the WAL file. It processes all keys marked as dirty, persisting their current values or deletion status, then clears their dirty flags upon successful write.
Sync is automatically called periodically from the store's background synchronization process. This method only ensures consistency between memory and the WAL file, but doesn't guarantee data is physically written to disk - that step is handled by the Store.Flush method.
func (*PersistMap[T]) Update ¶ added in v1.3.0
func (pm *PersistMap[T]) Update(key string, updater func(upd *Update[T])) (newValue T, exists bool)
Update atomically updates the value for the given key using the updater function, and immediately writes the change to the WAL (without forcing disk fsync).
The updater receives an UpdateAction containing the current value and existence state. It can:
- Simply modify upd.Value to update the value (default action is "set")
- Call upd.Set() to explicitly set a new value
- Call upd.Delete() to remove the key
- Call upd.Cancel() to keep the original value unchanged
This method locks the relevant hash table bucket during execution, so avoid long-running operations in the updater function to prevent blocking other bucket operations.
func (*PersistMap[T]) UpdateAsync ¶ added in v1.3.0
func (pm *PersistMap[T]) UpdateAsync(key string, updater func(upd *Update[T])) (newValue T, exists bool)
UpdateAsync atomically updates a key using the updater function.
It only updates the in-memory value and marks the key as dirty so that background FSyncAll will eventually persist the change.
The updater receives an UpdateAction containing the current value and existence state. It can:
- Simply modify upd.Value to update the value (default action is "set")
- Call upd.Set() to explicitly set a new value
- Call upd.Delete() to remove the key
- Call upd.Cancel() to keep the original value unchanged
This method locks the relevant hash table bucket during execution, so avoid long-running operations in the updater function to prevent blocking other bucket operations.
func (*PersistMap[T]) UpdateFSync ¶ added in v1.3.0
func (pm *PersistMap[T]) UpdateFSync(key string, updater func(upd *Update[T])) (newValue T, exists bool, err error)
UpdateFSync atomically updates a key using the updater function, writes to the WAL, and forces a physical disk flush (fsync).
Offers maximum durability against both application and system crashes, but with the highest performance cost.
The updater receives an UpdateAction containing the current value and existence state. It can:
- Simply modify upd.Value to update the value (default action is "set")
- Call upd.Set() to explicitly set a new value
- Call upd.Delete() to remove the key
- Call upd.Cancel() to keep the original value unchanged
This method locks the relevant hash table bucket during execution, so avoid long-running operations in the updater function to prevent blocking other bucket operations.
func (*PersistMap[T]) UpdateInMemory ¶ added in v1.9.0
func (pm *PersistMap[T]) UpdateInMemory(key string, updater func(upd *Update[T])) T
UpdateInMemory atomically updates a value in memory only without writing to WAL or marking the key as dirty. This change won't trigger immediate persistence, but will be persisted if:
- This key is later modified with Set/Update/etc.
- A Shrink operation occurs
The method uses the same Update struct as regular Update methods for API consistency, but only supports the Set action. Attempts to use Delete or Cancel will cause panic.
Useful for non-exported, derived, or cached fields.
type Store ¶
type Store struct {
//
ErrorHandler func(err error)
ReaderBufferSize int
// contains filtered or unexported fields
}
Store represents the WAL(write-ahead log) storage
func New ¶ added in v1.7.0
func New() *Store
New creates and initializes a new Store instance.
The returned Store is not yet connected to any file - you must call Open() with a file path to load existing data or create a new persistence file.
By default, the Store is configured with:
- DefaultSyncInterval (1 second) for background synchronization
- A default error handler that calls log.Fatal
- Empty maps for tracking PersistMap instances and orphaned records
Example usage:
store := persist.New()
err := store.Open("mydata.db")
if err != nil {
log.Fatal(err)
}
defer store.Close()
func (*Store) Close ¶
Saves all pending changes and stops the background sync goroutine Then closes the underlying file.
The Store should not be used after calling Close.
func (*Store) Delete ¶
Delete marks a key as deleted by writing a "delete" record to the log. The record format consists of two lines:
- D <key>
- <Empty value line>
The newline after the empty value line serves as a marker that the delete record was successfully written and can be safely processed during recovery.
func (*Store) FSyncAll ¶ added in v1.3.0
FSyncAll ensures complete data durability by:
- Synchronizing all dirty map entries to the WAL file
- Performing an fsync operation to guarantee data is physically written to disk
This operation provides the strongest durability guarantee, protecting against both application crashes and system failures. It's automatically called periodically based on the configured syncInterval, but can also be called manually when immediate durability is required.
func (*Store) GetSyncInterval ¶
SetSyncInterval configures how frequently the background goroutine will call FSyncAll() to ensure all changes are durably committed to disk
func (*Store) Open ¶ added in v1.7.0
Open opens the persistent storage file, validates/writes the WAL header, starts the background sync goroutine and immediately loads all WAL records into the registered maps.
func (*Store) Set ¶
Set persists a key-value pair by writing a "set" record to the WAL log and updates the corresponding entry in orphanRecords.
This is a synchronous operation that writes to the WAL file immediately, but without fsync.
func (*Store) SetSyncInterval ¶
SetSyncInterval sets a new sync interval
func (*Store) Shrink ¶
Shrink compacts the WAL file by discarding deleted records and redundant updates, retaining only the latest state for each key. The operation is designed to be minimally blocking:
- Most compaction happens without locks, allowing concurrent operations
- Operations performed during shrinking are captured and preserved
- Only brief locks are used to swap files and finalize pending operations
The function creates a temporary file with current state only, then atomically replaces the original WAL file.
func (*Store) StartAutoShrink ¶ added in v1.8.0
StartAutoShrink initiates a background goroutine that automatically compacts the WAL file at regular intervals when certain conditions are met.
Parameters:
- checkInterval: How frequently to check if compaction is needed
- shrinkRatio: The threshold ratio of (WAL records)/(active keys) that triggers shrinking
func (*Store) Stats ¶ added in v1.8.0
Stats returns statistics about the store state.
Returns:
- activeKeys: The total number of currently active (non-deleted) keys across all registered maps and orphan records. This represents the actual data items currently stored.
- walRecords: The total number of records written to the WAL file since opening, including both set and delete operations. This can be significantly higher than activeKeys due to updates and deletions.
This method can be useful for monitoring storage growth and determining when a Shrink() operation might be beneficial (when walRecords is much larger than activeKeys).
type Update ¶ added in v1.6.1
type Update[T any] struct { Value T // Current value retrieved from the map Exists bool // Whether the key exists // contains filtered or unexported fields }
Update encapsulates the state for updating a key in the map. It holds the current value and its existence flag, and allows the updater to specify the intended action: update (set), deletion, or cancellation. By default, the action is set to update, so modifying the Value field directly implies a "set" operation.
func (*Update[T]) Cancel ¶ added in v1.6.1
func (ua *Update[T]) Cancel()
Cancel indicates that no changes should be applied