Example #1
0
// key顺序扫描,常用于数据导出、附近搜索
// 返回的key是面向用户的key,而非内部结构的raw_key
func (l *LevelRedis) KeyEnumerate(seek []byte, direction IterDirection, fn func(i int, key, keytype, value []byte, quit *bool)) {
	var iter *gorocks.Iterator
	if l.snap != nil {
		iter = l.db.NewIterator(l.ro)
	} else {
		ro := gorocks.NewReadOptions()
		ro.SetFillCache(false)
		defer ro.Close()
		iter = l.db.NewIterator(ro)
	}
	defer iter.Close()

	minkey := joinStringBytes(KEY_PREFIX, SEP_LEFT, string(seek))
	maxkey := []byte{MAXBYTE}
	prefix := joinStringBytes(KEY_PREFIX, SEP_LEFT)
	l.Enumerate(iter, minkey, maxkey, direction, func(i int, key, value []byte, quit *bool) {
		if !bytes.HasPrefix(key, prefix) {
			*quit = true
			return
		}
		left := bytes.Index(key, []byte(SEP_LEFT))
		right := bytes.LastIndex(key, []byte(SEP_RIGHT))
		if left == -1 || right == -1 {
			return // just skip
		}
		fn(i, key[left+1:right], key[right+1:], value, quit)
	})
}
Example #2
0
func (l *LevelRedis) RangeEnumerate(min, max []byte, direction IterDirection, fn func(i int, key, value []byte, quit *bool)) {
	var iter *gorocks.Iterator
	if l.snap != nil {
		iter = l.db.NewIterator(l.ro)
	} else {
		ro := gorocks.NewReadOptions()
		ro.SetFillCache(false)
		defer ro.Close()
		iter = l.db.NewIterator(ro)
	}
	defer iter.Close()
	l.Enumerate(iter, min, max, direction, fn)
}
Example #3
0
// 范围扫描
func (l *LevelRedis) Enumerate(iter *gorocks.Iterator, min, max []byte, direction IterDirection, fn func(i int, key, value []byte, quit *bool)) {
	l.incrCounter("enum")
	found := false
	if direction == IterBackward {
		if len(max) == 0 {
			iter.SeekToLast()
		} else {
			iter.Seek(max)
		}
	} else {
		if len(min) == 0 {
			iter.SeekToFirst()
		} else {
			iter.Seek(min)
		}

	}
	found = iter.Valid()
	if !found {
		return
	}

	i := -1
	// 范围判断
	if found && between(iter.Key(), min, max) {
		i++
		quit := false
		fn(i, copyBytes(iter.Key()), copyBytes(iter.Value()), &quit)
		if quit {
			return
		}
	}
	for {
		found = false
		if direction == IterBackward {
			iter.Prev()
		} else {
			iter.Next()
		}
		found = iter.Valid()
		if found && between(iter.Key(), min, max) {
			i++
			quit := false
			fn(i, copyBytes(iter.Key()), copyBytes(iter.Value()), &quit)
			if quit {
				return
			}
		} else {
			break
		}
	}

	return
}