-
Notifications
You must be signed in to change notification settings - Fork 0
LevelDB Cache #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a LevelDB-backed implementation of the httpcache.Cache interface, providing a persistent, disk-based caching option alongside the existing in-memory and Ristretto cache implementations.
Changes:
- Implements a new LevelDB cache backend with Get, Put, Del, and Close methods
- Adds comprehensive tests and benchmarks for the LevelDB cache
- Adds proper cleanup (defer Close()) to existing Ristretto tests
- Updates dependencies to include goleveldb and its transitive dependencies
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| leveldb/leveldb.go | Core implementation of LevelDB cache with error logging and io.Closer interface |
| leveldb/leveldb_test.go | Basic functional and concurrency tests for LevelDB cache |
| leveldb/leveldb_bench_test.go | Performance benchmarks for Get, Put, and mixed operations |
| ristretto/ristretto_test.go | Added defer cache.Close() for proper resource cleanup in tests |
| go.mod | Added goleveldb dependency |
| go.sum | Updated with goleveldb and its transitive dependencies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| // Make returns a cache using the specified db instance as the underlying storage. | ||
| func Make(db *leveldb.DB) *Cache { |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Make function should validate that the db parameter is not nil to prevent panics when methods are called on the Cache. Add a nil check and return an error or panic with a descriptive message if db is nil.
| func Make(db *leveldb.DB) *Cache { | |
| func Make(db *leveldb.DB) *Cache { | |
| if db == nil { | |
| panic("leveldb: nil *leveldb.DB passed to leveldb.Make") | |
| } |
| @@ -0,0 +1,61 @@ | |||
| package leveldb | |||
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a package-level documentation comment to describe the leveldb package, similar to the pattern used in ristretto/ristretto.go. This should explain what the package provides, its use case, and include a simple example. Package documentation improves discoverability and usability.
| func benchmarkGet(size int) func(b *testing.B) { | ||
| return func(b *testing.B) { | ||
| path := filepath.Join(b.TempDir(), "cache.db") | ||
| cache, err := leveldb.New(path) | ||
| require.NoError(b, err) | ||
| defer cache.Close() |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache instance created in this benchmark is not properly closed. This can lead to resource leaks, especially in benchmarks that run multiple iterations. Add a defer statement after line 16 to close the cache.
| func benchmarkPut(size int) func(b *testing.B) { | ||
| return func(b *testing.B) { | ||
| path := filepath.Join(b.TempDir(), "cache.db") | ||
| cache, err := leveldb.New(path) | ||
| require.NoError(b, err) | ||
| defer cache.Close() |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache instance created in this benchmark is not properly closed. This can lead to resource leaks, especially in benchmarks that run multiple iterations. Add a defer statement after line 44 to close the cache.
| func BenchmarkLevelDBCacheMixed(b *testing.B) { | ||
| path := filepath.Join(b.TempDir(), "cache.db") | ||
| cache, err := leveldb.New(path) | ||
| require.NoError(b, err) | ||
| defer cache.Close() |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache instance created in this benchmark is not properly closed. This can lead to resource leaks, especially in benchmarks that run multiple iterations. Add a defer statement after line 66 to close the cache.
| func BenchmarkLevelDBCacheParallelMixed(b *testing.B) { | ||
| path := filepath.Join(b.TempDir(), "cache.db") | ||
| cache, err := leveldb.New(path) | ||
| require.NoError(b, err) | ||
| defer cache.Close() |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache instance created in this benchmark is not properly closed. This can lead to resource leaks, especially in benchmarks that run multiple iterations. Add a defer statement after line 89 to close the cache.
| github.com/cespare/xxhash/v2 v2.3.0 // indirect | ||
| github.com/davecgh/go-spew v1.1.1 // indirect | ||
| github.com/dustin/go-humanize v1.0.1 // indirect | ||
| github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version of golang/snappy is from 2018 (commit 2e65f85255db). Consider updating to a more recent version for potential bug fixes and performance improvements. The goleveldb dependency may be pulling in an outdated transitive dependency.
| github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect | |
| github.com/golang/snappy v0.0.4 // indirect |
| // Cache is an implementation of httpcache.Cache with leveldb storage | ||
| type Cache struct { | ||
| db *leveldb.DB | ||
| } |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add compile-time interface checks to ensure Cache implements httpcache.Cache and io.Closer, similar to the pattern used in ristretto/ristretto.go. Add these lines after the Cache struct definition: var _ httpcache.Cache = (*Cache)(nil) and var _ io.Closer = (*Cache)(nil). This ensures the interface is properly implemented and catches any breaking changes at compile time.
Scope of changes
Adds LevelDB stateful cache.
Fixes SC-36558
Type of change
Author checklist