...
1
16
17 package caching
18
19 import (
20 `strings`
21 `unsafe`
22
23 `github.com/bytedance/sonic/internal/rt`
24 )
25
26 type FieldMap struct {
27 N uint64
28 b unsafe.Pointer
29 m map[string]int
30 }
31
32 type FieldEntry struct {
33 ID int
34 Name string
35 Hash uint64
36 }
37
38 const (
39 FieldMap_N = int64(unsafe.Offsetof(FieldMap{}.N))
40 FieldMap_b = int64(unsafe.Offsetof(FieldMap{}.b))
41 FieldEntrySize = int64(unsafe.Sizeof(FieldEntry{}))
42 )
43
44 func newBucket(n int) unsafe.Pointer {
45 v := make([]FieldEntry, n)
46 return (*rt.GoSlice)(unsafe.Pointer(&v)).Ptr
47 }
48
49 func CreateFieldMap(n int) *FieldMap {
50 return &FieldMap {
51 N: uint64(n * 2),
52 b: newBucket(n * 2),
53 m: make(map[string]int, n * 2),
54 }
55 }
56
57 func (self *FieldMap) At(p uint64) *FieldEntry {
58 off := uintptr(p) * uintptr(FieldEntrySize)
59 return (*FieldEntry)(unsafe.Pointer(uintptr(self.b) + off))
60 }
61
62
63
64
65 func (self *FieldMap) Get(name string) int {
66 h := StrHash(name)
67 p := h % self.N
68 s := self.At(p)
69
70
72 for s.Hash != 0 {
73 if s.Hash == h && s.Name == name {
74 return s.ID
75 } else {
76 p = (p + 1) % self.N
77 s = self.At(p)
78 }
79 }
80
81
82 return -1
83 }
84
85 func (self *FieldMap) Set(name string, i int) {
86 h := StrHash(name)
87 p := h % self.N
88 s := self.At(p)
89
90
92 for s.Hash != 0 {
93 p = (p + 1) % self.N
94 s = self.At(p)
95 }
96
97
98 s.ID = i
99 s.Hash = h
100 s.Name = name
101
102
103 key := strings.ToLower(name)
104 if v, ok := self.m[key]; !ok || i < v {
105 self.m[key] = i
106 }
107 }
108
109 func (self *FieldMap) GetCaseInsensitive(name string) int {
110 if i, ok := self.m[strings.ToLower(name)]; ok {
111 return i
112 } else {
113 return -1
114 }
115 }
116
View as plain text