Probes items of the left-hand operand against the cached hash set, lazily extending the set from the cached right-hand iterator on misses. @param iter1 left-hand iterator @param cache active cache (set and iter must be initialized) @param qc query context @return true on first hit, {@code fa
(final Iter iter1, final CmpCache cache, final QueryContext qc)
| 62 | * @throws QueryException query exception |
| 63 | */ |
| 64 | private static boolean probe(final Iter iter1, final CmpCache cache, final QueryContext qc) |
| 65 | throws QueryException { |
| 66 | final HashItemSet set = cache.set; |
| 67 | Iter ir2 = cache.iter; |
| 68 | |
| 69 | // loop through input items |
| 70 | for(Item item1; (item1 = qc.next(iter1)) != null;) { |
| 71 | // check if item has already been cached |
| 72 | if(set.contains(item1)) { |
| 73 | cache.hit = true; |
| 74 | return true; |
| 75 | } |
| 76 | |
| 77 | // cache remaining items (stop after first hit) |
| 78 | if(ir2 != null) { |
| 79 | for(Item item2; (item2 = qc.next(ir2)) != null;) { |
| 80 | set.add(item2); |
| 81 | if(set.contains(item1)) { |
| 82 | cache.hit = true; |
| 83 | return true; |
| 84 | } |
| 85 | } |
| 86 | // iterator exhausted, all items are cached |
| 87 | cache.iter = null; |
| 88 | ir2 = null; |
| 89 | } |
| 90 | } |
| 91 | return false; |
| 92 | } |
| 93 | |
| 94 | @Override |
| 95 | public CmpG copy(final CompileContext cc, final IntObjectMap<Var> vm) { |