-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathmok.go
110 lines (99 loc) · 2.5 KB
/
mok.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"encoding/base64"
"encoding/binary"
"encoding/hex"
"fmt"
"strings"
"github.com/pingcap/tidb/util/codec"
)
type Node struct {
typ string // "key", "table_id", "row_id", "index_id", "index_values", "index_value", "ts"
val []byte
variants []*Variant
}
type Variant struct {
method string
children []*Node
}
func N(t string, v []byte) *Node {
return &Node{typ: t, val: v}
}
func (n *Node) String() string {
switch n.typ {
case "key", "raw_key", "index_values":
switch *keyFormat {
case "hex":
return `"` + strings.ToUpper(hex.EncodeToString(n.val)) + `"`
case "base64":
return `"` + base64.StdEncoding.EncodeToString(n.val) + `"`
case "proto":
return `"` + formatProto(string(n.val)) + `"`
default:
return fmt.Sprintf("%q", n.val)
}
case "key_mode":
return fmt.Sprintf("key mode: %s", KeyMode(n.val[0]))
case "keyspace_id":
tmp := []byte{'\x00'}
t := append(tmp, n.val...)
id := binary.BigEndian.Uint32(t)
return fmt.Sprintf("keyspace: %v", id)
case "table_id":
_, id, _ := codec.DecodeInt(n.val)
return fmt.Sprintf("table: %v", id)
case "row_id":
_, id, _ := codec.DecodeInt(n.val)
return fmt.Sprintf("row: %v", id)
case "index_id":
_, id, _ := codec.DecodeInt(n.val)
return fmt.Sprintf("index: %v", id)
case "index_value":
_, d, _ := codec.DecodeOne(n.val)
s, _ := d.ToString()
return fmt.Sprintf("kind: %v, value: %v", indexTypeToString[d.Kind()], s)
case "ts":
_, ts, _ := codec.DecodeUintDesc(n.val)
return fmt.Sprintf("ts: %v (%v)", ts, GetTimeFromTS(uint64(ts)))
}
return fmt.Sprintf("%v:%q", n.typ, n.val)
}
func (n *Node) Expand() *Node {
for _, fn := range rules {
if t := fn(n); t != nil {
for _, child := range t.children {
child.Expand()
}
n.variants = append(n.variants, t)
}
}
return n
}
func (n *Node) Print() {
fmt.Println(n.String())
for i, t := range n.variants {
t.PrintIndent("", i == len(n.variants)-1)
}
}
func (n *Node) PrintIndent(indent string, last bool) {
indent = printIndent(indent, last)
fmt.Println(n.String())
for i, t := range n.variants {
t.PrintIndent(indent, i == len(n.variants)-1)
}
}
func (v *Variant) PrintIndent(indent string, last bool) {
indent = printIndent(indent, last)
fmt.Printf("## %s\n", v.method)
for i, c := range v.children {
c.PrintIndent(indent, i == len(v.children)-1)
}
}
func printIndent(indent string, last bool) string {
if last {
fmt.Print(indent + "└─")
return indent + " "
}
fmt.Print(indent + "├─")
return indent + "│ "
}