示例#1
0
// 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
}
示例#2
0
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
}