diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index f5d6e96..9c7bc56 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: [ '1.13', '1.14', '1.15', '1.16', '1.17', '1.18' ] + go: [ '1.18', '1.19', '1.20', '1.21', '1.22' ] name: Go ${{ matrix.go }} sample steps: - uses: actions/checkout@v2 @@ -29,6 +29,9 @@ jobs: fail_ci_if_error: true verbose: true + - name: Run examples + run: make test.examples + - name: Run linter run: make lint diff --git a/Makefile b/Makefile index 06563ea..9553670 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,10 @@ help: test: go test -race -v -coverprofile=coverage.txt -covermode=atomic +#test.examples: @ Runs examples +test.examples: + go test -race -v ./examples + #bench: @ Runs performance tests bench: go test -bench=. diff --git a/examples/examples_test.go b/examples/examples_test.go new file mode 100644 index 0000000..c4c50c6 --- /dev/null +++ b/examples/examples_test.go @@ -0,0 +1,125 @@ +package main + +import ( + "fmt" + "time" + + "github.com/jahnestacado/tlru" +) + +var ( + entry1 = tlru.Entry[string, int]{Key: "entry-1", Value: 1} + entry2 = tlru.Entry[string, int]{Key: "entry-2", Value: 2} + entry3 = tlru.Entry[string, int]{Key: "entry-3", Value: 3} + entry4 = tlru.Entry[string, int]{Key: "entry-4", Value: 4} + entry5 = tlru.Entry[string, int]{Key: "entry-5", Value: 5} + + ttl = 2 * time.Millisecond +) + +func ExampleLRA() { + evictionChannel := make(chan tlru.EvictedEntry[string, int]) + config := tlru.Config[string, int]{ + MaxSize: 2, + TTL: ttl, + EvictionPolicy: tlru.LRA, + EvictionChannel: &evictionChannel, + GarbageCollectionInterval: ttl, + } + cache := tlru.New(config) + + go func() { + for { + evictedEntry := <-evictionChannel + fmt.Printf("Entry with key: '%s' has been evicted with reason: %s\n", evictedEntry.Key, evictedEntry.Reason.String()) + } + }() + + cache.Set(entry1.Key, entry1.Value) + time.Sleep(2 * ttl) + cache.Set(entry2.Key, entry2.Value) + cache.Set(entry3.Key, entry3.Value) + cache.Set(entry4.Key, entry4.Value) + cache.Delete(entry4.Key) + cache.Set(entry5.Key, entry5.Value) + + // Duplicate keys are not allowed in LRA + err := cache.Set(entry5.Key, entry5.Value) + if err != nil { + fmt.Println(err.Error()) + } + + fmt.Printf("Number of Keys in cache: %d\n", len(cache.Keys())) + fmt.Printf("Entry with key: 'entry-3' is in cache: %t\n", cache.Has(entry3.Key)) + fmt.Printf("Entry with key: 'entry-5' is in cache: %t\n", cache.Has(entry5.Key)) + + cache.Get(entry3.Key) + cachedEntry3 := cache.Get(entry3.Key) + fmt.Printf("Entry with key: '%s' has been accessed %d times\n", entry3.Key, cachedEntry3.Counter) + + cache.Get(entry5.Key) + cache.Get(entry5.Key) + cachedEntry5 := cache.Get(entry5.Key) + fmt.Printf("Entry with key: '%s' has been accessed %d times\n", entry5.Key, cachedEntry5.Counter) + + // Output: + // Entry with key: 'entry-1' has been evicted with reason: Expired + // Entry with key: 'entry-2' has been evicted with reason: Dropped + // Entry with key: 'entry-4' has been evicted with reason: Deleted + // tlru.Set: Key 'entry-5' already exist. Entry replacement is not allowed in LRA EvictionPolicy + // Number of Keys in cache: 2 + // Entry with key: 'entry-3' is in cache: true + // Entry with key: 'entry-5' is in cache: true + // Entry with key: 'entry-3' has been accessed 2 times + // Entry with key: 'entry-5' has been accessed 3 times +} + +func ExampleLRI() { + evictionChannel := make(chan tlru.EvictedEntry[string, int]) + config := tlru.Config[string, int]{ + MaxSize: 3, + TTL: ttl, + EvictionPolicy: tlru.LRI, + EvictionChannel: &evictionChannel, + GarbageCollectionInterval: ttl, + } + cache := tlru.New(config) + + go func() { + for { + evictedEntry := <-evictionChannel + fmt.Printf("Entry with key: '%s' has been evicted with reason: %s\n", evictedEntry.Key, evictedEntry.Reason.String()) + } + }() + + cache.Set(entry1.Key, entry1.Value) + time.Sleep(2 * ttl) + cache.Set(entry2.Key, entry2.Value) + cache.Set(entry3.Key, entry3.Value) + cache.Set(entry2.Key, entry2.Value) + cache.Set(entry4.Key, entry4.Value) + cache.Set(entry4.Key, entry4.Value) + cache.Set(entry5.Key, entry5.Value) + cache.Set(entry4.Key, entry4.Value) + + cache.Delete(entry5.Key) + + fmt.Printf("Number of Keys in cache: %d\n", len(cache.Keys())) + fmt.Printf("Entry with key: 'entry-2' is in cache: %t\n", cache.Has(entry2.Key)) + fmt.Printf("Entry with key: 'entry-4' is in cache: %t\n", cache.Has(entry4.Key)) + + cachedEntry2 := cache.Get(entry2.Key) + fmt.Printf("Entry with key: '%s' has been inserted %d times\n", entry2.Key, cachedEntry2.Counter) + cachedEntry4 := cache.Get(entry4.Key) + fmt.Printf("Entry with key: '%s' has been inserted %d times\n", entry4.Key, cachedEntry4.Counter) + + // Output: + // Entry with key: 'entry-1' has been evicted with reason: Expired + // Entry with key: 'entry-3' has been evicted with reason: Dropped + // Entry with key: 'entry-5' has been evicted with reason: Deleted + // Number of Keys in cache: 2 + // Entry with key: 'entry-2' is in cache: true + // Entry with key: 'entry-4' is in cache: true + // Entry with key: 'entry-2' has been inserted 2 times + // Entry with key: 'entry-4' has been inserted 3 times +} diff --git a/examples/lra/tlru_lra.go b/examples/lra/tlru_lra.go deleted file mode 100644 index 45faae7..0000000 --- a/examples/lra/tlru_lra.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "fmt" - "time" - - "github.com/jahnestacado/tlru" -) - -var ( - entry1 = tlru.Entry{Key: "entry-1", Value: 1} - entry2 = tlru.Entry{Key: "entry-2", Value: 2} - entry3 = tlru.Entry{Key: "entry-3", Value: 3} - entry4 = tlru.Entry{Key: "entry-4", Value: 4} - entry5 = tlru.Entry{Key: "entry-5", Value: 5} - - ttl = 2 * time.Millisecond -) - -func main() { - evictionChannel := make(chan tlru.EvictedEntry, 0) - config := tlru.Config{ - MaxSize: 2, - TTL: ttl, - EvictionPolicy: tlru.LRA, - EvictionChannel: &evictionChannel, - GarbageCollectionInterval: &ttl, - } - cache := tlru.New(config) - - go func() { - for { - evictedEntry := <-evictionChannel - fmt.Printf("Entry with key: '%s' has been evicted with reason: %s\n", evictedEntry.Key, evictedEntry.Reason.String()) - // Entry with key: 'entry-1' has been evicted with reason: Expired - // Entry with key: 'entry-2' has been evicted with reason: Dropped - // Entry with key: 'entry-4' has been evicted with reason: Deleted - } - }() - - cache.Set(entry1) - time.Sleep(2 * ttl) - cache.Set(entry2) - cache.Set(entry3) - cache.Set(entry4) - cache.Delete(entry4.Key) - cache.Set(entry5) - - // Duplicate keys are not allowed in LRA - err := cache.Set(entry5) - if err != nil { - fmt.Println(err.Error()) - // tlru.Set: Key 'entry-5' already exist. Entry replacement is not allowed in LRA EvictionPolicy - } - - keys := cache.Keys() - fmt.Printf("Keys in cache: %v\n", keys) - // Keys in cache: [key5 key3] (The key order is not guaranteed) - - cache.Get(entry3.Key) - cachedEntry3 := cache.Get(entry3.Key) - fmt.Printf("Entry with key: '%s' has been accessed %d times \n", entry3.Key, cachedEntry3.Counter) - // Entry with key: 'entry-3' has been accessed 2 times - - cache.Get(entry5.Key) - cache.Get(entry5.Key) - cachedEntry5 := cache.Get(entry5.Key) - fmt.Printf("Entry with key: '%s' has been accessed %d times \n", entry5.Key, cachedEntry5.Counter) - // Entry with key: 'entry-5' has been accessed 3 times -} diff --git a/examples/lri/tlru_lri.go b/examples/lri/tlru_lri.go deleted file mode 100644 index 347d035..0000000 --- a/examples/lri/tlru_lri.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "fmt" - "time" - - "github.com/jahnestacado/tlru" -) - -var ( - entry1 = tlru.Entry{Key: "entry-1", Value: 1} - entry2 = tlru.Entry{Key: "entry-2", Value: 2} - entry3 = tlru.Entry{Key: "entry-3", Value: 3} - entry4 = tlru.Entry{Key: "entry-4", Value: 4} - entry5 = tlru.Entry{Key: "entry-5", Value: 5} - - ttl = 2 * time.Millisecond -) - -func main() { - evictionChannel := make(chan tlru.EvictedEntry, 0) - config := tlru.Config{ - MaxSize: 3, - TTL: ttl, - EvictionPolicy: tlru.LRI, - EvictionChannel: &evictionChannel, - GarbageCollectionInterval: &ttl, - } - cache := tlru.New(config) - - go func() { - for { - evictedEntry := <-evictionChannel - fmt.Printf("Entry with key: '%s' has been evicted with reason: %s\n", evictedEntry.Key, evictedEntry.Reason.String()) - // Entry with key: 'entry-1' has been evicted with reason: Expired - // Entry with key: 'entry-3' has been evicted with reason: Dropped - // Entry with key: 'entry-5' has been evicted with reason: Deleted - } - }() - - cache.Set(entry1) - time.Sleep(2 * ttl) - cache.Set(entry2) - cache.Set(entry3) - cache.Set(entry2) - cache.Set(entry4) - cache.Set(entry4) - cache.Set(entry5) - cache.Set(entry4) - - cache.Delete(entry5.Key) - - keys := cache.Keys() - fmt.Printf("Keys in cache: %v\n", keys) - // Keys in cache: [entry-2 entry-4] (The key order is not guaranteed) - - cachedEntry2 := cache.Get(entry2.Key) - fmt.Printf("Entry with key: '%s' has been inserted %d times \n", entry2.Key, cachedEntry2.Counter) - // Entry with key: 'entry-2' has been inserted 2 times - cachedEntry4 := cache.Get(entry4.Key) - fmt.Printf("Entry with '%s' has been inserted %d times \n", entry4.Key, cachedEntry4.Counter) - // Entry with key: 'entry-4' has been inserted 3 times -}