/// <summary> /// Instead of filling the JoinCollector with iterators from all /// data sources, fill only the rightmost for this key. /// </summary> /// <remarks> /// Instead of filling the JoinCollector with iterators from all /// data sources, fill only the rightmost for this key. /// This not only saves space by discarding the other sources, but /// it also emits the number of key-value pairs in the preferred /// RecordReader instead of repeating that stream n times, where /// n is the cardinality of the cross product of the discarded /// streams for the given key. /// </remarks> /// <exception cref="System.IO.IOException"/> protected internal override void FillJoinCollector(K iterkey) { PriorityQueue <ComposableRecordReader <K, object> > q = GetRecordReaderQueue(); if (!q.IsEmpty()) { int highpos = -1; AList <ComposableRecordReader <K, object> > list = new AList <ComposableRecordReader < K, object> >(kids.Length); q.Peek().Key(iterkey); WritableComparator cmp = GetComparator(); while (0 == cmp.Compare(q.Peek().Key(), iterkey)) { ComposableRecordReader <K, object> t = q.Poll(); if (-1 == highpos || list[highpos].Id() < t.Id()) { highpos = list.Count; } list.AddItem(t); if (q.IsEmpty()) { break; } } ComposableRecordReader <K, object> t_1 = list.Remove(highpos); t_1.Accept(jc, iterkey); foreach (ComposableRecordReader <K, object> rr in list) { rr.Skip(iterkey); } list.AddItem(t_1); foreach (ComposableRecordReader <K, object> rr_1 in list) { if (rr_1.HasNext()) { q.AddItem(rr_1); } } } }
/// <summary> /// For all child RRs offering the key provided, obtain an iterator /// at that position in the JoinCollector. /// </summary> /// <exception cref="System.IO.IOException"/> protected internal virtual void FillJoinCollector(K iterkey) { if (!q.IsEmpty()) { q.Peek().Key(iterkey); while (0 == cmp.Compare(q.Peek().Key(), iterkey)) { ComposableRecordReader <K, object> t = q.Poll(); t.Accept(jc, iterkey); if (t.HasNext()) { q.AddItem(t); } else { if (q.IsEmpty()) { return; } } } } }