-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
revert LRUEjector and remove random ejection fallback
- Loading branch information
Tarak Ben Youssef
committed
Jul 12, 2023
1 parent
67b4390
commit 1f1a341
Showing
2 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
package stdmap | ||
|
||
import ( | ||
crand "crypto/rand" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/onflow/flow-go/model/flow" | ||
"github.com/onflow/flow-go/utils/unittest" | ||
) | ||
|
||
// TestLRUEjector_Track evaluates that tracking a new item adds the item to the ejector table. | ||
func TestLRUEjector_Track(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
// ejector's table should be empty | ||
assert.Len(t, ejector.table, 0) | ||
|
||
// sequence number of ejector should initially be zero | ||
assert.Equal(t, ejector.seqNum, uint64(0)) | ||
|
||
// creates adds an item to the ejector | ||
item := flow.Identifier{0x00} | ||
ejector.Track(item) | ||
|
||
// size of ejector's table should be one | ||
// which indicates that ejector is tracking the item | ||
assert.Len(t, ejector.table, 1) | ||
|
||
// item should reside in the ejector's table | ||
_, ok := ejector.table[item] | ||
assert.True(t, ok) | ||
|
||
// sequence number of ejector should be increased by one | ||
assert.Equal(t, ejector.seqNum, uint64(1)) | ||
} | ||
|
||
// TestLRUEjector_Track_Duplicate evaluates that tracking a duplicate item | ||
// does not change the internal state of the ejector. | ||
func TestLRUEjector_Track_Duplicate(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates adds an item to the ejector | ||
item := flow.Identifier{0x00} | ||
ejector.Track(item) | ||
|
||
// size of ejector's table should be one | ||
// which indicates that ejector is tracking the item | ||
assert.Len(t, ejector.table, 1) | ||
|
||
// item should reside in the ejector's table | ||
_, ok := ejector.table[item] | ||
assert.True(t, ok) | ||
|
||
// sequence number of ejector should be increased by one | ||
assert.Equal(t, ejector.seqNum, uint64(1)) | ||
|
||
// adds the duplicate item | ||
ejector.Track(item) | ||
|
||
// internal state of the ejector should be unchaged | ||
assert.Len(t, ejector.table, 1) | ||
assert.Equal(t, ejector.seqNum, uint64(1)) | ||
_, ok = ejector.table[item] | ||
assert.True(t, ok) | ||
} | ||
|
||
// TestLRUEjector_Track_Many evaluates that tracking many items | ||
// changes the state of ejector properly, i.e., items reside on the | ||
// memory, and sequence number changed accordingly. | ||
func TestLRUEjector_Track_Many(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates and tracks 100 items | ||
size := 100 | ||
items := flow.IdentifierList{} | ||
for i := 0; i < size; i++ { | ||
var id flow.Identifier | ||
_, _ = crand.Read(id[:]) | ||
ejector.Track(id) | ||
items = append(items, id) | ||
} | ||
|
||
// size of ejector's table should be 100 | ||
assert.Len(t, ejector.table, size) | ||
|
||
// all items should reside in the ejector's table | ||
for _, id := range items { | ||
_, ok := ejector.table[id] | ||
require.True(t, ok) | ||
} | ||
|
||
// sequence number of ejector should be increased by size | ||
assert.Equal(t, ejector.seqNum, uint64(size)) | ||
} | ||
|
||
// TestLRUEjector_Untrack_One evaluates that untracking an existing item | ||
// removes it from the ejector state and changes the state accordingly. | ||
func TestLRUEjector_Untrack_One(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates adds an item to the ejector | ||
item := flow.Identifier{0x00} | ||
ejector.Track(item) | ||
|
||
// size of ejector's table should be one | ||
// which indicates that ejector is tracking the item | ||
assert.Len(t, ejector.table, 1) | ||
|
||
// item should reside in the ejector's table | ||
_, ok := ejector.table[item] | ||
assert.True(t, ok) | ||
|
||
// sequence number of ejector should be increased by one | ||
assert.Equal(t, ejector.seqNum, uint64(1)) | ||
|
||
// untracks the item | ||
ejector.Untrack(item) | ||
|
||
// internal state of the ejector should be changed | ||
assert.Len(t, ejector.table, 0) | ||
|
||
// sequence number should not be changed | ||
assert.Equal(t, ejector.seqNum, uint64(1)) | ||
|
||
// item should no longer reside on internal state of ejector | ||
_, ok = ejector.table[item] | ||
assert.False(t, ok) | ||
} | ||
|
||
// TestLRUEjector_Untrack_Duplicate evaluates that untracking an item twice | ||
// removes it from the ejector state only once and changes the state safely. | ||
func TestLRUEjector_Untrack_Duplicate(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates and adds two items to the ejector | ||
item1 := flow.Identifier{0x00} | ||
item2 := flow.Identifier{0x01} | ||
ejector.Track(item1) | ||
ejector.Track(item2) | ||
|
||
// size of ejector's table should be two | ||
// which indicates that ejector is tracking the items | ||
assert.Len(t, ejector.table, 2) | ||
|
||
// items should reside in the ejector's table | ||
_, ok := ejector.table[item1] | ||
assert.True(t, ok) | ||
_, ok = ejector.table[item2] | ||
assert.True(t, ok) | ||
|
||
// sequence number of ejector should be increased by two | ||
assert.Equal(t, ejector.seqNum, uint64(2)) | ||
|
||
// untracks the item twice | ||
ejector.Untrack(item1) | ||
ejector.Untrack(item1) | ||
|
||
// internal state of the ejector should be changed | ||
assert.Len(t, ejector.table, 1) | ||
|
||
// sequence number should not be changed | ||
assert.Equal(t, ejector.seqNum, uint64(2)) | ||
|
||
// double untracking should only affect the untracked item1 | ||
_, ok = ejector.table[item1] | ||
assert.False(t, ok) | ||
|
||
// item 2 should still reside in the memory | ||
_, ok = ejector.table[item2] | ||
assert.True(t, ok) | ||
} | ||
|
||
// TestLRUEjector_UntrackEject evaluates that untracking the next ejectable item | ||
// properly changes the next ejectable item in the ejector. | ||
func TestLRUEjector_UntrackEject(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates and tracks 100 items | ||
size := 100 | ||
backEnd := NewBackend() | ||
|
||
items := make([]flow.Identifier, size) | ||
|
||
for i := 0; i < size; i++ { | ||
mockEntity := unittest.MockEntityFixture() | ||
require.True(t, backEnd.Add(mockEntity)) | ||
|
||
id := mockEntity.ID() | ||
ejector.Track(id) | ||
items[i] = id | ||
} | ||
|
||
// untracks the oldest item | ||
ejector.Untrack(items[0]) | ||
|
||
// next ejectable item should be the second oldest item | ||
id := ejector.Eject(backEnd) | ||
assert.Equal(t, id, items[1]) | ||
} | ||
|
||
// TestLRUEjector_EjectAll adds many item to the ejector and then ejects them | ||
// all one by one and evaluates an LRU ejection behavior. | ||
func TestLRUEjector_EjectAll(t *testing.T) { | ||
ejector := NewLRUEjector() | ||
|
||
// creates and tracks 100 items | ||
size := 100 | ||
backEnd := NewBackend() | ||
|
||
items := make([]flow.Identifier, size) | ||
|
||
for i := 0; i < size; i++ { | ||
mockEntity := unittest.MockEntityFixture() | ||
require.True(t, backEnd.Add(mockEntity)) | ||
|
||
id := mockEntity.ID() | ||
ejector.Track(id) | ||
items[i] = id | ||
} | ||
|
||
require.Equal(t, uint(size), backEnd.Size()) | ||
|
||
// ejects one by one | ||
for i := 0; i < size; i++ { | ||
id := ejector.Eject(backEnd) | ||
require.Equal(t, id, items[i]) | ||
} | ||
} |