Skip to content

Conversation

@bbengfort
Copy link
Contributor

@bbengfort bbengfort commented Jan 13, 2026

Scope of changes

Adds LevelDB stateful cache.

Fixes SC-36558

Type of change

  • new feature
  • bug fix
  • documentation
  • testing
  • technical debt
  • other (describe)

Author checklist

  • I have manually tested the change and/or added automation in the form of unit tests or integration tests
  • I have added new test fixtures as needed to support added tests
  • Check this box if a reviewer can merge this pull request after approval (leave it unchecked if you want to do it yourself)
  • I have moved the associated Shortcut story to "Ready for Review"

Copilot AI review requested due to automatic review settings January 13, 2026 13:42
Copy link

Copilot AI left a 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 {
Copy link

Copilot AI Jan 13, 2026

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.

Suggested change
func Make(db *leveldb.DB) *Cache {
func Make(db *leveldb.DB) *Cache {
if db == nil {
panic("leveldb: nil *leveldb.DB passed to leveldb.Make")
}

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,61 @@
package leveldb
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +16
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()
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +44
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()
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +66
func BenchmarkLevelDBCacheMixed(b *testing.B) {
path := filepath.Join(b.TempDir(), "cache.db")
cache, err := leveldb.New(path)
require.NoError(b, err)
defer cache.Close()
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +89
func BenchmarkLevelDBCacheParallelMixed(b *testing.B) {
path := filepath.Join(b.TempDir(), "cache.db")
cache, err := leveldb.New(path)
require.NoError(b, err)
defer cache.Close()
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Jan 13, 2026

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.

Suggested change
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
github.com/golang/snappy v0.0.4 // indirect

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +14
// Cache is an implementation of httpcache.Cache with leveldb storage
type Cache struct {
db *leveldb.DB
}
Copy link

Copilot AI Jan 13, 2026

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.

Copilot uses AI. Check for mistakes.
@bbengfort bbengfort merged commit 04d5283 into main Jan 13, 2026
8 checks passed
@bbengfort bbengfort deleted the sc-36558 branch January 13, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants