@Override public Void call() throws Exception { boolean didRun = false; try { acceptSolutions(); if (op.runHashJoin(context, state)) { didRun = true; doHashJoin(); } // Done. return null; } finally { if (didRun) { /* * The state needs to be released each time this operator * runs in order to discard the intermediate solutions * buffered on the hash index that were just joined against * the access path. If we do not discard the state after * processing the intermediate solutions, then they will * continue to accumulate and we will over-report joins * (duplicate solutions will be output for things already in * the hash index the next time we evaluate the hash join * against the access path). */ state.release(); } sink.close(); if (sink2 != null) sink2.close(); } }