github.com/maypok86/otter@v1.2.1/internal/s3fifo/ghost.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 "github.com/dolthub/maphash" 19 "github.com/gammazero/deque" 20 21 "github.com/maypok86/otter/internal/generated/node" 22 ) 23 24 type ghost[K comparable, V any] struct { 25 q *deque.Deque[uint64] 26 m map[uint64]struct{} 27 main *main[K, V] 28 small *small[K, V] 29 hasher maphash.Hasher[K] 30 } 31 32 func newGhost[K comparable, V any](main *main[K, V]) *ghost[K, V] { 33 return &ghost[K, V]{ 34 q: deque.New[uint64](), 35 m: make(map[uint64]struct{}), 36 main: main, 37 hasher: maphash.NewHasher[K](), 38 } 39 } 40 41 func (g *ghost[K, V]) isGhost(n node.Node[K, V]) bool { 42 h := g.hasher.Hash(n.Key()) 43 _, ok := g.m[h] 44 return ok 45 } 46 47 func (g *ghost[K, V]) insert(deleted []node.Node[K, V], n node.Node[K, V]) []node.Node[K, V] { 48 deleted = append(deleted, n) 49 50 h := g.hasher.Hash(n.Key()) 51 52 if _, ok := g.m[h]; ok { 53 return deleted 54 } 55 56 maxLength := g.small.length() + g.main.length() 57 if maxLength == 0 { 58 return deleted 59 } 60 61 for g.q.Len() >= maxLength { 62 v := g.q.PopFront() 63 delete(g.m, v) 64 } 65 66 g.q.PushBack(h) 67 g.m[h] = struct{}{} 68 69 return deleted 70 } 71 72 func (g *ghost[K, V]) clear() { 73 g.q.Clear() 74 for k := range g.m { 75 delete(g.m, k) 76 } 77 }