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  }