public void OnNext(StreamMessage <TKey, TSpray> batch) { if (this.multicast) { for (int i = 0; i < this.totalBranches; i++) { this.pool.Get(out StreamMessage <TKey, TSpray> _outbatch); _outbatch.CloneFrom(batch, false); this.Observers[i].OnNext(_outbatch); } batch.Free(); return; } // If this batch contains any punctuation, we need to broadcast them to all observers. StreamMessage <TKey, TSpray> broadcastMaster = null; for (int i = batch.Count - 1; i >= 0; i--) { if (batch.vother.col[i] < 0) { // Create a master broadcast batch that we can clone from. // TODO: maybe it's better to allocate a new batch without deleted data gaps? this.pool.Get(out broadcastMaster); broadcastMaster.CloneFrom(batch); broadcastMaster.bitvector = broadcastMaster.bitvector.MakeWritable(this.pool.bitvectorPool); // Since we only care about punctuations, delete everything for (int deletingIndex = 0; deletingIndex <= broadcastMaster.Count >> 6; deletingIndex++) { broadcastMaster.bitvector.col[deletingIndex] = ~(0L); } break; } } int originalBatchRecipient; if (this.spraySortOrderComparer == null) { originalBatchRecipient = this.l1_spray; this.Observers[this.l1_spray].OnNext(batch); this.l1_spray++; if (this.l1_spray == this.totalBranches) { this.l1_spray = 0; } } else { if (this.first || (this.spraySortOrderComparerFunc(this.lastElem, batch[0]) == 0)) { this.first = false; this.lastElem = batch[batch.Count - 1]; originalBatchRecipient = this.l1_spray; this.Observers[this.l1_spray].OnNext(batch); } else { this.lastElem = batch[batch.Count - 1]; this.l1_spray++; if (this.l1_spray == this.totalBranches) { this.l1_spray = 0; } originalBatchRecipient = this.l1_spray; this.Observers[this.l1_spray].OnNext(batch); } } if (broadcastMaster != null) { // Broadcast to all except the observer that received the current batch int lastBroadcastIndex = this.totalBranches - 1; if (lastBroadcastIndex == originalBatchRecipient) { lastBroadcastIndex--; } for (int i = 0; i < this.totalBranches; i++) { if (i == originalBatchRecipient) { continue; // skip observer that received the current batch } if (i == lastBroadcastIndex) { this.Observers[i].OnNext(broadcastMaster); } else { this.pool.Get(out StreamMessage <TKey, TSpray> broadcastClone); broadcastClone.CloneFrom(broadcastMaster); this.Observers[i].OnNext(broadcastClone); } } } }