Skip to content

Commit

Permalink
Added other and ttl for negatives in the ctor
Browse files Browse the repository at this point in the history
  • Loading branch information
lrleon committed Nov 23, 2023
1 parent 2d61a6b commit 6fce91f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
17 changes: 7 additions & 10 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,11 @@ func (cache *CacheDriver[T, K]) Touch(keyVal T) error {

type Options[K, T any] func(*CacheDriver[K, T])

func WithTTLForNegative[K, T any](ttl time.Duration) Options[K, T] {
return func(cache *CacheDriver[K, T]) {
cache.ttlForNegative = ttl
}
}

func New[K any, T any](
capacity int,
capFactor float64,
ttl time.Duration,
ttlForNegative time.Duration,
processor ProcessorI[K, T],
options ...Options[K, T],
) *CacheDriver[K, T] {
Expand All @@ -227,7 +222,7 @@ func New[K any, T any](
extendedCapacity: int(extendedCapacity),
numEntries: 0,
ttl: ttl,
ttlForNegative: ttl,
ttlForNegative: ttlForNegative,
table: make(map[string]*CacheEntry[T], int(extendedCapacity)),
processor: processor,
compressor: lz4Compressor{},
Expand Down Expand Up @@ -295,12 +290,13 @@ func NewWithCompression[T any, K any](
capacity int,
capFactor float64,
ttl time.Duration,
ttlForNegative time.Duration,
processor ProcessorI[T, K],
compressor TransformerI[K],
options ...Options[T, K],
) (cache *CacheDriver[T, K]) {

cache = New(capacity, capFactor, ttl, processor, options...)
cache = New(capacity, capFactor, ttl, ttlForNegative, processor, options...)
if cache != nil {
cache.toCompress = true
cache.transformer = compressor
Expand Down Expand Up @@ -417,7 +413,8 @@ func (cache *CacheDriver[T, K]) allocateEntry(
// immediately returns the cached entry. If the request is the first, then it blocks until the result is
// ready. If the request is not the first but the result is not still ready, then it blocks
// until the result is ready
func (cache *CacheDriver[T, K]) RetrieveFromCacheOrCompute(request T) (K, *models.RequestError) {
func (cache *CacheDriver[T, K]) RetrieveFromCacheOrCompute(request T,
other ...interface{}) (K, *models.RequestError) {

var requestError *models.RequestError
var zeroK K
Expand Down Expand Up @@ -507,7 +504,7 @@ func (cache *CacheDriver[T, K]) RetrieveFromCacheOrCompute(request T) (K, *model
entry.lock.Lock() // other requests will wait for until postProcessedResponse is gotten
defer entry.lock.Unlock()

retVal, requestError := cache.processor.CacheMissSolver(request)
retVal, requestError := cache.processor.CacheMissSolver(request, other...)
if requestError != nil {
switch requestError.Code {
case Status4xx, Status4xxCached:
Expand Down
36 changes: 21 additions & 15 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ func (p *MyProcessor) ToMapKey(entry *RequestEntry) (string, error) {
return string(b), nil
}

func (p *MyProcessor) CacheMissSolver(request *RequestEntry) ([]byte, *models.RequestError) {
func (p *MyProcessor) CacheMissSolver(request *RequestEntry,
other ...interface{}) ([]byte, *models.RequestError) {

entry := request
urequest := &URequest{
Expand Down Expand Up @@ -76,6 +77,7 @@ func TestNew(t *testing.T) {
100,
.4,
time.Minute,
time.Minute,
mp,
)

Expand All @@ -91,11 +93,11 @@ func TestBadFactor(t *testing.T) {

mp := &MyProcessor{}
assert.Panics(t, func() {
New[*RequestEntry, []byte](100, .099, time.Minute, mp)
New[*RequestEntry, []byte](100, .099, time.Minute, time.Minute, mp)
})

assert.Panics(t, func() {
New[*RequestEntry, []byte](100, 3.00001, time.Minute, mp)
New[*RequestEntry, []byte](100, 3.00001, time.Minute, time.Minute, mp)
})
}

Expand All @@ -114,7 +116,8 @@ func TestWithCompress(t *testing.T) {
compressedResponse := []byte("compressed")
compressor.EXPECT().Compress([]byte(keats)).Return(compressedResponse, nil).Times(1)

cache := NewWithCompression[any, any](Capacity, .4, 3*time.Minute, processor, transformer)
cache := NewWithCompression[any, any](Capacity, .4, 3*time.Minute,
20*time.Second, processor, transformer)
cache.compressor = compressor

val, ptr := cache.RetrieveFromCacheOrCompute("Keats")
Expand Down Expand Up @@ -147,7 +150,7 @@ func createCacheWithCapEntriesInside(
processor *mocks.ProcessorI[*RequestEntry, *RequestEntry],
) (*CacheDriver[*RequestEntry, *RequestEntry], map[*RequestEntry]bool) {

cache := New[*RequestEntry, *RequestEntry](capacity, .4, TTL, processor)
cache := New[*RequestEntry, *RequestEntry](capacity, .4, TTL, TTL, processor)

requestTbl := make(map[*RequestEntry]bool)
for i := 0; i < capacity; i++ {
Expand All @@ -168,7 +171,8 @@ func createCompressedCacheWithCapEntriesInside(
) (*CacheDriver[*RequestEntry, *RequestEntry], map[*RequestEntry]bool) {

transformer := &DefaultTransformer[*RequestEntry]{}
cache := NewWithCompression[*RequestEntry, *RequestEntry](capacity, .4, TTL, processor, transformer)
cache := NewWithCompression[*RequestEntry, *RequestEntry](capacity, .4, TTL, TTL,
processor, transformer)

requestTbl := make(map[*RequestEntry]bool)
for i := 0; i < capacity; i++ {
Expand Down Expand Up @@ -239,7 +243,7 @@ func TestCacheDriver_testTTL(t *testing.T) {

ttl := 3 * time.Second
processor := mocks.NewProcessorI[any, any](t)
cache := New[any, any](Capacity, .4, ttl, processor)
cache := New[any, any](Capacity, .4, ttl, ttl, processor)

request := &RequestEntry{
N: 10,
Expand Down Expand Up @@ -383,7 +387,7 @@ func TestCacheDriver_Clean(t *testing.T) {

func TestCacheDriver_HitCost(t *testing.T) {
processor := &MyProcessor{}
cache := New[*RequestEntry, []byte](Capacity, .4, TTL, processor)
cache := New[*RequestEntry, []byte](Capacity, .4, TTL, TTL, processor)

requestTbl := make(map[*RequestEntry]bool)
for i := 0; i < Capacity; i++ {
Expand Down Expand Up @@ -422,6 +426,7 @@ func TestConcurrency(t *testing.T) {
SuperCap,
.3,
30*time.Second,
30*time.Second,
myProccessor,
)

Expand Down Expand Up @@ -486,6 +491,7 @@ func TestConcurrencyAndCompress(t *testing.T) {
SuperCap,
.3,
30*time.Second,
30*time.Second,
myProccessor,
defaultTransformer,
)
Expand Down Expand Up @@ -633,7 +639,7 @@ func TestCacheDriver_Touch(t *testing.T) {
// test the StoreValue method first insert values in the cache
func TestCacheDriver_StoreOrUpdateValue(t *testing.T) {
processor := mocks.NewProcessorI[int, int](t)
cache := New[int, int](Capacity, .4, TTL, processor)
cache := New[int, int](Capacity, .4, TTL, TTL, processor)

elements := Capacity
for i := 0; i < elements; i++ {
Expand All @@ -656,7 +662,7 @@ func TestCacheDriver_StoreOrUpdateValue(t *testing.T) {

func TestCacheDriver_StoreValueConcurrentInsert(t *testing.T) {
processor := mocks.NewProcessorI[int, int](t)
cache := New[int, int](Capacity, .4, TTL, processor)
cache := New[int, int](Capacity, .4, TTL, TTL, processor)

elements := Capacity
goroutines := 5
Expand Down Expand Up @@ -687,7 +693,7 @@ func TestCacheDriver_StoreValueConcurrentInsert(t *testing.T) {
// test retrieve value
func TestCacheDriver_RetrieveValue(t *testing.T) {
processor := mocks.NewProcessorI[int, int](t)
cache := New[int, int](Capacity, .4, TTL, processor)
cache := New[int, int](Capacity, .4, TTL, TTL, processor)

elements := Capacity
for i := 0; i < elements; i++ {
Expand All @@ -714,8 +720,8 @@ func TestTTLForNegative(t *testing.T) {
Capacity,
.4,
2*time.Second,
time.Second,
processor,
WithTTLForNegative[*RequestEntry, *RequestEntry](1*time.Second),
)

//Add a negative entry
Expand Down Expand Up @@ -794,7 +800,7 @@ func BenchmarkInsertDynamic(b *testing.B) {

func benchInsert(b *testing.B, seed int64) {

cache := New[Adder, int](Capacity, 0.5, TTL, &BenchProcessor{})
cache := New[Adder, int](Capacity, 0.5, TTL, TTL, &BenchProcessor{})
rand.Seed(seed)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand All @@ -805,7 +811,6 @@ func benchInsert(b *testing.B, seed int64) {
_, _ = cache.RetrieveFromCacheOrCompute(adder)
}
}

}

func createRandomArray(seed int64, size int) []Adder {
Expand All @@ -820,9 +825,10 @@ func createRandomArray(seed int64, size int) []Adder {
}

func benchInsertAvalanche(b *testing.B, seed int64) {

var size int = 1e3
arr := createRandomArray(seed, size)
cache := New[Adder, int](Capacity, 0.5, TTL, &BenchProcessor{})
cache := New[Adder, int](Capacity, 0.5, TTL, TTL, &BenchProcessor{})
rand.Seed(seed)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand Down
2 changes: 1 addition & 1 deletion interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
//go:generate mockery --name ProcessorI --with-expecter=true --filename=processor_mock.go
type ProcessorI[K, T any] interface {
ToMapKey(K) (string, error)
CacheMissSolver(K) (T, *models.RequestError) //we will leave the pre process logic for this function
CacheMissSolver(K, ...interface{}) (T, *models.RequestError) //we will leave the pre process logic for this function
}

// CompressorI is the interface that wraps the basic Compress and Decompress methods.
Expand Down

0 comments on commit 6fce91f

Please sign in to comment.