Moved to google.golang.org/genproto/googleapis/api/annotations

Fixes #52
This commit is contained in:
Valerio Gheri
2017-03-31 18:01:58 +02:00
parent 024c5a4e4e
commit c40779224f
2037 changed files with 831329 additions and 1854 deletions

View File

@@ -0,0 +1,2 @@
// Package utilities provides members for internal use in grpc-gateway.
package utilities

View File

@@ -0,0 +1,22 @@
package utilities
// An OpCode is a opcode of compiled path patterns.
type OpCode int
// These constants are the valid values of OpCode.
const (
// OpNop does nothing
OpNop = OpCode(iota)
// OpPush pushes a component to stack
OpPush
// OpLitPush pushes a component to stack if it matches to the literal
OpLitPush
// OpPushM concatenates the remaining components and pushes it to stack
OpPushM
// OpConcatN pops N items from stack, concatenates them and pushes it back to stack
OpConcatN
// OpCapture pops an item and binds it to the variable
OpCapture
// OpEnd is the least postive invalid opcode.
OpEnd
)

View File

@@ -0,0 +1,177 @@
package utilities
import (
"sort"
)
// DoubleArray is a Double Array implementation of trie on sequences of strings.
type DoubleArray struct {
// Encoding keeps an encoding from string to int
Encoding map[string]int
// Base is the base array of Double Array
Base []int
// Check is the check array of Double Array
Check []int
}
// NewDoubleArray builds a DoubleArray from a set of sequences of strings.
func NewDoubleArray(seqs [][]string) *DoubleArray {
da := &DoubleArray{Encoding: make(map[string]int)}
if len(seqs) == 0 {
return da
}
encoded := registerTokens(da, seqs)
sort.Sort(byLex(encoded))
root := node{row: -1, col: -1, left: 0, right: len(encoded)}
addSeqs(da, encoded, 0, root)
for i := len(da.Base); i > 0; i-- {
if da.Check[i-1] != 0 {
da.Base = da.Base[:i]
da.Check = da.Check[:i]
break
}
}
return da
}
func registerTokens(da *DoubleArray, seqs [][]string) [][]int {
var result [][]int
for _, seq := range seqs {
var encoded []int
for _, token := range seq {
if _, ok := da.Encoding[token]; !ok {
da.Encoding[token] = len(da.Encoding)
}
encoded = append(encoded, da.Encoding[token])
}
result = append(result, encoded)
}
for i := range result {
result[i] = append(result[i], len(da.Encoding))
}
return result
}
type node struct {
row, col int
left, right int
}
func (n node) value(seqs [][]int) int {
return seqs[n.row][n.col]
}
func (n node) children(seqs [][]int) []*node {
var result []*node
lastVal := int(-1)
last := new(node)
for i := n.left; i < n.right; i++ {
if lastVal == seqs[i][n.col+1] {
continue
}
last.right = i
last = &node{
row: i,
col: n.col + 1,
left: i,
}
result = append(result, last)
}
last.right = n.right
return result
}
func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) {
ensureSize(da, pos)
children := n.children(seqs)
var i int
for i = 1; ; i++ {
ok := func() bool {
for _, child := range children {
code := child.value(seqs)
j := i + code
ensureSize(da, j)
if da.Check[j] != 0 {
return false
}
}
return true
}()
if ok {
break
}
}
da.Base[pos] = i
for _, child := range children {
code := child.value(seqs)
j := i + code
da.Check[j] = pos + 1
}
terminator := len(da.Encoding)
for _, child := range children {
code := child.value(seqs)
if code == terminator {
continue
}
j := i + code
addSeqs(da, seqs, j, *child)
}
}
func ensureSize(da *DoubleArray, i int) {
for i >= len(da.Base) {
da.Base = append(da.Base, make([]int, len(da.Base)+1)...)
da.Check = append(da.Check, make([]int, len(da.Check)+1)...)
}
}
type byLex [][]int
func (l byLex) Len() int { return len(l) }
func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
func (l byLex) Less(i, j int) bool {
si := l[i]
sj := l[j]
var k int
for k = 0; k < len(si) && k < len(sj); k++ {
if si[k] < sj[k] {
return true
}
if si[k] > sj[k] {
return false
}
}
if k < len(sj) {
return true
}
return false
}
// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence.
func (da *DoubleArray) HasCommonPrefix(seq []string) bool {
if len(da.Base) == 0 {
return false
}
var i int
for _, t := range seq {
code, ok := da.Encoding[t]
if !ok {
break
}
j := da.Base[i] + code
if len(da.Check) <= j || da.Check[j] != i+1 {
break
}
i = j
}
j := da.Base[i] + len(da.Encoding)
if len(da.Check) <= j || da.Check[j] != i+1 {
return false
}
return true
}

View File

@@ -0,0 +1,372 @@
package utilities_test
import (
"reflect"
"testing"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
)
func TestMaxCommonPrefix(t *testing.T) {
for _, spec := range []struct {
da utilities.DoubleArray
tokens []string
want bool
}{
{
da: utilities.DoubleArray{},
tokens: nil,
want: false,
},
{
da: utilities.DoubleArray{},
tokens: []string{"foo"},
want: false,
},
{
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
},
Base: []int{1, 1, 0},
Check: []int{0, 1, 2},
},
tokens: nil,
want: false,
},
{
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
},
Base: []int{1, 1, 0},
Check: []int{0, 1, 2},
},
tokens: []string{"foo"},
want: true,
},
{
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
},
Base: []int{1, 1, 0},
Check: []int{0, 1, 2},
},
tokens: []string{"bar"},
want: false,
},
{
// foo|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 1, 2, 0, 0},
Check: []int{0, 1, 1, 2, 3},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^foo$
// 4: ^bar$
},
tokens: []string{"foo"},
want: true,
},
{
// foo|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 1, 2, 0, 0},
Check: []int{0, 1, 1, 2, 3},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^foo$
// 4: ^bar$
},
tokens: []string{"bar"},
want: true,
},
{
// foo|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 1, 2, 0, 0},
Check: []int{0, 1, 1, 2, 3},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^foo$
// 4: ^bar$
},
tokens: []string{"something-else"},
want: false,
},
{
// foo|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 1, 2, 0, 0},
Check: []int{0, 1, 1, 2, 3},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^foo$
// 4: ^bar$
},
tokens: []string{"foo", "bar"},
want: true,
},
{
// foo|foo\.bar|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 3, 1, 0, 4, 0, 0},
Check: []int{0, 1, 1, 3, 2, 2, 5},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^bar$
// 4: ^foo.bar
// 5: ^foo$
// 6: ^foo.bar$
},
tokens: []string{"foo"},
want: true,
},
{
// foo|foo\.bar|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 3, 1, 0, 4, 0, 0},
Check: []int{0, 1, 1, 3, 2, 2, 5},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^bar$
// 4: ^foo.bar
// 5: ^foo$
// 6: ^foo.bar$
},
tokens: []string{"foo", "bar"},
want: true,
},
{
// foo|foo\.bar|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 3, 1, 0, 4, 0, 0},
Check: []int{0, 1, 1, 3, 2, 2, 5},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^bar$
// 4: ^foo.bar
// 5: ^foo$
// 6: ^foo.bar$
},
tokens: []string{"bar"},
want: true,
},
{
// foo|foo\.bar|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 3, 1, 0, 4, 0, 0},
Check: []int{0, 1, 1, 3, 2, 2, 5},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^bar$
// 4: ^foo.bar
// 5: ^foo$
// 6: ^foo.bar$
},
tokens: []string{"something-else"},
want: false,
},
{
// foo|foo\.bar|bar
da: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 3, 1, 0, 4, 0, 0},
Check: []int{0, 1, 1, 3, 2, 2, 5},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^bar$
// 4: ^foo.bar
// 5: ^foo$
// 6: ^foo.bar$
},
tokens: []string{"foo", "bar", "baz"},
want: true,
},
} {
got := spec.da.HasCommonPrefix(spec.tokens)
if got != spec.want {
t.Errorf("%#v.HasCommonPrefix(%v) = %v; want %v", spec.da, spec.tokens, got, spec.want)
}
}
}
func TestAdd(t *testing.T) {
for _, spec := range []struct {
tokens [][]string
want utilities.DoubleArray
}{
{
want: utilities.DoubleArray{
Encoding: make(map[string]int),
},
},
{
tokens: [][]string{{"foo"}},
want: utilities.DoubleArray{
Encoding: map[string]int{"foo": 0},
Base: []int{1, 1, 0},
Check: []int{0, 1, 2},
// 0: ^
// 1: ^foo
// 2: ^foo$
},
},
{
tokens: [][]string{{"foo"}, {"bar"}},
want: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
},
Base: []int{1, 1, 2, 0, 0},
Check: []int{0, 1, 1, 2, 3},
// 0: ^
// 1: ^foo
// 2: ^bar
// 3: ^foo$
// 4: ^bar$
},
},
{
tokens: [][]string{{"foo", "bar"}, {"foo", "baz"}},
want: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
"baz": 2,
},
Base: []int{1, 1, 1, 2, 0, 0},
Check: []int{0, 1, 2, 2, 3, 4},
// 0: ^
// 1: ^foo
// 2: ^foo.bar
// 3: ^foo.baz
// 4: ^foo.bar$
// 5: ^foo.baz$
},
},
{
tokens: [][]string{{"foo", "bar"}, {"foo", "baz"}, {"qux"}},
want: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
"baz": 2,
"qux": 3,
},
Base: []int{1, 1, 1, 2, 3, 0, 0, 0},
Check: []int{0, 1, 2, 2, 1, 3, 4, 5},
// 0: ^
// 1: ^foo
// 2: ^foo.bar
// 3: ^foo.baz
// 4: ^qux
// 5: ^foo.bar$
// 6: ^foo.baz$
// 7: ^qux$
},
},
{
tokens: [][]string{
{"foo", "bar"},
{"foo", "baz", "bar"},
{"qux", "foo"},
},
want: utilities.DoubleArray{
Encoding: map[string]int{
"foo": 0,
"bar": 1,
"baz": 2,
"qux": 3,
},
Base: []int{1, 1, 1, 5, 8, 0, 3, 0, 5, 0},
Check: []int{0, 1, 2, 2, 1, 3, 4, 7, 5, 9},
// 0: ^
// 1: ^foo
// 2: ^foo.bar
// 3: ^foo.baz
// 4: ^qux
// 5: ^foo.bar$
// 6: ^foo.baz.bar
// 7: ^foo.baz.bar$
// 8: ^qux.foo
// 9: ^qux.foo$
},
},
} {
da := utilities.NewDoubleArray(spec.tokens)
if got, want := da.Encoding, spec.want.Encoding; !reflect.DeepEqual(got, want) {
t.Errorf("da.Encoding = %v; want %v; tokens = %#v", got, want, spec.tokens)
}
if got, want := da.Base, spec.want.Base; !compareArray(got, want) {
t.Errorf("da.Base = %v; want %v; tokens = %#v", got, want, spec.tokens)
}
if got, want := da.Check, spec.want.Check; !compareArray(got, want) {
t.Errorf("da.Check = %v; want %v; tokens = %#v", got, want, spec.tokens)
}
}
}
func compareArray(got, want []int) bool {
var i int
for i = 0; i < len(got) && i < len(want); i++ {
if got[i] != want[i] {
return false
}
}
if i < len(want) {
return false
}
for ; i < len(got); i++ {
if got[i] != 0 {
return false
}
}
return true
}