fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

1package zoekt 2 3import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "unsafe" 8) 9 10// Wire-format of map[uint32]MinimalRepoListEntry is pretty straightforward: 11// 12// byte(1) version 13// uvarint(len(minimal)) 14// uvarint(sum(len(entry.Branches) for entry in minimal)) 15// for repoID, entry in minimal: 16// uvarint(repoID) 17// byte(entry.HasSymbols) 18// uvarint(len(entry.Branches)) 19// for b in entry.Branches: 20// str(b.Name) 21// str(b.Version) 22 23// reposMapEncode implements an efficient encoder for ReposMap. 24func reposMapEncode(minimal ReposMap) ([]byte, error) { 25 if minimal == nil { 26 return nil, nil 27 } 28 29 var b bytes.Buffer 30 var enc [binary.MaxVarintLen64]byte 31 varint := func(n int) { 32 m := binary.PutUvarint(enc[:], uint64(n)) 33 b.Write(enc[:m]) 34 } 35 str := func(s string) { 36 varint(len(s)) 37 b.WriteString(s) 38 } 39 strSize := func(s string) int { 40 return binary.PutUvarint(enc[:], uint64(len(s))) + len(s) 41 } 42 43 // We calculate this up front so when decoding we only need to allocate the 44 // underlying array once. 45 allBranchesLen := 0 46 for _, entry := range minimal { 47 allBranchesLen += len(entry.Branches) 48 } 49 50 // Calculate size 51 size := 1 // version 52 size += binary.PutUvarint(enc[:], uint64(len(minimal))) 53 size += binary.PutUvarint(enc[:], uint64(allBranchesLen)) 54 for repoID, entry := range minimal { 55 size += binary.PutUvarint(enc[:], uint64(repoID)) 56 size += 1 // HasSymbols 57 size += binary.PutUvarint(enc[:], uint64(len(entry.Branches))) 58 for _, b := range entry.Branches { 59 size += strSize(b.Name) 60 size += strSize(b.Version) 61 } 62 } 63 b.Grow(size) 64 65 // Version 66 b.WriteByte(1) 67 68 // Length 69 varint(len(minimal)) 70 71 varint(allBranchesLen) 72 73 for repoID, entry := range minimal { 74 varint(int(repoID)) 75 76 hasSymbols := byte(1) 77 if !entry.HasSymbols { 78 hasSymbols = 0 79 } 80 b.WriteByte(hasSymbols) 81 82 varint(len(entry.Branches)) 83 for _, b := range entry.Branches { 84 str(b.Name) 85 str(b.Version) 86 } 87 } 88 89 return b.Bytes(), nil 90} 91 92// reposMapDecode implements an efficient decoder for map[string]struct{}. 93func reposMapDecode(b []byte) (ReposMap, error) { 94 // nil input 95 if len(b) == 0 { 96 return nil, nil 97 } 98 99 // binaryReader returns strings pointing into b to avoid allocations. We 100 // don't own b, so we create a copy of it. 101 r := binaryReader{ 102 typ: "ReposMap", 103 b: append([]byte{}, b...), 104 } 105 106 // Version 107 if v := r.byt(); v != 1 { 108 return nil, fmt.Errorf("unsupported stringSet encoding version %d", v) 109 } 110 111 // Length 112 l := r.uvarint() 113 m := make(map[uint32]MinimalRepoListEntry, l) 114 115 // Pre-allocate slice for all branches 116 allBranchesLen := r.uvarint() 117 allBranches := make([]RepositoryBranch, 0, allBranchesLen) 118 119 for i := 0; i < l; i++ { 120 repoID := r.uvarint() 121 hasSymbols := r.byt() == 1 122 lb := r.uvarint() 123 for i := 0; i < lb; i++ { 124 allBranches = append(allBranches, RepositoryBranch{ 125 Name: r.str(), 126 Version: r.str(), 127 }) 128 } 129 branches := allBranches[len(allBranches)-lb:] 130 m[uint32(repoID)] = MinimalRepoListEntry{ 131 HasSymbols: hasSymbols, 132 Branches: branches, 133 } 134 } 135 136 return m, r.err 137} 138 139type binaryReader struct { 140 typ string 141 b []byte 142 err error 143} 144 145func (b *binaryReader) uvarint() int { 146 x, n := binary.Uvarint(b.b) 147 if n < 0 { 148 b.b = nil 149 b.err = fmt.Errorf("malformed %s", b.typ) 150 return 0 151 } 152 b.b = b.b[n:] 153 return int(x) 154} 155 156func (b *binaryReader) str() string { 157 l := b.uvarint() 158 if l > len(b.b) { 159 b.b = nil 160 b.err = fmt.Errorf("malformed %s", b.typ) 161 return "" 162 } 163 s := b2s(b.b[:l]) 164 b.b = b.b[l:] 165 return s 166} 167 168func (b *binaryReader) byt() byte { 169 if len(b.b) < 1 { 170 b.b = nil 171 b.err = fmt.Errorf("malformed %s", b.typ) 172 return 0 173 } 174 x := b.b[0] 175 b.b = b.b[1:] 176 return x 177} 178 179func b2s(b []byte) string { 180 return *(*string)(unsafe.Pointer(&b)) 181}