mirror of
https://github.com/opengram-server/opengram.git
synced 2026-08-09 07:43:23 +03:00
80 lines
3.0 KiB
C#
80 lines
3.0 KiB
C#
// -----------------------------------------------------------------------
|
|
// <copyright file="SimpleStreamSerializer.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// </copyright>
|
|
// -----------------------------------------------------------------------
|
|
|
|
using System.IO;
|
|
|
|
namespace Microsoft.Cuckoo;
|
|
|
|
/// <summary>
|
|
/// Simple stream serializer that writes the cuckoo filter directly out
|
|
/// to a stream. Investigate <see cref="GzipStreamSerializer" /> for a more
|
|
/// storage-friendly version.
|
|
/// </summary>
|
|
public class SimpleStreamSerializer : ICuckooSerializer
|
|
{
|
|
/// <summary>
|
|
/// Deserializes the CuckooFilter to from a stream.
|
|
/// </summary>
|
|
/// <param name="source">Source stream to read</param>
|
|
/// <param name="hashAlgorithm">Hash algorithm</param>
|
|
public virtual CuckooFilter Deserialize(Stream source, IHashAlgorithm hashAlgorithm = null)
|
|
{
|
|
var paramsReadBuffer = new byte[16];
|
|
//source.Read(paramsReadBuffer, 0, 16);
|
|
source.ReadExactly(paramsReadBuffer);
|
|
|
|
var entriesPerBucket = ReadBigEndianUint(paramsReadBuffer, 0);
|
|
var fingerprintLength = ReadBigEndianUint(paramsReadBuffer, 4);
|
|
var buckets = ReadBigEndianUint(paramsReadBuffer, 8);
|
|
var maxKicks = ReadBigEndianUint(paramsReadBuffer, 12);
|
|
|
|
var contents = new byte[buckets * entriesPerBucket * fingerprintLength];
|
|
//source.Read(contents, 0, contents.Length);
|
|
source.ReadExactly(contents);
|
|
|
|
return new CuckooFilter(
|
|
contents,
|
|
entriesPerBucket,
|
|
fingerprintLength,
|
|
maxKicks,
|
|
hashAlgorithm);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Serializes the CuckooFilter to a stream.
|
|
/// </summary>
|
|
/// <param name="target">Target stream to write to</param>
|
|
/// <param name="filter">Filter to serialize</param>
|
|
public virtual void Serialize(Stream target, CuckooFilter filter)
|
|
{
|
|
var writeBuffer = new byte[16];
|
|
WriteBigEndianUint(writeBuffer, filter.EntriesPerBucket, 0);
|
|
WriteBigEndianUint(writeBuffer, filter.FingerprintLength, 4);
|
|
WriteBigEndianUint(writeBuffer, filter.Buckets, 8);
|
|
WriteBigEndianUint(writeBuffer, filter.MaxKicks, 12);
|
|
target.Write(writeBuffer, 0, 16);
|
|
target.Write(filter.Contents, 0, filter.Contents.Length);
|
|
}
|
|
|
|
private static uint ReadBigEndianUint(byte[] target, int offset)
|
|
{
|
|
uint x = 0;
|
|
x |= (uint)(target[offset] << 24);
|
|
x |= (uint)(target[offset + 1] << 16);
|
|
x |= (uint)(target[offset + 2] << 8);
|
|
x |= target[offset + 3];
|
|
|
|
return x;
|
|
}
|
|
|
|
private static void WriteBigEndianUint(byte[] target, uint number, int offset)
|
|
{
|
|
target[offset] = (byte)(number >> 24);
|
|
target[offset + 1] = (byte)(number >> 16);
|
|
target[offset + 2] = (byte)(number >> 8);
|
|
target[offset + 3] = (byte)number;
|
|
}
|
|
} |