- 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>
56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
//go:build !(js && wasm)
|
|
|
|
package bbolt
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"next.orly.dev/pkg/database"
|
|
)
|
|
|
|
func init() {
|
|
database.RegisterBboltFactory(newBboltFromConfig)
|
|
}
|
|
|
|
// newBboltFromConfig creates a BBolt database from DatabaseConfig
|
|
func newBboltFromConfig(
|
|
ctx context.Context,
|
|
cancel context.CancelFunc,
|
|
cfg *database.DatabaseConfig,
|
|
) (database.Database, error) {
|
|
// Convert DatabaseConfig to BboltConfig
|
|
bboltCfg := &BboltConfig{
|
|
DataDir: cfg.DataDir,
|
|
LogLevel: cfg.LogLevel,
|
|
|
|
// Use bbolt-specific settings from DatabaseConfig if present
|
|
// These will be added to DatabaseConfig later
|
|
BatchMaxEvents: cfg.BboltBatchMaxEvents,
|
|
BatchMaxBytes: cfg.BboltBatchMaxBytes,
|
|
BatchFlushTimeout: cfg.BboltFlushTimeout,
|
|
BloomSizeMB: cfg.BboltBloomSizeMB,
|
|
NoSync: cfg.BboltNoSync,
|
|
InitialMmapSize: cfg.BboltMmapSize,
|
|
}
|
|
|
|
// Apply defaults if not set
|
|
if bboltCfg.BatchMaxEvents <= 0 {
|
|
bboltCfg.BatchMaxEvents = 5000
|
|
}
|
|
if bboltCfg.BatchMaxBytes <= 0 {
|
|
bboltCfg.BatchMaxBytes = 128 * 1024 * 1024 // 128MB
|
|
}
|
|
if bboltCfg.BatchFlushTimeout <= 0 {
|
|
bboltCfg.BatchFlushTimeout = 30 * time.Second
|
|
}
|
|
if bboltCfg.BloomSizeMB <= 0 {
|
|
bboltCfg.BloomSizeMB = 16
|
|
}
|
|
if bboltCfg.InitialMmapSize <= 0 {
|
|
bboltCfg.InitialMmapSize = 8 * 1024 * 1024 * 1024 // 8GB
|
|
}
|
|
|
|
return NewWithConfig(ctx, cancel, bboltCfg)
|
|
}
|