ScaloDB - Reusable Database Library
A high-performance, embeddable key-value database for Go applications.
Features
- Embedded Mode: Use directly in your application (2-5M ops/sec)
- Server Mode: Run as standalone server (500K-3M ops/sec)
- MVCC: Lock-free concurrent reads
- WAL: Write-ahead logging for durability
- Thread-Safe: Use from multiple goroutines
- Simple API: Easy integration
Quick Start
Installation
# Copy this folder to your project cp -r scalodb /path/to/your/project/ # Or use as Go module cd scalodb go mod init github.com/yourusername/scalodb
Embedded Mode
package main import ( "fmt" "scalodb" ) func main() { // Create database db, _ := scalodb.New(&scalodb.Config{ WALPath: "myapp.wal", }) defer db.Close() // Use it db.Put("user:1001", []byte("John Doe")) value, _ := db.Get("user:1001") fmt.Println(string(value)) }
Server Mode
package main import ( "log" "scalodb" ) func main() { db, _ := scalodb.New(&scalodb.Config{ Addr: ":8080", MaxConns: 10000, WALPath: "server.wal", }) defer db.Close() log.Println("Starting server on :8080") db.StartAndWait() }
API Reference
Configuration
type Config struct { Addr string // Listen address (":8080"), empty for embedded MaxConns int // Max connections (default: 1000) WALPath string // WAL file path (default: "scalodb.wal") EnableWAL bool // Enable WAL (default: true) }
Operations
// Create database db, err := scalodb.New(&scalodb.Config{}) // Store data err = db.Put(key string, value []byte) // Retrieve data value, err := db.Get(key string) // Delete data err = db.Delete(key string) // Scan all data data, err := db.Scan() // Get statistics stats := db.Stats() // Close database err = db.Close()
Server Control
// Start server (non-blocking) err = db.Start() // Start and wait (blocking) err = db.StartAndWait() // Stop server err = db.Stop()
Example Code
All examples are included in the documentation below.
Use Cases
Session Store
type SessionStore struct { db *scalodb.DB } func NewSessionStore() (*SessionStore, error) { db, err := scalodb.New(&scalodb.Config{ WALPath: "sessions.wal", }) return &SessionStore{db: db}, err } func (s *SessionStore) Set(id string, data []byte) error { return s.db.Put("session:"+id, data) } func (s *SessionStore) Get(id string) ([]byte, error) { return s.db.Get("session:" + id) }
Cache Layer
type Cache struct { db *scalodb.DB } func NewCache() (*Cache, error) { db, err := scalodb.New(&scalodb.Config{ WALPath: "cache.wal", EnableWAL: false, // No persistence for cache }) return &Cache{db: db}, err } func (c *Cache) Set(key string, value []byte) error { return c.db.Put("cache:"+key, value) } func (c *Cache) Get(key string) ([]byte, error) { return c.db.Get("cache:" + key) }
REST API Backend
func main() { db, _ := scalodb.New(&scalodb.Config{}) defer db.Close() http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) { key := r.URL.Query().Get("key") switch r.Method { case "GET": value, _ := db.Get(key) w.Write(value) case "POST": value, _ := io.ReadAll(r.Body) db.Put(key, value) } }) http.ListenAndServe(":8080", nil) }
Performance
- Embedded Mode: 2-5M operations/second
- Server Mode: 500K-3M operations/second
- Concurrent Reads: Lock-free with MVCC
- Durability: WAL with crash recovery
- Scalability: Horizontal via sharding
Thread Safety
ScaloDB is fully thread-safe:
db, _ := scalodb.New(&scalodb.Config{}) go func() { db.Put("key1", []byte("value1")) }() go func() { db.Put("key2", []byte("value2")) }() go func() { value, _ := db.Get("key1") }()
Documentation
- README.md - This file (complete documentation)
- LIBRARY_USAGE.md - Detailed API documentation
- REUSABLE_SUMMARY.md - Quick reference guide
Architecture
scalodb-library/
├── scalodb.go # Main library API
├── storage/ # Storage engine
│ ├── engine.go # Main engine
│ ├── mvcc.go # MVCC implementation
│ └── wal.go # Write-ahead log
└── README.md # This file
Integration
With Gin
r := gin.Default() r.GET("/data/:key", func(c *gin.Context) { value, _ := db.Get(c.Param("key")) c.Data(200, "text/plain", value) }) r.POST("/data/:key", func(c *gin.Context) { value, _ := c.GetRawData() db.Put(c.Param("key"), value) c.Status(201) })
With Echo
e := echo.New() e.GET("/data/:key", func(c echo.Context) error { value, _ := db.Get(c.Param("key")) return c.Blob(200, "text/plain", value) }) e.POST("/data/:key", func(c echo.Context) error { value, _ := io.ReadAll(c.Request().Body) db.Put(c.Param("key"), value) return c.NoContent(201) })
Best Practices
-
Always defer Close(): Ensures WAL is flushed
db, _ := scalodb.New(&scalodb.Config{}) defer db.Close()
-
Use key prefixes: Organize your data
db.Put("user:1001:profile", data) db.Put("session:abc123", data) db.Put("cache:homepage", data)
-
Handle errors: Don't ignore returns
if err := db.Put(key, value); err != nil { log.Printf("Failed: %v", err) }
-
Monitor stats: Track growth
stats := db.Stats() log.Printf("Keys: %d, Size: %d", stats.TotalKeys, stats.TotalSize)
Comparison: Embedded vs Server
| Feature | Embedded | Server |
|---|---|---|
| Performance | Fastest | Fast |
| Multi-process | No | Yes |
| Network | No | Yes |
| Setup | Simple | Requires server |
| Use case | Single app | Microservices |
License
MIT License - Free to use in any project
Support
- See examples/ for code samples
- Read LIBRARY_USAGE.md for detailed docs
- Check REUSABLE_SUMMARY.md for quick reference