1b10c286e7
index scheme is named smolder compiles and unit tests pass, that is all
95 lines
3.3 KiB
Go
95 lines
3.3 KiB
Go
// Copyright 2014 The Cockroach Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
// implied. See the License for the specific language governing
|
|
// permissions and limitations under the License.
|
|
//
|
|
// Author: Tobias Schottdorf (tobias.schottdorf@gmail.com)
|
|
|
|
// Bleve changes:
|
|
// - changed package name
|
|
// - removed dep on pkg/errors (even though its awesome and we should use it)
|
|
|
|
package smolder
|
|
|
|
import "fmt"
|
|
|
|
const (
|
|
// IntMin is chosen such that the range of int tags does not overlap the
|
|
// ascii character set that is frequently used in testing.
|
|
IntMin = 0x80
|
|
// IntMax is the maximum int tag value.
|
|
IntMax = 0xfd
|
|
|
|
intMaxWidth = 8
|
|
intZero = IntMin + intMaxWidth
|
|
intSmall = IntMax - intZero - intMaxWidth // 109
|
|
)
|
|
|
|
// EncodeUvarintAscending encodes the uint64 value using a variable length
|
|
// (length-prefixed) representation. The length is encoded as a single
|
|
// byte indicating the number of encoded bytes (-8) to follow. See
|
|
// EncodeVarintAscending for rationale. The encoded bytes are appended to the
|
|
// supplied buffer and the final buffer is returned.
|
|
func EncodeUvarintAscending(b []byte, v uint64) []byte {
|
|
switch {
|
|
case v <= intSmall:
|
|
return append(b, intZero+byte(v))
|
|
case v <= 0xff:
|
|
return append(b, IntMax-7, byte(v))
|
|
case v <= 0xffff:
|
|
return append(b, IntMax-6, byte(v>>8), byte(v))
|
|
case v <= 0xffffff:
|
|
return append(b, IntMax-5, byte(v>>16), byte(v>>8), byte(v))
|
|
case v <= 0xffffffff:
|
|
return append(b, IntMax-4, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
|
case v <= 0xffffffffff:
|
|
return append(b, IntMax-3, byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8),
|
|
byte(v))
|
|
case v <= 0xffffffffffff:
|
|
return append(b, IntMax-2, byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16),
|
|
byte(v>>8), byte(v))
|
|
case v <= 0xffffffffffffff:
|
|
return append(b, IntMax-1, byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24),
|
|
byte(v>>16), byte(v>>8), byte(v))
|
|
default:
|
|
return append(b, IntMax, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32),
|
|
byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
|
}
|
|
}
|
|
|
|
// DecodeUvarintAscending decodes a varint encoded uint64 from the input
|
|
// buffer. The remainder of the input buffer and the decoded uint64
|
|
// are returned.
|
|
func DecodeUvarintAscending(b []byte) ([]byte, uint64, error) {
|
|
if len(b) == 0 {
|
|
return nil, 0, fmt.Errorf("insufficient bytes to decode uvarint value")
|
|
}
|
|
length := int(b[0]) - intZero
|
|
b = b[1:] // skip length byte
|
|
if length <= intSmall {
|
|
return b, uint64(length), nil
|
|
}
|
|
length -= intSmall
|
|
if length < 0 || length > 8 {
|
|
return nil, 0, fmt.Errorf("invalid uvarint length of %d", length)
|
|
} else if len(b) < length {
|
|
return nil, 0, fmt.Errorf("insufficient bytes to decode uvarint value: %v", b)
|
|
}
|
|
var v uint64
|
|
// It is faster to range over the elements in a slice than to index
|
|
// into the slice on each loop iteration.
|
|
for _, t := range b[:length] {
|
|
v = (v << 8) | uint64(t)
|
|
}
|
|
return b[length:], v, nil
|
|
}
|