mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 11:28:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package nodb
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"errors"
 | |
| 	"regexp"
 | |
| 
 | |
| 	"github.com/lunny/nodb/store"
 | |
| )
 | |
| 
 | |
| var errDataType = errors.New("error data type")
 | |
| var errMetaKey = errors.New("error meta key")
 | |
| 
 | |
| // Seek search the prefix key
 | |
| func (db *DB) Seek(key []byte) (*store.Iterator, error) {
 | |
| 	return db.seek(KVType, key)
 | |
| }
 | |
| 
 | |
| func (db *DB) seek(dataType byte, key []byte) (*store.Iterator, error) {
 | |
| 	var minKey []byte
 | |
| 	var err error
 | |
| 
 | |
| 	if len(key) > 0 {
 | |
| 		if err = checkKeySize(key); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 	} else {
 | |
| 		if minKey, err = db.encodeMinKey(dataType); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	it := db.bucket.NewIterator()
 | |
| 	it.Seek(minKey)
 | |
| 	return it, nil
 | |
| }
 | |
| 
 | |
| func (db *DB) MaxKey() ([]byte, error) {
 | |
| 	return db.encodeMaxKey(KVType)
 | |
| }
 | |
| 
 | |
| func (db *DB) Key(it *store.Iterator) ([]byte, error) {
 | |
| 	return db.decodeMetaKey(KVType, it.Key())
 | |
| }
 | |
| 
 | |
| func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match string) ([][]byte, error) {
 | |
| 	var minKey, maxKey []byte
 | |
| 	var err error
 | |
| 	var r *regexp.Regexp
 | |
| 
 | |
| 	if len(match) > 0 {
 | |
| 		if r, err = regexp.Compile(match); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if len(key) > 0 {
 | |
| 		if err = checkKeySize(key); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 	} else {
 | |
| 		if minKey, err = db.encodeMinKey(dataType); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if maxKey, err = db.encodeMaxKey(dataType); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if count <= 0 {
 | |
| 		count = defaultScanCount
 | |
| 	}
 | |
| 
 | |
| 	v := make([][]byte, 0, count)
 | |
| 
 | |
| 	it := db.bucket.NewIterator()
 | |
| 	it.Seek(minKey)
 | |
| 
 | |
| 	if !inclusive {
 | |
| 		if it.Valid() && bytes.Equal(it.RawKey(), minKey) {
 | |
| 			it.Next()
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for i := 0; it.Valid() && i < count && bytes.Compare(it.RawKey(), maxKey) < 0; it.Next() {
 | |
| 		if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
 | |
| 			continue
 | |
| 		} else if r != nil && !r.Match(k) {
 | |
| 			continue
 | |
| 		} else {
 | |
| 			v = append(v, k)
 | |
| 			i++
 | |
| 		}
 | |
| 	}
 | |
| 	it.Close()
 | |
| 	return v, nil
 | |
| }
 | |
| 
 | |
| func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
 | |
| 	return db.encodeMetaKey(dataType, nil)
 | |
| }
 | |
| 
 | |
| func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
 | |
| 	k, err := db.encodeMetaKey(dataType, nil)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	k[len(k)-1] = dataType + 1
 | |
| 	return k, nil
 | |
| }
 | |
| 
 | |
| func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
 | |
| 	switch dataType {
 | |
| 	case KVType:
 | |
| 		return db.encodeKVKey(key), nil
 | |
| 	case LMetaType:
 | |
| 		return db.lEncodeMetaKey(key), nil
 | |
| 	case HSizeType:
 | |
| 		return db.hEncodeSizeKey(key), nil
 | |
| 	case ZSizeType:
 | |
| 		return db.zEncodeSizeKey(key), nil
 | |
| 	case BitMetaType:
 | |
| 		return db.bEncodeMetaKey(key), nil
 | |
| 	case SSizeType:
 | |
| 		return db.sEncodeSizeKey(key), nil
 | |
| 	default:
 | |
| 		return nil, errDataType
 | |
| 	}
 | |
| }
 | |
| func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) {
 | |
| 	if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
 | |
| 		return nil, errMetaKey
 | |
| 	}
 | |
| 	return ek[2:], nil
 | |
| }
 |