github.com/fjl/memsize@v0.0.2/bitmap_test.go (about) 1 package memsize 2 3 import ( 4 "fmt" 5 "math/rand" 6 "testing" 7 ) 8 9 func TestBitmapBlock(t *testing.T) { 10 marks := map[uintptr]bool{ 11 10: true, 12 13: true, 13 44: true, 14 128: true, 15 129: true, 16 256: true, 17 700: true, 18 } 19 var b bmBlock 20 for i := range marks { 21 b.mark(i) 22 } 23 for i := uintptr(0); i < bmBlockRange; i++ { 24 if b.isMarked(i) && !marks[i] { 25 t.Fatalf("wrong mark at %d", i) 26 } 27 } 28 if count := b.count(0, bmBlockRange-1); count != len(marks) { 29 t.Fatalf("wrong onesCount: got %d, want %d", count, len(marks)) 30 } 31 } 32 33 func TestBitmapBlockCount(t *testing.T) { 34 var b bmBlock 35 // Mark addresses (90,250) 36 for i := 90; i < 250; i++ { 37 b.mark(uintptr(i)) 38 } 39 // Check counts. 40 tests := []struct { 41 start, end uintptr 42 want int 43 }{ 44 {start: 0, end: 0, want: 0}, 45 {start: 0, end: 10, want: 0}, 46 {start: 0, end: 250, want: 160}, 47 {start: 0, end: 240, want: 150}, 48 {start: 0, end: bmBlockRange - 1, want: 160}, 49 {start: 100, end: bmBlockRange - 1, want: 150}, 50 {start: 100, end: 110, want: 10}, 51 {start: 100, end: 250, want: 150}, 52 {start: 100, end: 211, want: 111}, 53 {start: 111, end: 211, want: 100}, 54 } 55 for _, test := range tests { 56 t.Run(fmt.Sprintf("%d-%d", test.start, test.end), func(t *testing.T) { 57 if c := b.count(test.start, test.end); c != test.want { 58 t.Errorf("wrong onesCountRange(%d, %d): got %d, want %d", test.start, test.end, c, test.want) 59 } 60 }) 61 } 62 } 63 64 func TestBitmapMarkRange(t *testing.T) { 65 N := 1000 66 67 // Generate random non-overlapping mark ranges. 68 var ( 69 r = rand.New(rand.NewSource(312321312)) 70 bm = newBitmap() 71 ranges = make(map[uintptr]uintptr) 72 addr uintptr 73 total uintptr // number of bytes marked 74 ) 75 for i := 0; i < N; i++ { 76 addr += uintptr(r.Intn(bmBlockRange)) 77 len := uintptr(r.Intn(40)) 78 total += len 79 ranges[addr] = len 80 bm.markRange(addr, len) 81 } 82 83 // Check all marks are set. 84 for start, len := range ranges { 85 for i := uintptr(0); i < len; i++ { 86 if !bm.isMarked(start + i) { 87 t.Fatalf("not marked at %d", start) 88 } 89 } 90 } 91 92 // Check total number of bits is reported correctly. 93 if c := bm.countRange(0, addr+ranges[addr]); c != total { 94 t.Errorf("countRange(0, %d) returned %d, want %d", addr, c, total) 95 } 96 97 // Probe random addresses. 98 for i := 0; i < N; i++ { 99 addr := uintptr(r.Uint64()) 100 marked := false 101 for start, len := range ranges { 102 if addr >= start && addr < start+len { 103 marked = true 104 break 105 } 106 } 107 if bm.isMarked(addr) && !marked { 108 t.Fatalf("extra mark at %d", addr) 109 } 110 } 111 } 112 113 func BenchmarkBitmapMarkRange(b *testing.B) { 114 var addrs [2048]uintptr 115 r := rand.New(rand.NewSource(423098209802)) 116 for i := range addrs { 117 addrs[i] = uintptr(r.Uint64()) 118 } 119 120 doit := func(b *testing.B, rlen int) { 121 bm := newBitmap() 122 for i := 0; i < b.N; i++ { 123 addr := addrs[i%len(addrs)] 124 bm.markRange(addr, uintptr(rlen)) 125 } 126 } 127 for rlen := 1; rlen <= 4096; rlen *= 8 { 128 b.Run(fmt.Sprintf("%d", rlen), func(b *testing.B) { doit(b, rlen) }) 129 } 130 }