Add BBolt database backend for HDD-optimized archival relays (v0.48.0)
- BBolt B+tree backend with sequential access patterns for spinning disks - Write batching (5000 events / 128MB / 30s flush) to reduce disk thrashing - Adjacency list storage for graph data (one key per vertex, not per edge) - Bloom filter for fast negative edge existence checks (~12MB for 10M edges) - No query cache (saves RAM, B+tree reads are fast enough on HDD) - Migration tool: orly migrate --from badger --to bbolt - Configuration: ORLY_BBOLT_* environment variables Files modified: - app/config/config.go: Added BBolt configuration options - main.go: Added migrate subcommand and BBolt config wiring - pkg/database/factory.go: Added BBolt factory registration - pkg/bbolt/*: New BBolt database backend implementation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
62
pkg/bbolt/markers.go
Normal file
62
pkg/bbolt/markers.go
Normal file
@@ -0,0 +1,62 @@
|
||||
//go:build !(js && wasm)
|
||||
|
||||
package bbolt
|
||||
|
||||
import (
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
const markerPrefix = "marker:"
|
||||
|
||||
// SetMarker sets a metadata marker.
|
||||
func (b *B) SetMarker(key string, value []byte) error {
|
||||
return b.db.Update(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket(bucketMeta)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
return bucket.Put([]byte(markerPrefix+key), value)
|
||||
})
|
||||
}
|
||||
|
||||
// GetMarker gets a metadata marker.
|
||||
func (b *B) GetMarker(key string) (value []byte, err error) {
|
||||
err = b.db.View(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket(bucketMeta)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
data := bucket.Get([]byte(markerPrefix + key))
|
||||
if data != nil {
|
||||
value = make([]byte, len(data))
|
||||
copy(value, data)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// HasMarker checks if a marker exists.
|
||||
func (b *B) HasMarker(key string) bool {
|
||||
var exists bool
|
||||
b.db.View(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket(bucketMeta)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
exists = bucket.Get([]byte(markerPrefix+key)) != nil
|
||||
return nil
|
||||
})
|
||||
return exists
|
||||
}
|
||||
|
||||
// DeleteMarker deletes a marker.
|
||||
func (b *B) DeleteMarker(key string) error {
|
||||
return b.db.Update(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket(bucketMeta)
|
||||
if bucket == nil {
|
||||
return nil
|
||||
}
|
||||
return bucket.Delete([]byte(markerPrefix + key))
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user