coocood/freecache

Items are dropped from the cache but are not represented in `OverwriteCount` or `EvacuateCount`

thesilentg opened this issue · 2 comments

In this example, 60 million distinct keys get written into the cache. Set returns a non-nil error for all 60 million writes. However, at the end of all of the writes, there are only ~32 million items in the cache. Both OverwriteCount() and EvacuateCount() still report 0 items. To validate that the cache actually is missing items, we call Get for each key. This shows that ~27 million items are missing. My understanding is that if n distinct keys are written into the cache, then EntryCount() + OverwriteCount() + EvacuateCount() + ExpiredCount() should equal n. Is this correct? Why are the ~27 million items not represented in OverwriteCount() or EvacuateCount()?

Code below:

	cache := freecache.NewCache( 1024 * 1024 * 1024)

	for i := 0; i < 60000000; i ++ {
		err := cache.Set([]byte(strconv.Itoa(i)), []byte("A"), 0)
		if err != nil {
			log.Fatal(err)
		}
	}

	fmt.Printf("Items in cache %d\n", cache.EntryCount())
	fmt.Printf("Items overwritten %d\n", cache.OverwriteCount())
	fmt.Printf("Items evacuated %d\n", cache.EvacuateCount())
	fmt.Printf("Items expired %d\n\n", cache.ExpiredCount())

	missingItems := 0
	for i := 0; i < 60000000; i ++ {
		res, err := cache.Get([]byte(strconv.Itoa(i)))
		if err == freecache.ErrNotFound || (err == nil && string(res) != "A") {
			missingItems ++
		} else if err != nil {
			log.Fatal(err)
		}
	}

	fmt.Printf("Items in cache %d\n", cache.EntryCount())
	fmt.Printf("Items overwritten %d\n", cache.OverwriteCount())
	fmt.Printf("Items evacuated %d\n", cache.EvacuateCount())
	fmt.Printf("Items expired %d\n", cache.ExpiredCount())
	fmt.Printf("Items missing %d\n", missingItems)

Output:

Items in cache 32537600
Items overwritten 0
Items evacuated 0
Items expired 0

Items in cache 32537600
Items overwritten 0
Items evacuated 0
Items expired 0
Items missing 27462400

Great. Thanks for the quick fix!