github.com/charlievieth/fastwalk@v1.0.3/entry_filter_unix_test.go (about) 1 //go:build (linux || darwin || freebsd || openbsd || netbsd || !windows) && !appengine 2 // +build linux darwin freebsd openbsd netbsd !windows 3 // +build !appengine 4 5 package fastwalk 6 7 import ( 8 "math/rand" 9 "runtime" 10 "sync" 11 "testing" 12 "time" 13 ) 14 15 type devIno struct { 16 Dev, Ino uint64 17 } 18 19 func generateDevIno(rr *rand.Rand, ndev, size int) []devIno { 20 devs := make([]uint64, ndev) 21 for i := range devs { 22 devs[i] = rr.Uint64() 23 } 24 pairs := make([]devIno, size) 25 seen := make(map[devIno]struct{}, len(pairs)) 26 for i := range pairs { 27 for { 28 di := devIno{ 29 Dev: devs[rr.Intn(len(devs))], 30 Ino: rr.Uint64(), 31 } 32 if _, ok := seen[di]; !ok { 33 pairs[i] = di 34 seen[di] = struct{}{} 35 break 36 } 37 } 38 } 39 rr.Shuffle(len(pairs), func(i, j int) { 40 pairs[i], pairs[j] = pairs[j], pairs[i] 41 }) 42 return pairs 43 } 44 45 func TestEntryFilter_Unix(t *testing.T) { 46 rr := rand.New(rand.NewSource(1)) 47 pairs := generateDevIno(rr, 2, 100) 48 49 x := NewEntryFilter() 50 for _, p := range pairs { 51 if x.seen(p.Dev, p.Ino) { 52 t.Errorf("duplicate: Dev: %d Ino: %d", p.Dev, p.Ino) 53 } 54 } 55 for _, p := range pairs { 56 if !x.seen(p.Dev, p.Ino) { 57 t.Errorf("wat: Dev: %d Ino: %d", p.Dev, p.Ino) 58 } 59 } 60 } 61 62 func TestEntryFilter_Unix_Parallel(t *testing.T) { 63 if testing.Short() { 64 t.Skip("Short test") 65 } 66 wg := new(sync.WaitGroup) 67 ready := new(sync.WaitGroup) 68 start := make(chan struct{}) 69 x := NewEntryFilter() 70 71 numWorkers := runtime.NumCPU() * 2 72 if numWorkers < 2 { 73 numWorkers = 2 74 } 75 if numWorkers > 8 { 76 numWorkers = 8 77 } 78 79 rr := rand.New(rand.NewSource(time.Now().UnixNano())) 80 pairs := generateDevIno(rr, 2, numWorkers*8192) 81 82 for i := 0; i < numWorkers; i++ { 83 wg.Add(1) 84 ready.Add(1) 85 go func(i int, pairs []devIno) { 86 defer wg.Done() 87 ready.Done() 88 <-start 89 for _, p := range pairs { 90 if x.seen(p.Dev, p.Ino) { 91 t.Errorf("%d: unseen dev/ino: Dev: %d Ino: %d", i, p.Dev, p.Ino) 92 return 93 } 94 } 95 for _, p := range pairs { 96 if !x.seen(p.Dev, p.Ino) { 97 t.Errorf("%d: missed seen dev/ino: Dev: %d Ino: %d", i, p.Dev, p.Ino) 98 return 99 } 100 } 101 }(i, pairs[i*numWorkers:(i+1)*numWorkers]) 102 } 103 104 ready.Wait() 105 close(start) 106 wg.Wait() 107 } 108 109 func BenchmarkEntryFilter_Unix(b *testing.B) { 110 if testing.Short() { 111 b.Skip("Skipping: short test") 112 } 113 rr := rand.New(rand.NewSource(1)) 114 pairs := generateDevIno(rr, 2, 8192) 115 x := NewEntryFilter() 116 117 for _, p := range pairs { 118 x.seen(p.Dev, p.Ino) 119 } 120 if len(pairs) != 8192 { 121 panic("nope!") 122 } 123 124 b.ResetTimer() 125 b.Run("Sequential", func(b *testing.B) { 126 for i := 0; i < b.N; i++ { 127 p := pairs[i%8192] 128 x.seen(p.Dev, p.Ino) 129 } 130 }) 131 132 b.Run("Parallel", func(b *testing.B) { 133 b.RunParallel(func(pb *testing.PB) { 134 for i := 0; pb.Next(); i++ { 135 p := pairs[i%8192] 136 x.seen(p.Dev, p.Ino) 137 } 138 }) 139 }) 140 }