// WritePropertyMap writes an entire PropertyMap to the buffer. `context` // behaves the same way that it does for WriteKey. // // If WritePropertyMapDeterministic is true, then the rows will be sorted by // property name before they're serialized to buf (mostly useful for testing, // but also potentially useful if you need to make a hash of the property data). // // Write skips metadata keys. func WritePropertyMap(buf Buffer, context KeyContext, pm ds.PropertyMap) (err error) { defer recoverTo(&err) rows := make(sort.StringSlice, 0, len(pm)) tmpBuf := &bytes.Buffer{} pm, _ = pm.Save(false) for name, vals := range pm { tmpBuf.Reset() _, e := cmpbin.WriteString(tmpBuf, name) panicIf(e) _, e = cmpbin.WriteUint(tmpBuf, uint64(len(vals))) panicIf(e) for _, p := range vals { panicIf(WriteProperty(tmpBuf, context, p)) } rows = append(rows, tmpBuf.String()) } if WritePropertyMapDeterministic { rows.Sort() } _, e := cmpbin.WriteUint(buf, uint64(len(pm))) panicIf(e) for _, r := range rows { _, e := buf.WriteString(r) panicIf(e) } return }
func encodeItemValue(pm ds.PropertyMap) []byte { pm, _ = pm.Save(false) buf := bytes.Buffer{} // errs can't happen, since we're using a byte buffer. _ = buf.WriteByte(byte(NoCompression)) _ = serialize.WritePropertyMap(&buf, serialize.WithoutContext, pm) data := buf.Bytes() if buf.Len() > CompressionThreshold { buf2 := bytes.NewBuffer(make([]byte, 0, len(data))) _ = buf2.WriteByte(byte(ZlibCompression)) writer := zlib.NewWriter(buf2) _, _ = writer.Write(data[1:]) // skip the NoCompression byte writer.Close() data = buf2.Bytes() } return data }