Пример #1
0
        public void OverFlowVolatile()
        {
            var sozuTable   = PrepareTests(2, /*firstLayerVolatile*/ true);
            var whatToWrite = new TxoPack(new Outpoint[120], new byte[8192]);
            var wa          = whatToWrite.GetResetWriter();

            for (var i = 0UL; i < 20; i++)
            {
                var txid     = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL + i));
                var outpoint = new Outpoint(txid, 0, 200);
                var payload  = new byte[200];
                payload[8]      = 8;
                payload[16 + i] = 42;
                wa.Write(in outpoint, payload);
            }
            sozuTable.Write(whatToWrite);

            var txoRead = new TxoPack(new Outpoint[120], new byte[8192]);

            sozuTable.Read(whatToWrite, txoRead);
            Assert.Equal(txoRead.Count, whatToWrite.Count);
            for (var i = 0; i < txoRead.Count; ++i)
            {
                Assert.True(txoRead.OutPoints[i].Equals(whatToWrite.OutPoints[i]));
                Assert.True(txoRead.Payloads.SequenceEqual(whatToWrite.Payloads));
            }
        }
Пример #2
0
        public void Read()
        {
            var path = @"Read-Test.store";

            File.Delete(path);
            File.Delete(Path.Combine(Path.GetDirectoryName(path), @"hot-" + Path.GetFileName(path)));
            using (var fw = File.OpenWrite(path))
            {
                fw.Write(new byte[]
                {
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                    0x01, 0x00, 0x00, 0x00, 0xf1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00,
                    0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00,
                    0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb8, 0x02, 0xb4, 0xb6, 0x09, 0x57, 0x75,
                    0x10, 0x92, 0xd2, 0x04, 0x1b, 0xac, 0xae, 0x6e, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0xd6, 0x17, 0xe6, 0x61, 0x8f, 0xa0, 0xb9, 0x49, 0x99, 0xf9, 0xb2, 0x89, 0xe1, 0xb1, 0x72, 0xac,
                    0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x92, 0x65, 0xbe, 0xf7, 0x46, 0xc3, 0x12,
                    0xd1, 0xa2, 0x27, 0xfa, 0x1b, 0x2f, 0x3e, 0x4c, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0xda, 0x26, 0x9a, 0x14, 0x9f, 0x07, 0xc9, 0xa8, 0x7d, 0xeb, 0xd7, 0xf7, 0x4f, 0x94, 0x9b, 0x7e
                });
            }
            var startHash = new Hash256(0xC000000000000000UL);
            var endHash   = new Hash256(0xF400000000000000UL);

            var sozuFactoryConfigs = new SozuFactoryConfig[1];

            sozuFactoryConfigs[0] = new SozuFactoryConfig(2, SozuFactory.TwoPhaseStoreType, 88);

            var whatToWrite = new TxoPack(new Outpoint[1], new byte[2048]);
            var firstHash   = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL));
            var wa          = whatToWrite.GetResetWriter();
            var outpoint    = new Outpoint(firstHash, 0, 8);
            var payload     = new byte[8];

            payload[0] = 42;
            wa.Write(in outpoint, payload);

            var txoRead = new TxoPack(new Outpoint[1], new byte[2048]);

            var sozuTable = new SozuFactory(null, startHash, endHash, sozuFactoryConfigs, path).Create();

            sozuTable.Read(whatToWrite, txoRead);

            Assert.Equal(txoRead.Count, whatToWrite.Count);
            Assert.True(txoRead.OutPoints[0].Equals(whatToWrite.OutPoints[0]));
            Assert.True(payload.AsSpan().SequenceEqual(txoRead.Payloads.Slice(0, 8)));
        }
Пример #3
0
        private void Work()
        {
            var txoIn  = TxoPack.Create();
            var txoOut = TxoPack.Create();

            // local array for capturing outpoints from inbox then sorting
            var outpoints = new Outpoint[Constants.MaxOutpointsCount];

            // array of inbox messages headers
            var messageHeaders = new byte[Constants.MaxOutpointsCount][];

            // array of inbox messages payloads
            // var payloads = new byte[MaxTxoCount][]; // not used in read request

            // provide index array for argsort
            var argsort = new int[Constants.MaxOutpointsCount];

            int txoCount = 0;

            while (!_source.Token.IsCancellationRequested)
            {
                var message = _inbox.Peek();
                if (message.Length > 0)
                {
                    // parse current message and add txo to txopack
                    var outpoint =
                        Outpoint.CreateNaked(
                            message.Slice(ClientServerMessage.PayloadStart, Outpoint.KeySizeInBytes));
                    outpoints[txoCount]      = outpoint;
                    messageHeaders[txoCount] = message.Slice(0, ClientServerMessage.PayloadStart).ToArray();
                    // payloads[messageCount] = message.Slice(ClientServerMessage.PayloadStart).ToArray();
                    // not used in read request
                    argsort[txoCount] = txoCount;
                    ++txoCount;

                    Debug.Assert(txoCount <= Constants.MaxOutpointsCount,
                                 "MaxTxoCount reached when looping inbox messages.");

                    _inbox.Next(message.Length);
                }
                else
                {
                    // current round of inbox message picking is over
                    Array.Sort(outpoints, argsort, 0, txoCount);
                    // sort txopack
                    ref var writer = ref txoIn.GetResetWriter();

                    // identify identical outpoint, and write querying txopack
                    ref var previous = ref outpoints[argsort[0]];
                    writer.Write(in previous, ReadOnlySpan <byte> .Empty);
                    for (ushort index = 1; index < txoCount; ++index)
                    {
                        ref var current = ref outpoints[argsort[index]];
                        if (previous != current)
                        {
                            previous = current;
                            writer.Write(in previous, ReadOnlySpan <byte> .Empty);
                        }
                    }
Пример #4
0
        /// <summary>
        /// Deserialize a TxoPack from Sector.
        /// </summary>
        /// <param name="sector">Sector to deserialize</param>
        /// <param name="pack">TxoPack to fill</param>
        /// <param name="childSectorIndex">sectorIndex of child</param>
        /// <remarks>
        /// Life-time of the response lasts until the next call to 'Read'.
        /// Size of TxoPack should be large enough to not overflow.
        /// </remarks>
        public static void Deserialize(this Sector sector, TxoPack pack, out SectorIndex childSectorIndex)
        {
            var sectorContent = sector.Contents;

            childSectorIndex =
                new SectorIndex(BitConverter.ToInt32(sectorContent.Slice(ChildSectorIndexStart, ChildSectorIndexSizeInBytes)));
            var numberOfTxo = BitConverter.ToInt32(sectorContent.Slice(TxoCountStart, TxoCountSizeInBytes));
            var payloadLengthAccumulator = 0;

            ref var writer = ref pack.GetResetWriter();
Пример #5
0
        public void Write(TxoPack txos, SectorIndex sectorIndex, Hash256 sectorHash)
        {
            if (_config.ImplicitSectors)
            {
                throw new InvalidOperationException();
            }

            var partition = PartitionByExplicitSector(sectorIndex, sectorHash, txos.GetForwardIterator());

            Write(partition, txos);
        }
Пример #6
0
        public void Write(TxoPack txos)
        {
            if (!_config.ImplicitSectors)
            {
                throw new InvalidOperationException();
            }

            var partition = PartitionByImplicitSector(txos.GetForwardIterator());

            Write(partition, txos);
        }
Пример #7
0
        /// <summary>
        /// Reading layers with explicit outpoint ranges.
        /// </summary>
        /// <param name="txoIn">txopack providing outpoints requesting a read</param>
        /// <param name="sectorIndex">Identifies the first sector to be read.</param>
        /// <param name="sectorHash">Identifies the hash range of the sector.</param>
        /// <param name="txoOut">output txoPack to collect read results</param>
        private void Read(TxoPack txoIn, SectorIndex sectorIndex, Hash256 sectorHash, TxoPack txoOut)
        {
            if (_config.ImplicitSectors)
            {
                throw new InvalidOperationException();
            }

            var partition = PartitionByExplicitSector(sectorIndex, sectorHash, txoIn.GetForwardIterator());

            Read(partition, txoOut);
        }
Пример #8
0
        public void Read(TxoPack txoIn, TxoPack txoOut)
        {
            if (!_config.ImplicitSectors)
            {
                throw new InvalidOperationException();
            }

            txoOut.Clear();
            var partition = PartitionByImplicitSector(txoIn.GetForwardIterator());

            Read(partition, txoOut);
        }
Пример #9
0
        private void Write(IEnumerable <SectorRange> partition, TxoPack txos)
        {
            // 'partition' is expected to be aligned with local sectors
            foreach (var range in partition)
            {
                var childSectorIndex = SectorIndex.Unknown;
                if (_store.TryRead(range.Index, out var sector))
                {
                    sector.Deserialize(_deserialized, out childSectorIndex);
                }
                else
                {
                    _deserialized.Clear(); // make empty TxoPack
                }

                _deserialized.AddOrMerge(txos.GetForwardIterator(), _merged, _lineage);

                // extra TXOs fit locally
                if (_merged.IsOverflowing(sector.Length))
                {
                    if (_subTable == null)
                    {
                        // Normally everything should have been set up during initialization
                        throw new SozuTableOverflowException();
                    }

                    // TODO: [tandabany] WIP for the overflowing part
                    _merged.Split((int)(sector.Length * .5), _kept, _flowDown);

                    if (childSectorIndex.IsUnknown())
                    {
                        var deltaBitDepth = _subTable._config.SectorBitDepth - _config.SectorBitDepth;
                        childSectorIndex = _subTable._store.AllocateSectors(1 << deltaBitDepth);
                    }

                    sector.Serialize(_kept, childSectorIndex);
                    _store.Write(range.Index, sector);

                    _subTable.Write(_flowDown, childSectorIndex, range.LeftTxid);
                }
                else
                {
                    sector.Serialize(_merged, childSectorIndex);
                    _store.Write(range.Index, sector);
                }
            }
        }
Пример #10
0
        public void AddWithoutMergeTest()
        {
            const int testSize       = 5;
            var       txoPack        = MakeRandomTxoPack(testSize);
            var       anotherTxoPack = MakeRandomTxoPack(testSize);

            var resultTxoPack = TxoPack.Create(2);

            txoPack.AddOrMerge(anotherTxoPack.GetForwardIterator(), resultTxoPack, null);

            // ensure number of outpoints
            Assert.True(testSize * 2 == resultTxoPack.Count, "Merged outpoints total number mismatch.");


            // ensure that merged TxoPack has sorted keys;
            var     iter = resultTxoPack.GetForwardIterator();
            ref var op   = ref iter.Current;
Пример #11
0
        public void WriteVolatile()
        {
            var sozuTable   = PrepareTests(1, /*firstLayerVolatile*/ true);
            var whatToWrite = new TxoPack(new Outpoint[1], new byte[2048]);
            var firstHash   = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL));
            var wa          = whatToWrite.GetResetWriter();
            var outpoint    = new Outpoint(firstHash, 0, 100);
            var payload     = new byte[100];

            payload[0] = 42;
            wa.Write(in outpoint, payload);

            sozuTable.Write(whatToWrite);
            var txoRead = new TxoPack(new Outpoint[1], new byte[2048]);

            sozuTable.Read(whatToWrite, txoRead);
            Assert.Equal(txoRead.Count, whatToWrite.Count);
            Assert.True(txoRead.OutPoints[0].Equals(whatToWrite.OutPoints[0]));
            Assert.True(txoRead.Payloads.SequenceEqual(whatToWrite.Payloads));
        }
Пример #12
0
        /// <param name="config"></param>
        /// <param name="lineage"></param>
        /// <param name="store"></param>
        /// <param name="subTable"></param>
        public SozuTable(SozuConfig config, ILineage lineage, ISectorStore store, SozuTable subTable = null)
        {
            _config   = config;
            _lineage  = lineage;
            _store    = store;
            _subTable = subTable;

            _residue      = TxoPack.Create();
            _rangeOutputs = TxoPack.Create();
            _deserialized = TxoPack.Create();
            _complement   = TxoPack.Create();
            _kept         = TxoPack.Create();
            _flowDown     = TxoPack.Create();
            _merged       = TxoPack.Create(2);
            store.Initialize();
            if (config.ImplicitSectors && !store.HasSectors())
            {
                store.AllocateSectors(1 << config.SectorBitDepth);
                EnsurePersistence();
            }
        }
Пример #13
0
        private void Read(IEnumerable <SectorRange> partition, TxoPack outputs)
        {
            foreach (var range in partition)
            {
                var sector = _store.Read(range.Index);
                sector.Deserialize(_deserialized, out var childSectorIndex);

                // We need not to overwrite txos, but put inside the payload found
                _deserialized.Filter(range.Outpoints, _kept, _residue, _complement);

                if (_residue.Count == 0 || childSectorIndex.IsUnknown() || _subTable == null)
                {
                    _flowDown.Clear();
                }
                else
                {
                    // Recursive exploration
                    _subTable.Read(_residue, childSectorIndex, range.LeftTxid, _flowDown);
                }
                _flowDown.AddOrMerge(_kept.GetForwardIterator(), outputs, null);
            } // foreach (var range in partition)
        }
Пример #14
0
 public SectorRange(SectorIndex index, Hash256 leftTxid, TxoPack outpoints)
 {
     Index     = index;
     LeftTxid  = leftTxid;
     Outpoints = outpoints;
 }