github.com/maypok86/otter@v1.2.1/internal/s3fifo/policy_test.go (about) 1 // Copyright (c) 2023 Alexey Mayshev. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package s3fifo 16 17 import ( 18 "testing" 19 20 "github.com/maypok86/otter/internal/generated/node" 21 ) 22 23 func newNode(k int) node.Node[int, int] { 24 m := node.NewManager[int, int](node.Config{}) 25 n := m.Create(k, k, 0, 1) 26 return n 27 } 28 29 func TestPolicy_ReadAndWrite(t *testing.T) { 30 n := newNode(2) 31 p := NewPolicy[int, int](10) 32 p.Add(nil, n) 33 if !n.IsSmall() { 34 t.Fatalf("not valid node state: %+v", n) 35 } 36 } 37 38 func TestPolicy_OneHitWonders(t *testing.T) { 39 p := NewPolicy[int, int](10) 40 41 oneHitWonders := make([]node.Node[int, int], 0, 2) 42 for i := 0; i < cap(oneHitWonders); i++ { 43 oneHitWonders = append(oneHitWonders, newNode(i+1)) 44 } 45 46 popular := make([]node.Node[int, int], 0, 8) 47 for i := 0; i < cap(popular); i++ { 48 popular = append(popular, newNode(i+3)) 49 } 50 51 for _, n := range oneHitWonders { 52 p.Add(nil, n) 53 } 54 55 for _, n := range popular { 56 p.Add(nil, n) 57 } 58 59 p.Read(oneHitWonders) 60 for i := 0; i < 3; i++ { 61 p.Read(popular) 62 } 63 64 newNodes := make([]node.Node[int, int], 0, 11) 65 for i := 0; i < cap(newNodes); i++ { 66 newNodes = append(newNodes, newNode(i+12)) 67 } 68 69 for _, n := range newNodes { 70 p.Add(nil, n) 71 } 72 73 for _, n := range oneHitWonders { 74 if n.IsSmall() || n.IsMain() { 75 t.Fatalf("one hit wonder should be evicted: %+v", n) 76 } 77 } 78 79 for _, n := range popular { 80 if !n.IsMain() { 81 t.Fatalf("popular objects should be in main queue: %+v", n) 82 } 83 } 84 85 for _, n := range oneHitWonders { 86 p.Delete(n) 87 } 88 for _, n := range popular { 89 p.Delete(n) 90 } 91 for _, n := range newNodes { 92 p.Delete(n) 93 } 94 95 if p.small.cost+p.main.cost != 0 { 96 t.Fatalf("queues should be empty, but small size: %d, main size: %d", p.small.cost, p.main.cost) 97 } 98 } 99 100 func TestPolicy_Update(t *testing.T) { 101 p := NewPolicy[int, int](100) 102 103 n := newNode(1) 104 m := node.NewManager[int, int](node.Config{WithCost: true}) 105 n1 := m.Create(1, 1, 0, n.Cost()+8) 106 107 p.Add(nil, n) 108 p.Delete(n) 109 p.Add(nil, n1) 110 111 p.Read([]node.Node[int, int]{n1, n1}) 112 113 n2 := m.Create(2, 1, 0, 92) 114 deleted := p.Add(nil, n2) 115 116 if !n1.IsMain() { 117 t.Fatalf("updated node should be in main queue: %+v", n1) 118 } 119 120 if n2.IsSmall() || n2.IsMain() || len(deleted) != 1 || deleted[0] != n2 { 121 t.Fatalf("inserted node should be evicted: %+v", n2) 122 } 123 124 n3 := m.Create(1, 1, 0, 109) 125 p.Delete(n1) 126 deleted = p.Add(nil, n3) 127 if n3.IsSmall() || n3.IsMain() || len(deleted) != 1 || deleted[0] != n3 { 128 t.Fatalf("updated node should be evicted: %+v", n3) 129 } 130 }