github.com/safing/portbase@v0.19.5/database/interface_cache_test.go (about) 1 package database 2 3 import ( 4 "context" 5 "fmt" 6 "strconv" 7 "sync" 8 "testing" 9 ) 10 11 func benchmarkCacheWriting(b *testing.B, storageType string, cacheSize int, sampleSize int, delayWrites bool) { //nolint:gocognit,gocyclo,thelper 12 b.Run(fmt.Sprintf("CacheWriting_%s_%d_%d_%v", storageType, cacheSize, sampleSize, delayWrites), func(b *testing.B) { 13 // Setup Benchmark. 14 15 // Create database. 16 dbName := fmt.Sprintf("cache-w-benchmark-%s-%d-%d-%v", storageType, cacheSize, sampleSize, delayWrites) 17 _, err := Register(&Database{ 18 Name: dbName, 19 Description: fmt.Sprintf("Cache Benchmark Database for %s", storageType), 20 StorageType: storageType, 21 }) 22 if err != nil { 23 b.Fatal(err) 24 } 25 26 // Create benchmark interface. 27 options := &Options{ 28 Local: true, 29 Internal: true, 30 CacheSize: cacheSize, 31 } 32 if cacheSize > 0 && delayWrites { 33 options.DelayCachedWrites = dbName 34 } 35 db := NewInterface(options) 36 37 // Start 38 ctx, cancelCtx := context.WithCancel(context.Background()) 39 var wg sync.WaitGroup 40 if cacheSize > 0 && delayWrites { 41 wg.Add(1) 42 go func() { 43 err := db.DelayedCacheWriter(ctx) 44 if err != nil { 45 panic(err) 46 } 47 wg.Done() 48 }() 49 } 50 51 // Start Benchmark. 52 b.ResetTimer() 53 for i := 0; i < b.N; i++ { 54 testRecordID := i % sampleSize 55 r := NewExample( 56 dbName+":"+strconv.Itoa(testRecordID), 57 "A", 58 1, 59 ) 60 err = db.Put(r) 61 if err != nil { 62 b.Fatal(err) 63 } 64 } 65 66 // End cache writer and wait 67 cancelCtx() 68 wg.Wait() 69 }) 70 } 71 72 func benchmarkCacheReadWrite(b *testing.B, storageType string, cacheSize int, sampleSize int, delayWrites bool) { //nolint:gocognit,gocyclo,thelper 73 b.Run(fmt.Sprintf("CacheReadWrite_%s_%d_%d_%v", storageType, cacheSize, sampleSize, delayWrites), func(b *testing.B) { 74 // Setup Benchmark. 75 76 // Create database. 77 dbName := fmt.Sprintf("cache-rw-benchmark-%s-%d-%d-%v", storageType, cacheSize, sampleSize, delayWrites) 78 _, err := Register(&Database{ 79 Name: dbName, 80 Description: fmt.Sprintf("Cache Benchmark Database for %s", storageType), 81 StorageType: storageType, 82 }) 83 if err != nil { 84 b.Fatal(err) 85 } 86 87 // Create benchmark interface. 88 options := &Options{ 89 Local: true, 90 Internal: true, 91 CacheSize: cacheSize, 92 } 93 if cacheSize > 0 && delayWrites { 94 options.DelayCachedWrites = dbName 95 } 96 db := NewInterface(options) 97 98 // Start 99 ctx, cancelCtx := context.WithCancel(context.Background()) 100 var wg sync.WaitGroup 101 if cacheSize > 0 && delayWrites { 102 wg.Add(1) 103 go func() { 104 err := db.DelayedCacheWriter(ctx) 105 if err != nil { 106 panic(err) 107 } 108 wg.Done() 109 }() 110 } 111 112 // Start Benchmark. 113 b.ResetTimer() 114 writing := true 115 for i := 0; i < b.N; i++ { 116 testRecordID := i % sampleSize 117 key := dbName + ":" + strconv.Itoa(testRecordID) 118 119 if i > 0 && testRecordID == 0 { 120 writing = !writing // switch between reading and writing every samplesize 121 } 122 123 if writing { 124 r := NewExample(key, "A", 1) 125 err = db.Put(r) 126 } else { 127 _, err = db.Get(key) 128 } 129 if err != nil { 130 b.Fatal(err) 131 } 132 } 133 134 // End cache writer and wait 135 cancelCtx() 136 wg.Wait() 137 }) 138 } 139 140 func BenchmarkCache(b *testing.B) { 141 for _, storageType := range []string{"bbolt", "hashmap"} { 142 benchmarkCacheWriting(b, storageType, 32, 8, false) 143 benchmarkCacheWriting(b, storageType, 32, 8, true) 144 benchmarkCacheWriting(b, storageType, 32, 1024, false) 145 benchmarkCacheWriting(b, storageType, 32, 1024, true) 146 benchmarkCacheWriting(b, storageType, 512, 1024, false) 147 benchmarkCacheWriting(b, storageType, 512, 1024, true) 148 149 benchmarkCacheReadWrite(b, storageType, 32, 8, false) 150 benchmarkCacheReadWrite(b, storageType, 32, 8, true) 151 benchmarkCacheReadWrite(b, storageType, 32, 1024, false) 152 benchmarkCacheReadWrite(b, storageType, 32, 1024, true) 153 benchmarkCacheReadWrite(b, storageType, 512, 1024, false) 154 benchmarkCacheReadWrite(b, storageType, 512, 1024, true) 155 } 156 }