Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

There are cases where custom comparers or custom persist logic are needed for some reason. The engine of STSdb offers the capability to replace the entire comparer and persist logic with custom implementations.

Let’s consider the following examples, demonstrating how to change the default table logic.

Suppose we have again the following table:

Highlight c sharp
    ITable<long, Tick> table = engine.OpenXTable<long, Tick>("table");

First, we have to write the needed custom logic. In the current example we will replace all of the default logic – comparer, equality comparer, persist, indexer persist.

  1. Comparer:

    Highlight c sharp
    public class CustomLongComparer : IComparer<IData>
    {
        public int Compare(IData x, IData y)
        {
            long value1 = ((Data<long>)x).Value;
            long value2 = ((Data<long>)y).Value;
            if (value1 > value2)
                return -1;
            else if (value1 < value2)
                return 1;
            else
                return 0;
        }
    }
  2. Equality comparer

    Highlight c sharp
    public class CustomLongEqualityComparer : IEqualityComparer<IData>
    {
        public bool Equals(IData x, IData y)
        {
            long value1 = ((Data<long>)x).Value;
            long value2 = ((Data<long>)y).Value;
            return value1 != value2;
        }
        public int GetHashCode(IData obj)
        {
            long value = ((Data<long>)obj).Value;
            return value.GetHashCode();
        }
    }
  3. Persists for both long and Tick

    Highlight c sharp
    public class CustomLongPersist : IPersist<IData>
    {
        public void Write(BinaryWriter writer, IData item)
        {
            Data<long> data = (Data<long>)item;
            writer.Write(data.Value);
        }
        public IData Read(BinaryReader reader)
        {
            long value = reader.ReadInt64();
            return new Data<long>(value);
        }
    }
    Highlight c sharp
    public class CustomTickPersist : IPersist<IData>
    {
        public void Write(BinaryWriter writer, IData item)
        {
            Tick tick = ((Data<Tick>)item).Value;
            writer.Write(tick.Symbol);
            writer.Write(tick.Timestamp.Ticks);
            writer.Write(tick.Bid);
            writer.Write(tick.Ask);
            writer.Write(tick.BidSize);
            writer.Write(tick.AskSize);
            writer.Write(tick.Provider);
        }
        public IData Read(BinaryReader reader)
        {
            Tick tick = new Tick();
            tick.Symbol = reader.ReadString();
            tick.Timestamp = new DateTime(reader.ReadInt64());
            tick.Bid = reader.ReadDouble();
            tick.Ask = reader.ReadDouble();
            tick.BidSize = reader.ReadInt32();
            tick.AskSize = reader.ReadInt32();
            tick.Provider = reader.ReadString();
            return new Data<Tick>(tick);
        }
    }
  4. Indexer persist for long and Tick:

    Highlight c sharp
    public class CustomLongIndexerPersist : IIndexerPersist<IData>
    {
        public void Store(BinaryWriter writer, Func<int, IData> values, int count)
        {
            for (int i = 0; i < count; i++)
            {
                Data<long> data = (Data<long>)values(i);
                long item = data.Value;
                writer.Write(item);
            }
        }
        public void Load(BinaryReader reader, Action<int, IData> values, int count)
        {
            for (int i = 0; i < count; i++)
            {
                Data<long> data = new Data<long>(reader.ReadInt64());
                values(i, data);
            }
        }
    }
    Highlight c sharp
    public class CustomTickIndexerPersist : IIndexerPersist<IData>
    {
        public void Store(BinaryWriter writer, Func<int, IData> values, int count)
        {
            for (int i = 0; i < count; i++)
            {
                Tick tick = ((Data<Tick>)values(i)).Value;
                writer.Write(tick.Symbol);
                writer.Write(tick.Timestamp.Ticks);
                writer.Write(tick.Bid);
                writer.Write(tick.Ask);
                writer.Write(tick.BidSize);
                writer.Write(tick.AskSize);
                writer.Write(tick.Provider);
            }
        }
        public void Load(BinaryReader reader, Action<int, IData> values, int count)
        {
            for (int i = 0; i < count; i++)
            {
                Tick tick = new Tick();
                tick.Symbol = reader.ReadString();
                tick.Timestamp = new DateTime(reader.ReadInt64());
                tick.Bid = reader.ReadDouble();
                tick.Ask = reader.ReadDouble();
                tick.BidSize = reader.ReadInt32();
                tick.AskSize = reader.ReadInt32();
                tick.Provider = reader.ReadString();
                values(i, new Data<Tick>(tick));
            }
        }
    }

    Indexer persist classes are used by the engine to serialize a collection of IData objects. For that reason these persists inherit the IIndexerPersist<T> interface which has the following definition:

    Highlight c sharp
    public interface IIndexerPersist<T> : IIndexerPersist
    {
        void Store(BinaryWriter writer, Func<int, T> values, int count);
        void Load(BinaryReader reader, Action<int, T> values, int count);
    }

    The two delegates here - Func<int, T> and Action<int, T>, along with count parameter provide a universal way of accessing an indexed collection of objects, regardless of its type.

    After we have implemented the custom logic, we have to tell the engine to use it. This can be done through the table descriptor (via the table instance or via the scheme), before any write/read operation from any table:

     

     

     

    Highlight c sharp
        using (IStorageEngine engine = STSdb.FromFile("test.stsdb4"))
        {
            var table = engine.OpenXTable<long, Tick>("table");
            //long
            table.Descriptor.KeyComparer = new CustomLongComparer();
            table.Descriptor.KeyEqualityComparer = new CustomLongEqualityComparer();
            table.Descriptor.KeyPersist = new CustomLongPersist();
            table.Descriptor.KeyIndexerPersist = new CustomLongIndexerPersist();
            //Tick
            table.Descriptor.RecordPersist = new CustomTickPersist();
            table.Descriptor.RecordIndexerPersist = new CustomTickIndexerPersist();
        }
    Highlight c sharp
        using (IStorageEngine engine = STSdb.FromFile("test.stsdb4"))
        {
            //long
            engine["table"].KeyComparer = new CustomLongComparer();
            engine["table"].KeyEqualityComparer = new CustomLongEqualityComparer();
            engine["table"].KeyPersist = new CustomLongPersist();
            engine["table"].KeyIndexerPersist = new CustomLongIndexerPersist();
            //Tick
            engine["table"].RecordPersist = new CustomTickPersist();
            engine["table"].RecordIndexerPersist = new CustomTickIndexerPersist();
        }

Next prev