Пример #1
0
        /// <summary>
        /// Try Take element from cached queue.
        /// </summary>
        /// <param name="height">Height of block info needed</param>
        /// <param name="blockInfo"></param>
        /// <param name="isCacheSizeLimited">Use <see cref="_cachedBoundedCapacity"/> as cache count threshold if true.</param>
        /// <returns></returns>
        public bool TryTake(long height, out IBlockInfo blockInfo, bool isCacheSizeLimited)
        {
            // clear outdated data
            var cachedInQueue = CacheBlockInfoBeforeHeight(height);
            // isCacheSizeLimited means minimal caching size limit, so that most nodes have this block.
            var lastQueuedHeight = ToBeIndexedBlockInfoQueue.LastOrDefault()?.Height ?? 0;

            if (cachedInQueue && !(isCacheSizeLimited && lastQueuedHeight < height + CrossChainConstants.MinimalBlockInfoCacheThreshold))
            {
                var res = ToBeIndexedBlockInfoQueue.TryTake(out blockInfo,
                                                            CrossChainConstants.WaitingIntervalInMillisecond);
                if (res)
                {
                    CacheBlockInfo(blockInfo);
                }
                return(res);
            }

            blockInfo = LastBlockInfoInCache(height);
            if (blockInfo != null)
            {
                return(!isCacheSizeLimited ||
                       ToBeIndexedBlockInfoQueue.Count + CachedIndexedBlockInfoQueue.Count(ci => ci.Height >= height)
                       >= CrossChainConstants.MinimalBlockInfoCacheThreshold);
            }

            return(false);
        }
Пример #2
0
        public bool TryAdd(IBlockInfo blockInfo)
        {
            if (ToBeIndexedBlockInfoQueue.Count() >= _cachedBoundedCapacity)
            {
                return(false);
            }
            // thread unsafe in some extreme cases, but it can be covered with caching mechanism.
            if (blockInfo.Height != TargetChainHeight())
            {
                return(false);
            }
            var res = ToBeIndexedBlockInfoQueue.TryAdd(blockInfo);

            return(res);
        }
Пример #3
0
        public long TargetChainHeight()
        {
            var lastQueuedBlockInfo = ToBeIndexedBlockInfoQueue.LastOrDefault();

            if (lastQueuedBlockInfo != null)
            {
                return(lastQueuedBlockInfo.Height + 1);
            }
            var lastCachedBlockInfo = CachedIndexedBlockInfoQueue.LastOrDefault();

            if (lastCachedBlockInfo != null)
            {
                return(lastCachedBlockInfo.Height + 1);
            }
            return(_initTargetHeight);
        }
Пример #4
0
 /// <summary>
 /// Cache outdated data. The block with height lower than <paramref name="height"/> is outdated.
 /// </summary>
 /// <param name="height"></param>
 private bool CacheBlockInfoBeforeHeight(long height)
 {
     while (true)
     {
         var blockInfo = ToBeIndexedBlockInfoQueue.FirstOrDefault();
         if (blockInfo == null || blockInfo.Height > height)
         {
             return(false);
         }
         if (blockInfo.Height == height)
         {
             return(true);
         }
         var res = ToBeIndexedBlockInfoQueue.TryTake(out blockInfo, CrossChainConstants.WaitingIntervalInMillisecond);
         if (res)
         {
             CacheBlockInfo(blockInfo);
         }
     }
 }