/// <summary>Get a list of block lists to be replicated.</summary> /// <remarks> /// Get a list of block lists to be replicated. The index of block lists /// represents its replication priority. Replication index will be tracked for /// each priority list separately in priorityToReplIdx map. Iterates through /// all priority lists and find the elements after replication index. Once the /// last priority lists reaches to end, all replication indexes will be set to /// 0 and start from 1st priority list to fulfill the blockToProces count. /// </remarks> /// <param name="blocksToProcess">- number of blocks to fetch from underReplicated blocks. /// </param> /// <returns> /// Return a list of block lists to be replicated. The block list index /// represents its replication priority. /// </returns> public virtual IList <IList <Block> > ChooseUnderReplicatedBlocks(int blocksToProcess ) { lock (this) { // initialize data structure for the return value IList <IList <Block> > blocksToReplicate = new AList <IList <Block> >(Level); for (int i = 0; i < Level; i++) { blocksToReplicate.AddItem(new AList <Block>()); } if (Size() == 0) { // There are no blocks to collect. return(blocksToReplicate); } int blockCount = 0; for (int priority = 0; priority < Level; priority++) { // Go through all blocks that need replications with current priority. UnderReplicatedBlocks.BlockIterator neededReplicationsIterator = Iterator(priority ); int replIndex = priorityToReplIdx[priority]; // skip to the first unprocessed block, which is at replIndex for (int i_1 = 0; i_1 < replIndex && neededReplicationsIterator.HasNext(); i_1++) { neededReplicationsIterator.Next(); } blocksToProcess = Math.Min(blocksToProcess, Size()); if (blockCount == blocksToProcess) { break; } // break if already expected blocks are obtained // Loop through all remaining blocks in the list. while (blockCount < blocksToProcess && neededReplicationsIterator.HasNext()) { Block block = neededReplicationsIterator.Next(); blocksToReplicate[priority].AddItem(block); replIndex++; blockCount++; } if (!neededReplicationsIterator.HasNext() && neededReplicationsIterator.GetPriority () == Level - 1) { // reset all priorities replication index to 0 because there is no // recently added blocks in any list. for (int i_2 = 0; i_2 < Level; i_2++) { priorityToReplIdx[i_2] = 0; } break; } priorityToReplIdx[priority] = replIndex; } return(blocksToReplicate); } }
/// <summary>Determine whether or not a block is in a level without changing the API. /// </summary> /// <remarks> /// Determine whether or not a block is in a level without changing the API. /// Instead get the per-level iterator and run though it looking for a match. /// If the block is not found, an assertion is thrown. /// This is inefficient, but this is only a test case. /// </remarks> /// <param name="queues">queues to scan</param> /// <param name="block">block to look for</param> /// <param name="level">level to select</param> private void AssertInLevel(UnderReplicatedBlocks queues, Block block, int level) { UnderReplicatedBlocks.BlockIterator bi = queues.Iterator(level); while (bi.HasNext()) { Block next = bi.Next(); if (block.Equals(next)) { return; } } NUnit.Framework.Assert.Fail("Block " + block + " not found in level " + level); }