Golang bytes Index函数解析

func Index(s, sep []byte) int {
	n := len(sep)
	switch {
	case n == 0:
		return 0
	case n == 1:
		return IndexByte(s, sep[0])
	case n == len(s):
		if Equal(sep, s) {
			return 0
		}
		return -1
	case n > len(s):
		return -1
	case n <= bytealg.MaxLen:
		// Use brute force when s and sep both are small
		if len(s) <= bytealg.MaxBruteForce {
			return bytealg.Index(s, sep)
		}
		c0 := sep[0]
		c1 := sep[1]
		i := 0
		t := len(s) - n + 1
		fails := 0
		for i < t {
			if s[i] != c0 {
				// IndexByte is faster than bytealg.Index, so use it as long as
				// we're not getting lots of false positives.
				o := IndexByte(s[i:t], c0)
				if o < 0 {
					return -1
				}
				i += o
			}
			if s[i+1] == c1 && Equal(s[i:i+n], sep) {
				return i
			}
			fails++
			i++
			// Switch to bytealg.Index when IndexByte produces too many false positives.
			if fails > bytealg.Cutover(i) {
				r := bytealg.Index(s[i:], sep)
				if r >= 0 {
					return r + i
				}
				return -1
			}
		}
		return -1
	}
	c0 := sep[0]
	c1 := sep[1]
	i := 0
	fails := 0
	t := len(s) - n + 1
	for i < t {
		if s[i] != c0 {
			o := IndexByte(s[i:t], c0)
			if o < 0 {
				break
			}
			i += o
		}
		if s[i+1] == c1 && Equal(s[i:i+n], sep) {
			return i
		}
		i++
		fails++
		if fails >= 4+i>>4 && i < t {
			// Give up on IndexByte, it isn't skipping ahead
			// far enough to be better than Rabin-Karp.
			// Experiments (using IndexPeriodic) suggest
			// the cutover is about 16 byte skips.
			// TODO: if large prefixes of sep are matching
			// we should cutover at even larger average skips,
			// because Equal becomes that much more expensive.
			// This code does not take that effect into account.
			j := indexRabinKarp(s[i:], sep)
			if j < 0 {
				return -1
			}
			return i + j
		}
	}
	return -1
}

Index 函数解析

计算子byte长度 n

n == 0

返回0.(这里表示空[]byte包含于任意[]byte类型的slice)

n == 1

子byte只有一个byte,可以通过IndexByte进行校验包含关系,IndexByte是通过bytealg包中的IndexByte来实现的

n == len(s)

子byte和父byte长度相等,通过Equal函数进行字符串是否相同的比较

n > len(s)

子byte长度大于父byte长度,返回-1(即不包含)

n <= bytealg.MaxLen

子byte长度小于Index函数子串可搜索的最大长度

父串长度<=最大暴力破解长度(不知道咋翻译),返回bytealg.Index查询结果

父串长度>最大暴力破解长度,首页铆定到和子串第一个byte相同的位置,比较铆定第二位和子串第二位是否相等,相等则比较从铆定位置长度为子串长度的父串与子串是否相等,相等返回铆定位置。不相等错误次数fails累加。铆定位置累加i++,如果错误次数多过bytealg.Cutover的限制,使用bytealg.Index进行查询。

上述过程没有符合条件的,当错误次数fails >= 4+i >> 4 && i < t时,使用RabinKarp算法进行子串的查找。

你可能感兴趣的:(Golang)