public DeferredChainStateCursor(IChainState chainState, IStorageManager storageManager) { this.chainState = chainState; this.storageManager = storageManager; headers = new DeferredDictionary <UInt256, ChainedHeader>( blockHash => { ChainedHeader header; return(Tuple.Create(chainState.TryGetHeader(blockHash, out header), header)); }); unspentTxes = new WorkQueueDictionary <UInt256, UnspentTx>( txHash => { UnspentTx unspentTx; return(Tuple.Create(chainState.TryGetUnspentTx(txHash, out unspentTx), unspentTx)); }); unspentTxOutputs = new WorkQueueDictionary <TxOutputKey, TxOutput>( txOutputKey => { TxOutput txOutput; return(Tuple.Create(chainState.TryGetUnspentTxOutput(txOutputKey, out txOutput), txOutput)); }); blockSpentTxes = new DeferredDictionary <int, BlockSpentTxes>( blockHeight => { BlockSpentTxes spentTxes; return(Tuple.Create(chainState.TryGetBlockSpentTxes(blockHeight, out spentTxes), spentTxes)); }); blockUnmintedTxes = new DeferredDictionary <UInt256, IImmutableList <UnmintedTx> >( blockHash => { IImmutableList <UnmintedTx> unmintedTxes; return(Tuple.Create(chainState.TryGetBlockUnmintedTxes(blockHash, out unmintedTxes), unmintedTxes)); }); utxoApplier = new ActionBlock <WorkQueueDictionary <UInt256, UnspentTx> .WorkItem>( workItem => { workItem.Consume( (operation, unspentTxHash, unspentTx) => { lock (parentCursor) switch (operation) { case WorkQueueOperation.Nothing: break; case WorkQueueOperation.Add: if (!parentCursor.TryAddUnspentTx(unspentTx)) { throw new InvalidOperationException(); } break; case WorkQueueOperation.Update: if (!parentCursor.TryUpdateUnspentTx(unspentTx)) { throw new InvalidOperationException(); } break; case WorkQueueOperation.Remove: if (!parentCursor.TryRemoveUnspentTx(unspentTxHash)) { throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } }); }); unspentTxes.WorkQueue.LinkTo(utxoApplier, new DataflowLinkOptions { PropagateCompletion = true }); utxoApplier2 = new ActionBlock <WorkQueueDictionary <TxOutputKey, TxOutput> .WorkItem>( workItem => { workItem.Consume( (operation, txOutputKey, txOutput) => { lock (parentCursor) switch (operation) { case WorkQueueOperation.Nothing: break; case WorkQueueOperation.Add: if (!parentCursor.TryAddUnspentTxOutput(txOutputKey, txOutput)) { throw new InvalidOperationException(); } break; case WorkQueueOperation.Update: throw new InvalidOperationException(); case WorkQueueOperation.Remove: if (!parentCursor.TryRemoveUnspentTxOutput(txOutputKey)) { throw new InvalidOperationException(); } break; default: throw new InvalidOperationException(); } }); }); unspentTxOutputs.WorkQueue.LinkTo(utxoApplier2, new DataflowLinkOptions { PropagateCompletion = true }); }
public WorkQueueDictionary(Func <TKey, Tuple <bool, TValue> > parentTryGetValue, Func <IEnumerable <KeyValuePair <TKey, TValue> > > parentEnumerator = null) { this.parentDictionary = new DeferredDictionary <TKey, TValue>(parentTryGetValue, parentEnumerator); this.workQueue = new BufferBlock <WorkItem>(); this.workByKey = new Dictionary <TKey, WorkItem>(); }