Update to last common bleve (#3986)
This commit is contained in:
parent
1b7cd3d0b0
commit
917b9641ec
184 changed files with 39576 additions and 121 deletions
227
vendor/github.com/couchbase/vellum/encoder_v1.go
generated
vendored
Normal file
227
vendor/github.com/couchbase/vellum/encoder_v1.go
generated
vendored
Normal file
|
@ -0,0 +1,227 @@
|
|||
// Copyright (c) 2017 Couchbase, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package vellum
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
const versionV1 = 1
|
||||
const oneTransition = 1 << 7
|
||||
const transitionNext = 1 << 6
|
||||
const stateFinal = 1 << 6
|
||||
const footerSizeV1 = 16
|
||||
|
||||
func init() {
|
||||
registerEncoder(versionV1, func(w io.Writer) encoder {
|
||||
return newEncoderV1(w)
|
||||
})
|
||||
}
|
||||
|
||||
type encoderV1 struct {
|
||||
bw *writer
|
||||
}
|
||||
|
||||
func newEncoderV1(w io.Writer) *encoderV1 {
|
||||
return &encoderV1{
|
||||
bw: newWriter(w),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *encoderV1) reset(w io.Writer) {
|
||||
e.bw.Reset(w)
|
||||
}
|
||||
|
||||
func (e *encoderV1) start() error {
|
||||
header := make([]byte, headerSize)
|
||||
binary.LittleEndian.PutUint64(header, versionV1)
|
||||
binary.LittleEndian.PutUint64(header[8:], uint64(0)) // type
|
||||
n, err := e.bw.Write(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != headerSize {
|
||||
return fmt.Errorf("short write of header %d/%d", n, headerSize)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *encoderV1) encodeState(s *builderNode, lastAddr int) (int, error) {
|
||||
if len(s.trans) == 0 && s.final && s.finalOutput == 0 {
|
||||
return 0, nil
|
||||
} else if len(s.trans) != 1 || s.final {
|
||||
return e.encodeStateMany(s)
|
||||
} else if !s.final && s.trans[0].out == 0 && s.trans[0].addr == lastAddr {
|
||||
return e.encodeStateOneFinish(s, transitionNext)
|
||||
}
|
||||
return e.encodeStateOne(s)
|
||||
}
|
||||
|
||||
func (e *encoderV1) encodeStateOne(s *builderNode) (int, error) {
|
||||
start := uint64(e.bw.counter)
|
||||
outPackSize := 0
|
||||
if s.trans[0].out != 0 {
|
||||
outPackSize = packedSize(s.trans[0].out)
|
||||
err := e.bw.WritePackedUintIn(s.trans[0].out, outPackSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
delta := deltaAddr(start, uint64(s.trans[0].addr))
|
||||
transPackSize := packedSize(delta)
|
||||
err := e.bw.WritePackedUintIn(delta, transPackSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
packSize := encodePackSize(transPackSize, outPackSize)
|
||||
err = e.bw.WriteByte(packSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return e.encodeStateOneFinish(s, 0)
|
||||
}
|
||||
|
||||
func (e *encoderV1) encodeStateOneFinish(s *builderNode, next byte) (int, error) {
|
||||
enc := encodeCommon(s.trans[0].in)
|
||||
|
||||
// not a common input
|
||||
if enc == 0 {
|
||||
err := e.bw.WriteByte(s.trans[0].in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
err := e.bw.WriteByte(oneTransition | next | enc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return e.bw.counter - 1, nil
|
||||
}
|
||||
|
||||
func (e *encoderV1) encodeStateMany(s *builderNode) (int, error) {
|
||||
start := uint64(e.bw.counter)
|
||||
transPackSize := 0
|
||||
outPackSize := packedSize(s.finalOutput)
|
||||
anyOutputs := s.finalOutput != 0
|
||||
for i := range s.trans {
|
||||
delta := deltaAddr(start, uint64(s.trans[i].addr))
|
||||
tsize := packedSize(delta)
|
||||
if tsize > transPackSize {
|
||||
transPackSize = tsize
|
||||
}
|
||||
osize := packedSize(s.trans[i].out)
|
||||
if osize > outPackSize {
|
||||
outPackSize = osize
|
||||
}
|
||||
anyOutputs = anyOutputs || s.trans[i].out != 0
|
||||
}
|
||||
if !anyOutputs {
|
||||
outPackSize = 0
|
||||
}
|
||||
|
||||
if anyOutputs {
|
||||
// output final value
|
||||
if s.final {
|
||||
err := e.bw.WritePackedUintIn(s.finalOutput, outPackSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
// output transition values (in reverse)
|
||||
for j := len(s.trans) - 1; j >= 0; j-- {
|
||||
err := e.bw.WritePackedUintIn(s.trans[j].out, outPackSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// output transition dests (in reverse)
|
||||
for j := len(s.trans) - 1; j >= 0; j-- {
|
||||
delta := deltaAddr(start, uint64(s.trans[j].addr))
|
||||
err := e.bw.WritePackedUintIn(delta, transPackSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// output transition keys (in reverse)
|
||||
for j := len(s.trans) - 1; j >= 0; j-- {
|
||||
err := e.bw.WriteByte(s.trans[j].in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
packSize := encodePackSize(transPackSize, outPackSize)
|
||||
err := e.bw.WriteByte(packSize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
numTrans := encodeNumTrans(len(s.trans))
|
||||
|
||||
// if number of transitions wont fit in edge header byte
|
||||
// write out separately
|
||||
if numTrans == 0 {
|
||||
if len(s.trans) == 256 {
|
||||
// this wouldn't fit in single byte, but reuse value 1
|
||||
// which would have always fit in the edge header instead
|
||||
err = e.bw.WriteByte(1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
err = e.bw.WriteByte(byte(len(s.trans)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finally write edge header
|
||||
if s.final {
|
||||
numTrans |= stateFinal
|
||||
}
|
||||
err = e.bw.WriteByte(numTrans)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return e.bw.counter - 1, nil
|
||||
}
|
||||
|
||||
func (e *encoderV1) finish(count, rootAddr int) error {
|
||||
footer := make([]byte, footerSizeV1)
|
||||
binary.LittleEndian.PutUint64(footer, uint64(count)) // root addr
|
||||
binary.LittleEndian.PutUint64(footer[8:], uint64(rootAddr)) // root addr
|
||||
n, err := e.bw.Write(footer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != footerSizeV1 {
|
||||
return fmt.Errorf("short write of footer %d/%d", n, footerSizeV1)
|
||||
}
|
||||
err = e.bw.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue