github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/storage/segment/serialization.go (about) 1 package segment 2 3 import ( 4 "bufio" 5 "bytes" 6 "errors" 7 "io" 8 "time" 9 10 "github.com/pyroscope-io/pyroscope/pkg/storage/metadata" 11 "github.com/pyroscope-io/pyroscope/pkg/util/serialization" 12 "github.com/pyroscope-io/pyroscope/pkg/util/varint" 13 ) 14 15 // serialization format version. it's not very useful right now, but it will be in the future 16 const currentVersion = 3 17 18 func (s *Segment) populateFromMetadata(mdata map[string]interface{}) { 19 if v, ok := mdata["sampleRate"]; ok { 20 s.sampleRate = uint32(v.(float64)) 21 } 22 if v, ok := mdata["spyName"]; ok { 23 s.spyName = v.(string) 24 } 25 if v, ok := mdata["units"]; ok { 26 s.units = metadata.Units(v.(string)) 27 } 28 if v, ok := mdata["aggregationType"]; ok { 29 s.aggregationType = metadata.AggregationType(v.(string)) 30 } 31 } 32 33 func (s *Segment) generateMetadata() map[string]interface{} { 34 return map[string]interface{}{ 35 "sampleRate": s.sampleRate, 36 "spyName": s.spyName, 37 "units": s.units, 38 "aggregationType": s.aggregationType, 39 } 40 } 41 42 func (s *Segment) Serialize(w io.Writer) error { 43 s.m.RLock() 44 defer s.m.RUnlock() 45 46 vw := varint.NewWriter() 47 if _, err := vw.Write(w, currentVersion); err != nil { 48 return err 49 } 50 if err := serialization.WriteMetadata(w, s.generateMetadata()); err != nil { 51 return err 52 } 53 54 if s.root == nil { 55 return nil 56 } 57 58 s.serialize(w, vw, s.root) 59 60 return s.watermarks.serialize(w) 61 } 62 63 func (s *Segment) serialize(w io.Writer, vw varint.Writer, n *streeNode) { 64 vw.Write(w, uint64(n.depth)) 65 vw.Write(w, uint64(n.time.Unix())) 66 vw.Write(w, n.samples) 67 vw.Write(w, n.writes) 68 p := uint64(0) 69 if n.present { 70 p = 1 71 } 72 vw.Write(w, p) 73 74 // depth 75 // time 76 // keyInChunks 77 // children 78 l := 0 79 for _, v := range n.children { 80 if v != nil { 81 l++ 82 } 83 } 84 85 vw.Write(w, uint64(l)) 86 for _, v := range n.children { 87 if v != nil { 88 s.serialize(w, vw, v) 89 } 90 } 91 } 92 93 var errMaxDepth = errors.New("depth is too high") 94 95 func Deserialize(r io.Reader) (*Segment, error) { 96 s := New() 97 br := bufio.NewReader(r) // TODO if it's already a bytereader skip 98 99 // reads serialization format version, see comment at the top 100 version, err := varint.Read(br) 101 if err != nil { 102 return nil, err 103 } 104 105 mdata, err := serialization.ReadMetadata(br) 106 if err != nil { 107 return nil, err 108 } 109 s.populateFromMetadata(mdata) 110 111 // In some cases, there can be no nodes. 112 if br.Buffered() == 0 { 113 return s, nil 114 } 115 116 parents := []*streeNode{nil} 117 for len(parents) > 0 { 118 depth, err := varint.Read(br) 119 if err != nil { 120 return nil, err 121 } 122 if int(depth) >= len(durations) { 123 return nil, errMaxDepth 124 } 125 timeVal, err := varint.Read(br) 126 if err != nil { 127 return nil, err 128 } 129 samplesVal, err := varint.Read(br) 130 if err != nil { 131 return nil, err 132 } 133 var writesVal uint64 134 if version >= 2 { 135 writesVal, err = varint.Read(br) 136 if err != nil { 137 return nil, err 138 } 139 } 140 presentVal, err := varint.Read(br) 141 if err != nil { 142 return nil, err 143 } 144 node := newNode(time.Unix(int64(timeVal), 0), int(depth), multiplier) 145 if presentVal == 1 { 146 node.present = true 147 } 148 node.samples = samplesVal 149 node.writes = writesVal 150 if s.root == nil { 151 s.root = node 152 } 153 154 parent := parents[0] 155 parents = parents[1:] 156 if parent != nil { 157 parent.replace(node) 158 } 159 childrenLen, err := varint.Read(br) 160 if err != nil { 161 return nil, err 162 } 163 164 r := []*streeNode{} 165 for i := 0; i < int(childrenLen); i++ { 166 r = append(r, node) 167 } 168 parents = append(r, parents...) 169 } 170 171 if version >= 3 { 172 if err = deserializeWatermarks(br, &s.watermarks); err != nil { 173 return nil, err 174 } 175 } 176 177 return s, nil 178 } 179 180 func (s *Segment) Bytes() ([]byte, error) { 181 b := bytes.Buffer{} 182 if err := s.Serialize(&b); err != nil { 183 return nil, err 184 } 185 return b.Bytes(), nil 186 } 187 188 func FromBytes(p []byte) (*Segment, error) { 189 return Deserialize(bytes.NewReader(p)) 190 } 191 192 func (w watermarks) serialize(dst io.Writer) error { 193 vw := varint.NewWriter() 194 if _, err := vw.Write(dst, uint64(w.absoluteTime.UTC().Unix())); err != nil { 195 return err 196 } 197 if _, err := vw.Write(dst, uint64(len(w.levels))); err != nil { 198 return err 199 } 200 for k, v := range w.levels { 201 if _, err := vw.Write(dst, uint64(k)); err != nil { 202 return err 203 } 204 if _, err := vw.Write(dst, uint64(v.UTC().Unix())); err != nil { 205 return err 206 } 207 } 208 return nil 209 } 210 211 func deserializeWatermarks(r io.ByteReader, w *watermarks) error { 212 a, err := varint.Read(r) 213 if err != nil { 214 return err 215 } 216 w.absoluteTime = time.Unix(int64(a), 0).UTC() 217 l, err := varint.Read(r) 218 if err != nil { 219 return err 220 } 221 levels := int(l) 222 for i := 0; i < levels; i++ { 223 k, err := varint.Read(r) 224 if err != nil { 225 return err 226 } 227 v, err := varint.Read(r) 228 if err != nil { 229 return err 230 } 231 w.levels[int(k)] = time.Unix(int64(v), 0).UTC() 232 } 233 return nil 234 }