github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/sentinels/linear.go (about) 1 package sentinels 2 3 import "unsafe" 4 5 func SearchBasic(items []int, elem int) int { 6 for i, v := range items { 7 if v == elem { 8 return i 9 } 10 } 11 return len(items) 12 } 13 14 // requires -gcflags="-B" to be effective 15 func SearchBreak(items []int, elem int) (i int) { 16 for ; i < len(items); i++ { 17 if items[i] == elem { 18 break 19 } 20 } 21 return i 22 } 23 24 // requires -gcflags="-B" to be effective 25 func SearchSentinel(items []int, elem int) (i int) { 26 var last int 27 last, items[len(items)-1] = items[len(items)-1], elem 28 for items[i] != elem { 29 i++ 30 } 31 if i+1 == len(items) && last != elem { 32 i++ 33 } 34 items[len(items)-1] = last 35 return i 36 } 37 38 func SearchUnsafe(items []int, elem int) (i int) { 39 var last int 40 last, items[len(items)-1] = items[len(items)-1], elem 41 42 p := unsafe.Pointer(&items[0]) 43 for *(*int)(p) != elem { 44 p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(elem)) 45 } 46 i = int((uintptr(p) - uintptr(unsafe.Pointer(&items[0]))) / unsafe.Sizeof(elem)) 47 if i+1 == len(items) && last != elem { 48 i++ 49 } 50 items[len(items)-1] = last 51 return i 52 }