public bool MonitorProducers(SyncQueue <T>[] input, out T item) { T buff; // -1 is a non-index value which denotes that all queues are closed to enqueue while (SyncQueue <T> .TryTakeFromAny(input, out buff) != -1) { if (buff.Number == sequenceNumber) { item = buff; sequenceNumber++; return(true); } else if (lookAheadBuffer.Any(b => b.Number == sequenceNumber)) { lookAheadBuffer.Add(buff); item = lookAheadBuffer.First(); lookAheadBuffer.RemoveWhere(b => b.Number == sequenceNumber); sequenceNumber++; return(true); } else { lookAheadBuffer.Add(buff); } } // lookAheadBuffer may still containing items while they arrived out of order while (lookAheadBuffer.Count() != 0) { // must be always true in normal operation if (lookAheadBuffer.Any(b => b.Number == sequenceNumber)) { item = lookAheadBuffer.First(); lookAheadBuffer.RemoveWhere(b => b.Number == sequenceNumber); sequenceNumber++; return(true); } else { item = default(T); return(false); } } item = default(T); return(false); }
static void StartPipeline(string filePath, long blockSize) { int threadCount; int boundedCap; SetPipelineParams(blockSize, out threadCount, out boundedCap); var dataBlocks = new SyncQueue <Block>(boundedCap); var blocksToCompute = new SyncQueue <Block> [threadCount]; for (int i = 0; i < threadCount; i++) { blocksToCompute[i] = new SyncQueue <Block>(boundedCap); } Thread readStage; Thread[] computeStages; Thread multiplexStage; computeStages = new Thread[threadCount]; readStage = new Thread(() => HashProcessor.ReadFile(dataBlocks, filePath, blockSize)); readStage.Name = "Read Thread"; readStage.Start(); for (int i = 0; i < threadCount; i++) { int k = i; // for correct variable capturing computeStages[i] = new Thread(() => HashProcessor.ComputeHashes(dataBlocks, blocksToCompute[k])); computeStages[i].Name = "Thread " + i + 1; computeStages[i].Start(); } multiplexStage = new Thread(() => HashProcessor.MultiplexProducers(blocksToCompute)); multiplexStage.Name = "Mult Thread"; multiplexStage.Start(); readStage.Join(); foreach (var stage in computeStages) { stage.Join(); } multiplexStage.Join(); }
public static void ComputeHashes(SyncQueue <Block> input, SyncQueue <Block> output) { try { Block block; while (input.TryDequeue(out block)) { block.ComputeHash(); output.Enqueue(block); } } catch (Exception ex) { fault = true; // signal producer to stop Console.WriteLine(ex.ToString()); } finally { output.Close(); } }
public static void ReadFile(SyncQueue <Block> output, string filePath, long blockSize) { try { foreach (var block in FileReader.GetNextBlock(filePath, blockSize)) { if (fault) { break; // stop if any errors occurred while consuming } output.Enqueue(block); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { output.Close(); } }