/// <param name="start">Context provided by the upper layer.</param> /// <param name="leftTxid">Context provided by the upper layer.</param> /// <param name="iter">Should be sorted in increasing order.</param> private IEnumerable <SectorRange> PartitionByExplicitSector( SectorIndex start, Hash256 leftTxid, TxoForwardIterator iter) { var localSectorTxoPackWriteAnchor = _rangeOutputs.GetResetWriter(); var localSectorHash = leftTxid; // TODO: [vermorel] To be replaced by a regular 'foreach' for (; iter.EndNotReached; iter.MoveNext()) { var outpoint = iter.Current; var canonicalHash = outpoint.Txid.Truncate(_config.SectorBitDepth); Debug.Assert(localSectorHash.CompareTo(canonicalHash) <= 0, "Unordered outpoints."); if (!canonicalHash.Equals(localSectorHash)) { // reach here means current outpoint from iterator is in different sector than // localSectorHash, thus we need to flush what were written so far in writer if (!localSectorTxoPackWriteAnchor.IsEmpty) { // this works because subSectors are all allocated once var rangeIndex = start.GetNext(localSectorHash.Top(_config.SectorBitDepth) - leftTxid.Top(_config.SectorBitDepth)); yield return(new SectorRange(rangeIndex, localSectorHash, _rangeOutputs)); // recycling the list localSectorTxoPackWriteAnchor = _rangeOutputs.GetResetWriter(); } // flush done, we switch to next leftTxid localSectorHash = canonicalHash; } localSectorTxoPackWriteAnchor.Write(in outpoint, ReadOnlySpan <byte> .Empty); } if (!localSectorTxoPackWriteAnchor.IsEmpty) { var rangeIndex = start.GetNext(localSectorHash.Top(_config.SectorBitDepth) - leftTxid.Top(_config.SectorBitDepth)); yield return(new SectorRange(rangeIndex, localSectorHash, _rangeOutputs)); } }
/// <summary> /// Interprets the wrapped hash as a large unsigned integer, and /// returns the largest 'n' bits as an integer. /// <see cref="Hash256.Top"/> /// </summary> public int Top(int n) { return(_hash.Top(n)); }