public void Serialize(BinaryWriter writer) { byte b = 0; if (Sign) { b |= (byte)0x80; } if (IsReady) { b |= (byte)0x40; } if (AlwaysUseDelta) { b |= (byte)0x20; } b |= (byte)Type; writer.Write(b); if (Type == HelperType.Raw) { return; } if (Type == HelperType.OneStep) { CountCompression.Serialize(writer, Delta); return; } writer.Write(DeltaBits); }
public static void Compress(BinaryWriter writer, long[] values, int index, int count, Helper helper) { writer.Write(VERSION); if (count == 0) { return; } long value = values[index]; CountCompression.Serialize(writer, (ulong)value); if (count == 1) { return; } Debug.Assert(count == helper.Count); if (!helper.IsReady) { helper.Prepare(); } index++; count--; int maxIndex = index + count - 1; helper.Serialize(writer); if (helper.Type == HelperType.Raw) { while (index <= maxIndex) { writer.Write(values[index++]); } return; } if (helper.Type == HelperType.OneStep) { return; } ulong maxDelta = helper.Delta; bool alwaysUseDelta = helper.AlwaysUseDelta; int bitCount = BitUtils.GetBitBounds(maxDelta); bool writeSign = helper.Type == HelperType.Delta; CommonArray common = new CommonArray(); int sizeBits = helper.SizeBits > 0 ? helper.SizeBits : (1 + 1 + 64) * (count - 1); common.ByteArray = new byte[(int)Math.Ceiling(sizeBits / 8.0)]; ulong[] data = common.UInt64Array; int bitIndex = 0; ulong delta; bool sign; //false - positive, true - negative for (; index <= maxIndex; index++) { long newValue = values[index]; if (newValue >= value) { sign = false; delta = (ulong)(newValue - value); } else { sign = true; delta = (ulong)(value - newValue); } if (alwaysUseDelta || delta <= maxDelta) { if (!alwaysUseDelta) { SetFlag(data, bitIndex /*, true*/); //use delta bitIndex++; } if (writeSign) { if (sign) { SetFlag(data, bitIndex /*, sign*/); } bitIndex++; } SetBits(data, bitIndex, delta, bitCount); bitIndex += bitCount; } else { //SetFlag(data, bitIndex, false); //don't use delta bitIndex++; SetValue(data, bitIndex, (ulong)newValue); bitIndex += 64; } value = newValue; } int bytesCount = (int)Math.Ceiling(bitIndex / 8.0); CountCompression.Serialize(writer, (ulong)bytesCount); writer.Write(common.ByteArray, 0, bytesCount); }