@Override public void evaluate(VectorizedRowBatch batch) { int n = batch.size; if (n <= 0) { return; } VectorExpression childExpr1 = this.childExpressions[0]; boolean prevSelectInUse = batch.selectedInUse; // Save the original selected vector int[] sel = batch.selected; if (batch.selectedInUse) { System.arraycopy(sel, 0, initialSelected, 0, n); } else { for (int i = 0; i < n; i++) { initialSelected[i] = i; sel[i] = i; } batch.selectedInUse = true; } childExpr1.evaluate(batch); // Preserve the selected reference and size values generated // after the first child is evaluated. int sizeAfterFirstChild = batch.size; int[] selectedAfterFirstChild = batch.selected; // Calculate unselected ones in last evaluate. for (int j = 0; j < n; j++) { tmp[initialSelected[j]] = 0; } for (int j = 0; j < batch.size; j++) { tmp[selectedAfterFirstChild[j]] = 1; } int unselectedSize = 0; for (int j = 0; j < n; j++) { int i = initialSelected[j]; if (tmp[i] == 0) { unselected[unselectedSize++] = i; } } int newSize = sizeAfterFirstChild; batch.selected = unselected; batch.size = unselectedSize; if (unselectedSize > 0) { // Evaluate subsequent child expression over unselected ones only. final int childrenCount = this.childExpressions.length; int childIndex = 1; while (true) { boolean isLastChild = (childIndex + 1 >= childrenCount); // When we have yet another child beyond the current one... save unselected. if (!isLastChild) { System.arraycopy(batch.selected, 0, unselectedCopy, 0, unselectedSize); } VectorExpression childExpr = this.childExpressions[childIndex]; childExpr.evaluate(batch); // Merge the result of last evaluate to previous evaluate. newSize += batch.size; for (int i = 0; i < batch.size; i++) { tmp[batch.selected[i]] = 1; } if (isLastChild) { break; } unselectedSize = subtract(unselectedCopy, unselectedSize, batch.selected, batch.size, difference); if (unselectedSize == 0) { break; } System.arraycopy(difference, 0, batch.selected, 0, unselectedSize); batch.size = unselectedSize; childIndex++; } } // Important: Restore the batch's selected array. batch.selected = selectedAfterFirstChild; int k = 0; for (int j = 0; j < n; j++) { int i = initialSelected[j]; if (tmp[i] == 1) { batch.selected[k++] = i; } } batch.size = newSize; if (newSize == n) { // Filter didn't do anything batch.selectedInUse = prevSelectInUse; } }