You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ec...@apache.org on 2011/12/27 19:19:44 UTC

svn commit: r1224966 [5/10] - in /incubator/accumulo/branches/1.4: ./ contrib/accumulo_sample/ contrib/accumulo_sample/ingest/src/main/java/aggregator/ contrib/accumulo_sample/ingest/src/main/java/ingest/ contrib/accumulo_sample/ingest/src/test/java/ag...

Modified: incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/FieldIndexIterator.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/FieldIndexIterator.java?rev=1224966&r1=1224965&r2=1224966&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/FieldIndexIterator.java (original)
+++ incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/FieldIndexIterator.java Tue Dec 27 18:19:43 2011
@@ -1,19 +1,19 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package iterator;
 
 import java.io.IOException;
@@ -42,697 +42,682 @@ import org.apache.accumulo.core.iterator
 import function.QueryFunctions;
 
 /**
-* This iterator should only return keys from the fi\0{fieldName}:{fieldValue}
-* part of the shard table.  Expect topKey to be CF, {datatype}\0{UID}
-*/
+ * This iterator should only return keys from the fi\0{fieldName}:{fieldValue} part of the shard table. Expect topKey to be CF, {datatype}\0{UID}
+ */
 public class FieldIndexIterator extends WrappingIterator {
-
-    private Key topKey = null;
-    private Value topValue = null;
-    private Range range = null;
-    private Text currentRow;
-    private Text fName = null;
-    private String fNameString = null;
-    private Text fValue = null;
-    private String fOperator = null;
-    private Expression expr = null;
-    private static final Collection<ByteSequence> EMPTY_COL_FAMS = new ArrayList<ByteSequence>();
-    protected static final Logger log = Logger.getLogger(FieldIndexIterator.class);
-    private boolean negated = false;
-    private int type;
-    private static final String NULL_BYTE = "\0";
-    private static final String ONE_BYTE = "\1";
-    //According to the JEXL 2.0 docs, the engine is thread-safe. Let's create 1 engine per VM and
-    //cache 128 expressions
-    private static JexlEngine engine = new JexlEngine();
-    private Range parentRange;
-    private Text parentEndRow = null;
-    private FieldIndexKeyParser keyParser;
-
-    static {
-        engine.setCache(128);
-        Map<String, Object> functions = new HashMap<String, Object>();
-        functions.put("f", QueryFunctions.class);
-        engine.setFunctions(functions);
-    }
-
-    public static void setLogLevel(Level l) {
-        log.setLevel(l);
-    }
-
-    //-------------------------------------------------------------------------
-    //-------------  Constructors
-    public FieldIndexIterator() {
-    }
-
-    public FieldIndexIterator(int type, Text rowId, Text fieldName, Text fieldValue, String operator) {
-        this.fName = fieldName;
-        this.fNameString = fName.toString().substring(3);
-        this.fValue = fieldValue;
-        this.fOperator = operator;
-        this.range = buildRange(rowId);
-        this.negated = false;
-        this.type = type;
-
-        //Create the Jexl expression, we need to add the ' around the field value
-        StringBuilder buf = new StringBuilder();
-        buf.append(fNameString).append(" ").append(this.fOperator).append(" ").append("'").append(fValue.toString()).append("'");
-        this.expr = engine.createExpression(buf.toString());
-
-        //Set a default KeyParser
-        keyParser = createDefaultKeyParser();
-    }
-
-    public FieldIndexIterator(int type, Text rowId, Text fieldName, Text fieldValue, boolean neg, String operator) {
-        this.fName = fieldName;
-        this.fNameString = fName.toString().substring(3);
-        this.fValue = fieldValue;
-        this.fOperator = operator;
-        this.range = buildRange(rowId);
-        this.negated = neg;
-        this.type = type;
-
-        //Create the Jexl expression, we need to add the ' around the field value
-        StringBuilder buf = new StringBuilder();
-        buf.append(fNameString).append(" ").append(this.fOperator).append(" ").append("'").append(fValue.toString()).append("'");
-        this.expr = engine.createExpression(buf.toString());
-        //Set a default KeyParser
-        keyParser = createDefaultKeyParser();
-    }
-
-    public FieldIndexIterator(FieldIndexIterator other, IteratorEnvironment env) {
-        setSource(other.getSource().deepCopy(env));
-        //Set a default KeyParser
-        keyParser = createDefaultKeyParser();
-    }
-
-    private FieldIndexKeyParser createDefaultKeyParser() {
-        FieldIndexKeyParser parser = new FieldIndexKeyParser();
-        return parser;
-    }
-
-
-
-    @Override
-    public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) {
-        return new FieldIndexIterator(this, env);
-    }
-
-    @Override
-    public Key getTopKey() {
-        return topKey;
-    }
-
-    @Override
-    public Value getTopValue() {
-        return topValue;
-    }
-
-    @Override
-    public boolean hasTop() {
-        return (topKey != null);
-    }
-
-    @Override
-    public void next() throws IOException {
-        if (log.isDebugEnabled()) {
-            log.debug("next()");
-        }
-        if (this.hasTop()) {
-            currentRow = topKey.getRow();
-        }
-
-        getSource().next();
-        while (true) {
-            log.debug("next(), Range: " + range);
-            if (getSource().hasTop()) {
-                Key k = getSource().getTopKey();
-                if (range.contains(k)) {
-                    if (matches(k)) {
-                        topKey = k;
-                        topValue = getSource().getTopValue();
-                        return;
-                    } else {
-                    	getSource().next();
-                    }
-
-                } else {
-
-                    if (parentEndRow != null) { // need to check it
-                        if (k.getRow().equals(currentRow)) {
-                            currentRow = getNextRow();
-                        } else if (currentRow == null || k.getRow().compareTo(currentRow) > 0) {
-                            currentRow = k.getRow();
-                        }
-
-                        if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
-                            //you're done
-                            topKey = null;
-                            topValue = null;
-                            return;
-                        }
-
-                    } else { // we can go to end of the tablet
-                        if (k.getRow().equals(currentRow)) {
-                            currentRow = getNextRow();
-                            if (currentRow == null) {
-                                topKey = null;
-                                topValue = null;
-                                return;
-                            }
-                        } else if (currentRow == null || (k.getRow().compareTo(currentRow) > 0)) {
-                            currentRow = k.getRow();
-                        }
-                    }
-
-                    //construct new range and seek the source
-                    range = buildRange(currentRow);
-                    if (log.isDebugEnabled()) {
-                        log.debug("next, range: " + range);
-                    }
-                    getSource().seek(range, EMPTY_COL_FAMS, false);
-                }
-            } else {
+  
+  private Key topKey = null;
+  private Value topValue = null;
+  private Range range = null;
+  private Text currentRow;
+  private Text fName = null;
+  private String fNameString = null;
+  private Text fValue = null;
+  private String fOperator = null;
+  private Expression expr = null;
+  private static final Collection<ByteSequence> EMPTY_COL_FAMS = new ArrayList<ByteSequence>();
+  protected static final Logger log = Logger.getLogger(FieldIndexIterator.class);
+  private boolean negated = false;
+  private int type;
+  private static final String NULL_BYTE = "\0";
+  private static final String ONE_BYTE = "\1";
+  // According to the JEXL 2.0 docs, the engine is thread-safe. Let's create 1 engine per VM and
+  // cache 128 expressions
+  private static JexlEngine engine = new JexlEngine();
+  private Range parentRange;
+  private Text parentEndRow = null;
+  private FieldIndexKeyParser keyParser;
+  
+  static {
+    engine.setCache(128);
+    Map<String,Object> functions = new HashMap<String,Object>();
+    functions.put("f", QueryFunctions.class);
+    engine.setFunctions(functions);
+  }
+  
+  public static void setLogLevel(Level l) {
+    log.setLevel(l);
+  }
+  
+  // -------------------------------------------------------------------------
+  // ------------- Constructors
+  public FieldIndexIterator() {}
+  
+  public FieldIndexIterator(int type, Text rowId, Text fieldName, Text fieldValue, String operator) {
+    this.fName = fieldName;
+    this.fNameString = fName.toString().substring(3);
+    this.fValue = fieldValue;
+    this.fOperator = operator;
+    this.range = buildRange(rowId);
+    this.negated = false;
+    this.type = type;
+    
+    // Create the Jexl expression, we need to add the ' around the field value
+    StringBuilder buf = new StringBuilder();
+    buf.append(fNameString).append(" ").append(this.fOperator).append(" ").append("'").append(fValue.toString()).append("'");
+    this.expr = engine.createExpression(buf.toString());
+    
+    // Set a default KeyParser
+    keyParser = createDefaultKeyParser();
+  }
+  
+  public FieldIndexIterator(int type, Text rowId, Text fieldName, Text fieldValue, boolean neg, String operator) {
+    this.fName = fieldName;
+    this.fNameString = fName.toString().substring(3);
+    this.fValue = fieldValue;
+    this.fOperator = operator;
+    this.range = buildRange(rowId);
+    this.negated = neg;
+    this.type = type;
+    
+    // Create the Jexl expression, we need to add the ' around the field value
+    StringBuilder buf = new StringBuilder();
+    buf.append(fNameString).append(" ").append(this.fOperator).append(" ").append("'").append(fValue.toString()).append("'");
+    this.expr = engine.createExpression(buf.toString());
+    // Set a default KeyParser
+    keyParser = createDefaultKeyParser();
+  }
+  
+  public FieldIndexIterator(FieldIndexIterator other, IteratorEnvironment env) {
+    setSource(other.getSource().deepCopy(env));
+    // Set a default KeyParser
+    keyParser = createDefaultKeyParser();
+  }
+  
+  private FieldIndexKeyParser createDefaultKeyParser() {
+    FieldIndexKeyParser parser = new FieldIndexKeyParser();
+    return parser;
+  }
+  
+  @Override
+  public SortedKeyValueIterator<Key,Value> deepCopy(IteratorEnvironment env) {
+    return new FieldIndexIterator(this, env);
+  }
+  
+  @Override
+  public Key getTopKey() {
+    return topKey;
+  }
+  
+  @Override
+  public Value getTopValue() {
+    return topValue;
+  }
+  
+  @Override
+  public boolean hasTop() {
+    return (topKey != null);
+  }
+  
+  @Override
+  public void next() throws IOException {
+    if (log.isDebugEnabled()) {
+      log.debug("next()");
+    }
+    if (this.hasTop()) {
+      currentRow = topKey.getRow();
+    }
+    
+    getSource().next();
+    while (true) {
+      log.debug("next(), Range: " + range);
+      if (getSource().hasTop()) {
+        Key k = getSource().getTopKey();
+        if (range.contains(k)) {
+          if (matches(k)) {
+            topKey = k;
+            topValue = getSource().getTopValue();
+            return;
+          } else {
+            getSource().next();
+          }
+          
+        } else {
+          
+          if (parentEndRow != null) { // need to check it
+            if (k.getRow().equals(currentRow)) {
+              currentRow = getNextRow();
+            } else if (currentRow == null || k.getRow().compareTo(currentRow) > 0) {
+              currentRow = k.getRow();
+            }
+            
+            if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
+              // you're done
+              topKey = null;
+              topValue = null;
+              return;
+            }
+            
+          } else { // we can go to end of the tablet
+            if (k.getRow().equals(currentRow)) {
+              currentRow = getNextRow();
+              if (currentRow == null) {
                 topKey = null;
                 topValue = null;
                 return;
-            }
+              }
+            } else if (currentRow == null || (k.getRow().compareTo(currentRow) > 0)) {
+              currentRow = k.getRow();
+            }
+          }
+          
+          // construct new range and seek the source
+          range = buildRange(currentRow);
+          if (log.isDebugEnabled()) {
+            log.debug("next, range: " + range);
+          }
+          getSource().seek(range, EMPTY_COL_FAMS, false);
+        }
+      } else {
+        topKey = null;
+        topValue = null;
+        return;
+      }
+    }
+  }
+  
+  /*
+   * NOTE: there is some special magic here with range modification. If it's negated, assume the range is explicitly set and don't mess with it (this is how
+   * it's called by the BooleanLogicIterator) Otherwise, modify the range to start at the beginning and set an explicit end point.
+   * 
+   * In the future, maybe all we need to do is look for an endKey and modifying that.
+   */
+  @Override
+  public void seek(Range r, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
+    parentRange = r;
+    if (log.isDebugEnabled()) {
+      log.debug("begin seek, range: " + r);
+    }
+    if (parentRange.getEndKey() != null) {
+      if (parentRange.getEndKey().getRow() != null) {
+        parentEndRow = parentRange.getEndKey().getRow();
+        if (log.isDebugEnabled()) {
+          log.debug("begin seek, parentEndRow: " + parentEndRow);
         }
+      }
     }
-
-    /*
-     * NOTE: there is some special magic here with range modification.
-     * If it's negated, assume the range is explicitly set and don't mess with it
-     * (this is how it's called by the BooleanLogicIterator)
-     * Otherwise, modify the range to start at the beginning and set an explicit
-     * end point.
-     *
-     * In the future, maybe all we need to do is look for an endKey and modifying that.
-     */
-    @Override
-    public void seek(Range r, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
-        parentRange = r;
+    
+    try {
+      if (isNegated()) {
+        range = r;
         if (log.isDebugEnabled()) {
-            log.debug("begin seek, range: " + r);
+          log.debug("seek, negation, skipping range modification.");
         }
-        if (parentRange.getEndKey() != null) {
-            if (parentRange.getEndKey().getRow() != null) {
-                parentEndRow = parentRange.getEndKey().getRow();
-                if (log.isDebugEnabled()) {
-                    log.debug("begin seek, parentEndRow: " + parentEndRow);
-                }
-            }
+      } else {
+        if (r.getStartKey() != null) {
+          if (r.getStartKey().getRow() == null || r.getStartKey().getRow().toString().isEmpty()) {
+            currentRow = getFirstRow();
+          } else {
+            currentRow = r.getStartKey().getRow();
+          }
+          this.range = buildRange(currentRow);
+        } else {
+          currentRow = getFirstRow();
+          this.range = buildRange(currentRow);
         }
-
-
-        try {
-            if (isNegated()) {
-                range = r;
-                if (log.isDebugEnabled()) {
-                    log.debug("seek, negation, skipping range modification.");
-                }
+      }
+      
+      setTopKey(null);
+      setTopValue(null);
+      
+      if (log.isDebugEnabled()) {
+        log.debug("seek, incoming range: " + range);
+      }
+      getSource().seek(range, columnFamilies, inclusive);
+      
+      while (topKey == null) {
+        if (getSource().hasTop()) {
+          if (log.isDebugEnabled()) {
+            log.debug("seek, source has top: " + getSource().getTopKey());
+          }
+          Key k = getSource().getTopKey();
+          if (range.contains(k)) {
+            if (matches(k)) {
+              topKey = k;
+              topValue = getSource().getTopValue();
+              if (log.isDebugEnabled()) {
+                log.debug("seek, source has top in valid range");
+              }
             } else {
-                if (r.getStartKey() != null) {
-                    if (r.getStartKey().getRow() == null || r.getStartKey().getRow().toString().isEmpty()) {
-                        currentRow = getFirstRow();
-                    } else {
-                        currentRow = r.getStartKey().getRow();
-                    }
-                    this.range = buildRange(currentRow);
-                } else {
-                    currentRow = getFirstRow();
-                    this.range = buildRange(currentRow);
-                }
-            }
-
-            setTopKey(null);
-            setTopValue(null);
-
-            if (log.isDebugEnabled()) {
-                log.debug("seek, incoming range: " + range);
-            }
-            getSource().seek(range, columnFamilies, inclusive);
-
-            while (topKey == null) {
-                if (getSource().hasTop()) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("seek, source has top: " + getSource().getTopKey());
-                    }
-                    Key k = getSource().getTopKey();
-                    if (range.contains(k)) {
-                        if (matches(k)) {
-                            topKey = k;
-                            topValue = getSource().getTopValue();
-                            if (log.isDebugEnabled()) {
-                                log.debug("seek, source has top in valid range");
-                            }
-                        } else {
-                        	getSource().next();
-                        }
-                    } else {
-                        if (log.isDebugEnabled()) {
-                            log.debug("seek, top out of range");
-                            String pEndRow = "empty";
-                            if (parentEndRow != null) {
-                                pEndRow = parentEndRow.toString();
-                            }
-                            log.debug("source.topKey.row: " + k.getRow() + "\t currentRow: " + currentRow + "\t parentEndRow: " + pEndRow);
-                        }
-                        if (isNegated()) {
-                            topKey = null;
-                            topValue = null;
-                            return;
-                        }
-
-                        if (parentEndRow != null) {
-                            // check it
-                            if (k.getRow().equals(currentRow)) {
-                                currentRow = getNextRow();
-                            }
-
-                            if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
-                                //you're done
-                                topKey = null;
-                                topValue = null;
-                                return;
-                            }
-
-                        } else { // can go to end of the tablet
-                            if (k.getRow().equals(currentRow)) {
-                                currentRow = getNextRow();
-                                if (currentRow == null) {
-                                    topKey = null;
-                                    topValue = null;
-                                    return;
-                                }
-                            }
-                        }
-
-                        //construct new range and seek the source
-                        range = buildRange(currentRow);
-                        if (log.isDebugEnabled()) {
-                            log.debug("currentRow: " + currentRow);
-                            log.debug("seek, range: " + range);
-                        }
-                        getSource().seek(range, columnFamilies, inclusive);
-                    }
-                } else {
-                    if (log.isDebugEnabled()) {
-                        log.debug("seek, underlying source had no top key.");
-                    }
-                    topKey = null;
-                    topValue = null;
-                    return;
-                }
+              getSource().next();
             }
+          } else {
             if (log.isDebugEnabled()) {
-                log.debug("seek, topKey found: " + topKey);
-            }
-        } catch (IOException e) {
-            topKey = null;
-            topValue = null;
-            throw new IOException();
-        }
-    }
-
-    //-------------------------------------------------------------------------
-    //-------------  Public stuff
-    public boolean isNegated() {
-        return negated;
-    }
-
-    public Text getCurrentRow() {
-        return currentRow;
-    }
-
-    public Text getfName() {
-        return fName;
-    }
-
-    public Text getfValue() {
-        return fValue;
-    }
-
-    // works like seek, but we need to avoid range issues.
-    public boolean jump(Key jumpKey) throws IOException {
-        if (log.isDebugEnabled()) {
-            String pEndRow = "empty";
-            if (parentEndRow != null) {
+              log.debug("seek, top out of range");
+              String pEndRow = "empty";
+              if (parentEndRow != null) {
                 pEndRow = parentEndRow.toString();
+              }
+              log.debug("source.topKey.row: " + k.getRow() + "\t currentRow: " + currentRow + "\t parentEndRow: " + pEndRow);
             }
-            log.debug("jump, current range: " + range + "  parentEndRow is: " + pEndRow);
-
-        }
-
-        if (parentEndRow != null && jumpKey.getRow().compareTo(parentEndRow) > 0) {
-            //can't go there.
-            if (log.isDebugEnabled()) {
-                log.debug("jumpRow: " + jumpKey.getRow() + " is greater than my parentEndRow: " + parentEndRow);
-            }
-            return false;
-        }
-
-        int comp;
-        if (!this.hasTop()) {
-            if (log.isDebugEnabled()) {
-                log.debug("current row: " + this.currentRow);
+            if (isNegated()) {
+              topKey = null;
+              topValue = null;
+              return;
             }
-
-            /*
-             * if I don't have a top, then I should be out of my range for my current row.
-             * Need to check parent range to see if I'm supposed to continue to next
-             * row or not.  Current row can be null because maybe I never found
-             * anything in this row.
-             */
-
+            
             if (parentEndRow != null) {
-                // if jumpKey row is greater than parentEndRow, stop
-                if (jumpKey.getRow().compareTo(parentEndRow) > 0) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("jumpKey row is greater than my parentEndRow, done");
-                    }
-                    return false;
-                }
-
-                //if my current row is null, I must have hit the end of the tablet
-                if (currentRow == null) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("I have parentEndRow, but no current row, must have hit end of tablet, done");
-                    }
-                    return false;
-                }
-
-                //if my current row is greater than jump row stop, a seek will be
-                //called to get me going again.  If my row is equal, but i don't
-                //have a topkey, i'm done
-                if (currentRow.compareTo(jumpKey.getRow()) >= 0) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("I have parentEndRow, but topKey, and my currentRow is >= jumpRow, done");
-                    }
-                    return false;
-                }
-
-            } else { // we're allowed to go to the end of the tablet
-                //if my current row is null, I must have hit the end of the tablet
-                if (currentRow == null) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("no parentEndRow and current Row is null, must have hit end of tablet, done");
-                    }
-                    return false;
-                }
-
-                if (currentRow.compareTo(jumpKey.getRow()) >= 0) {
-                    // i'm past or equal to the jump point and have no top,
-                    // jumping's not going to help
-                    if (log.isDebugEnabled()) {
-                        log.debug("no parentEndRow, no topKey, and currentRow is >= jumpRow, done");
-                    }
-                    return false;
-                }
-            }
-
-            // ok, jumpKey is ahead of me I'll mark it and allow the normal
-            // flow to jump there and see if I have top.
-            if (log.isDebugEnabled()) {
-                log.debug("no topKey, but jumpRow is ahead and I'm allowed to go to it, marking");
-            }
-            comp = -1;
-
-        } else { // I have a topKey, I can do the normal comparisons
-            if (log.isDebugEnabled()) {
-                log.debug("have top, can do normal comparisons");
-            }
-            comp = this.topKey.getRow().compareTo(jumpKey.getRow());
-        }
-
-        //------------------
-        //compare rows
-        if (comp > 0) { // my row is ahead of jump key
-            if (canBeInNextRow()) {
-                if (log.isDebugEnabled()) {
-                    log.debug("I'm ahead of jump row & it's ok.");
-                    log.debug("jumpRow: " + jumpKey.getRow() + " myRow: " + topKey.getRow() + " parentEndRow: " + parentEndRow);
-                }
-                return true;
-            } else {
-                if (log.isDebugEnabled()) {
-                    log.debug("I'm ahead of jump row & can't be here, or at end of tablet.");
-                }
-                topKey = null;
-                topValue = null;
-                return false;
-            }
-
-        } else if (comp < 0) { //a row behind jump key, need to move forward
-            String myRow = "";
-            if (hasTop()) {
-                myRow = topKey.getRow().toString();
-            } else if (currentRow != null) {
-                myRow = currentRow.toString();
-            }
-            log.debug("My row " + myRow + " is less than jump row: " + jumpKey.getRow() + " seeking");
-            range = buildRange(jumpKey.getRow());
-            //this.seek(range, EMPTY_COL_FAMS, false);
-
-            boolean success = jumpSeek(range);
-            if (log.isDebugEnabled() && success) {
-                log.debug("uid forced jump, found topKey: " + topKey);
-            }
-
-
-            if (!this.hasTop()) {
-                log.debug("seeked with new row and had no top");
-                topKey = null;
-                topValue = null;
-                return false;
-            } else if (parentEndRow != null && currentRow.compareTo(parentEndRow) > 0) {
-                if (log.isDebugEnabled()) {
-                    log.debug("myRow: " + getTopKey().getRow() + " is past parentEndRow: " + parentEndRow);
-                }
+              // check it
+              if (k.getRow().equals(currentRow)) {
+                currentRow = getNextRow();
+              }
+              
+              if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
+                // you're done
                 topKey = null;
                 topValue = null;
-                return false;
-            }
-            if (log.isDebugEnabled()) {
-                log.debug("jumped, valid top: " + getTopKey());
-            }
-
-            return true;
-
-        } else {  // rows are equal, check the uid!
-
-            keyParser.parse(topKey);
-            String myUid = keyParser.getUid();
-            keyParser.parse(jumpKey);
-            String jumpUid = keyParser.getUid();
-
-            int ucomp = myUid.compareTo(jumpUid);
+                return;
+              }
+              
+            } else { // can go to end of the tablet
+              if (k.getRow().equals(currentRow)) {
+                currentRow = getNextRow();
+                if (currentRow == null) {
+                  topKey = null;
+                  topValue = null;
+                  return;
+                }
+              }
+            }
+            
+            // construct new range and seek the source
+            range = buildRange(currentRow);
             if (log.isDebugEnabled()) {
-                log.debug("topKeyUid: " + myUid + "  jumpUid: " + jumpUid + "  myUid.compareTo(jumpUid)->" + ucomp);
+              log.debug("currentRow: " + currentRow);
+              log.debug("seek, range: " + range);
             }
-            if (ucomp < 0) { //need to move up
-                log.debug("my uid is less than jumpUid, topUid: " + myUid + "   jumpUid: " + jumpUid);
-                // note my internal range stays the same, I just need to move forward
-                Key startKey = new Key(topKey.getRow(), fName, new Text(fValue + NULL_BYTE + jumpKey.getColumnQualifier()));
-                Key endKey = new Key(topKey.getRow(), fName, new Text(fValue + ONE_BYTE));
-                range = new Range(startKey, true, endKey, false);
-                log.debug("Using range: " + range + " to seek");
-                //source.seek(range, EMPTY_COL_FAMS, false);
-                boolean success = jumpSeek(range);
-                if (log.isDebugEnabled() && success) {
-                    log.debug("uid forced jump, found topKey: " + topKey);
-                }
-
-                return success;
-
-            } else { //else do nothing
-                log.debug("my uid is greater than jumpUid, topKey: " + topKey + "   jumpKey: " + jumpKey);
-                log.debug("doing nothing");
-            }
-        }
-
-        return hasTop();
-    }
-
-    //-------------------------------------------------------------------------
-    //-------------  Private stuff, KEEP OUT!!
-    private void setTopKey(Key key) {
-        topKey = key;
-    }
-
-    private void setTopValue(Value v) {
-        this.topValue = v;
-    }
-
-    private boolean canBeInNextRow() {
-        if (parentEndRow == null) {
-            return true;
-        } else if (currentRow == null) {
-            return false;
-        } else if (currentRow.compareTo(parentEndRow) <= 0) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private Range buildRange(Text rowId) {
-        if (type == ParserTreeConstants.JJTGTNODE
-                || type == ParserTreeConstants.JJTGENODE
-                || type == ParserTreeConstants.JJTLTNODE
-                || type == ParserTreeConstants.JJTLENODE
-                || type == ParserTreeConstants.JJTERNODE
-                || type == ParserTreeConstants.JJTNRNODE) {
-            Key startKey = new Key(rowId, fName);
-            Key endKey = new Key(rowId, new Text(fName + NULL_BYTE));
-            return (new Range(startKey, true, endKey, false));
+            getSource().seek(range, columnFamilies, inclusive);
+          }
         } else {
-            // construct new range
-            Key startKey = new Key(rowId, fName, new Text(fValue + NULL_BYTE));
-            Key endKey = new Key(rowId, fName, new Text(fValue + ONE_BYTE));
-            return (new Range(startKey, true, endKey, false));
-        }
-    }
-
-    // need to build a range starting at the end of current row and seek the
-    // source to it. If we get an IOException, that means we hit the end of the tablet.
-    private Text getNextRow() throws IOException {
+          if (log.isDebugEnabled()) {
+            log.debug("seek, underlying source had no top key.");
+          }
+          topKey = null;
+          topValue = null;
+          return;
+        }
+      }
+      if (log.isDebugEnabled()) {
+        log.debug("seek, topKey found: " + topKey);
+      }
+    } catch (IOException e) {
+      topKey = null;
+      topValue = null;
+      throw new IOException();
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  // ------------- Public stuff
+  public boolean isNegated() {
+    return negated;
+  }
+  
+  public Text getCurrentRow() {
+    return currentRow;
+  }
+  
+  public Text getfName() {
+    return fName;
+  }
+  
+  public Text getfValue() {
+    return fValue;
+  }
+  
+  // works like seek, but we need to avoid range issues.
+  public boolean jump(Key jumpKey) throws IOException {
+    if (log.isDebugEnabled()) {
+      String pEndRow = "empty";
+      if (parentEndRow != null) {
+        pEndRow = parentEndRow.toString();
+      }
+      log.debug("jump, current range: " + range + "  parentEndRow is: " + pEndRow);
+      
+    }
+    
+    if (parentEndRow != null && jumpKey.getRow().compareTo(parentEndRow) > 0) {
+      // can't go there.
+      if (log.isDebugEnabled()) {
+        log.debug("jumpRow: " + jumpKey.getRow() + " is greater than my parentEndRow: " + parentEndRow);
+      }
+      return false;
+    }
+    
+    int comp;
+    if (!this.hasTop()) {
+      if (log.isDebugEnabled()) {
+        log.debug("current row: " + this.currentRow);
+      }
+      
+      /*
+       * if I don't have a top, then I should be out of my range for my current row. Need to check parent range to see if I'm supposed to continue to next row
+       * or not. Current row can be null because maybe I never found anything in this row.
+       */
+      
+      if (parentEndRow != null) {
+        // if jumpKey row is greater than parentEndRow, stop
+        if (jumpKey.getRow().compareTo(parentEndRow) > 0) {
+          if (log.isDebugEnabled()) {
+            log.debug("jumpKey row is greater than my parentEndRow, done");
+          }
+          return false;
+        }
+        
+        // if my current row is null, I must have hit the end of the tablet
+        if (currentRow == null) {
+          if (log.isDebugEnabled()) {
+            log.debug("I have parentEndRow, but no current row, must have hit end of tablet, done");
+          }
+          return false;
+        }
+        
+        // if my current row is greater than jump row stop, a seek will be
+        // called to get me going again. If my row is equal, but i don't
+        // have a topkey, i'm done
+        if (currentRow.compareTo(jumpKey.getRow()) >= 0) {
+          if (log.isDebugEnabled()) {
+            log.debug("I have parentEndRow, but topKey, and my currentRow is >= jumpRow, done");
+          }
+          return false;
+        }
+        
+      } else { // we're allowed to go to the end of the tablet
+        // if my current row is null, I must have hit the end of the tablet
+        if (currentRow == null) {
+          if (log.isDebugEnabled()) {
+            log.debug("no parentEndRow and current Row is null, must have hit end of tablet, done");
+          }
+          return false;
+        }
+        
+        if (currentRow.compareTo(jumpKey.getRow()) >= 0) {
+          // i'm past or equal to the jump point and have no top,
+          // jumping's not going to help
+          if (log.isDebugEnabled()) {
+            log.debug("no parentEndRow, no topKey, and currentRow is >= jumpRow, done");
+          }
+          return false;
+        }
+      }
+      
+      // ok, jumpKey is ahead of me I'll mark it and allow the normal
+      // flow to jump there and see if I have top.
+      if (log.isDebugEnabled()) {
+        log.debug("no topKey, but jumpRow is ahead and I'm allowed to go to it, marking");
+      }
+      comp = -1;
+      
+    } else { // I have a topKey, I can do the normal comparisons
+      if (log.isDebugEnabled()) {
+        log.debug("have top, can do normal comparisons");
+      }
+      comp = this.topKey.getRow().compareTo(jumpKey.getRow());
+    }
+    
+    // ------------------
+    // compare rows
+    if (comp > 0) { // my row is ahead of jump key
+      if (canBeInNextRow()) {
         if (log.isDebugEnabled()) {
-            log.debug("getNextRow()");
+          log.debug("I'm ahead of jump row & it's ok.");
+          log.debug("jumpRow: " + jumpKey.getRow() + " myRow: " + topKey.getRow() + " parentEndRow: " + parentEndRow);
         }
-        Key fakeKey = new Key(new Text(currentRow + NULL_BYTE));
-        Range fakeRange = new Range(fakeKey, fakeKey);
-        getSource().seek(fakeRange, EMPTY_COL_FAMS, false);
-        if (getSource().hasTop()) {
-            return getSource().getTopKey().getRow();
-        } else {
-            return null;
+        return true;
+      } else {
+        if (log.isDebugEnabled()) {
+          log.debug("I'm ahead of jump row & can't be here, or at end of tablet.");
         }
-    }
-
-    private Text getFirstRow() throws IOException {
-    	getSource().seek(new Range(), EMPTY_COL_FAMS, false);
-        if (getSource().hasTop()) {
-            return getSource().getTopKey().getRow();
-        } else {
-            throw new IOException();
+        topKey = null;
+        topValue = null;
+        return false;
+      }
+      
+    } else if (comp < 0) { // a row behind jump key, need to move forward
+      String myRow = "";
+      if (hasTop()) {
+        myRow = topKey.getRow().toString();
+      } else if (currentRow != null) {
+        myRow = currentRow.toString();
+      }
+      log.debug("My row " + myRow + " is less than jump row: " + jumpKey.getRow() + " seeking");
+      range = buildRange(jumpKey.getRow());
+      // this.seek(range, EMPTY_COL_FAMS, false);
+      
+      boolean success = jumpSeek(range);
+      if (log.isDebugEnabled() && success) {
+        log.debug("uid forced jump, found topKey: " + topKey);
+      }
+      
+      if (!this.hasTop()) {
+        log.debug("seeked with new row and had no top");
+        topKey = null;
+        topValue = null;
+        return false;
+      } else if (parentEndRow != null && currentRow.compareTo(parentEndRow) > 0) {
+        if (log.isDebugEnabled()) {
+          log.debug("myRow: " + getTopKey().getRow() + " is past parentEndRow: " + parentEndRow);
         }
-    }
-
-    private boolean matches(Key k) {
+        topKey = null;
+        topValue = null;
+        return false;
+      }
+      if (log.isDebugEnabled()) {
+        log.debug("jumped, valid top: " + getTopKey());
+      }
+      
+      return true;
+      
+    } else { // rows are equal, check the uid!
+    
+      keyParser.parse(topKey);
+      String myUid = keyParser.getUid();
+      keyParser.parse(jumpKey);
+      String jumpUid = keyParser.getUid();
+      
+      int ucomp = myUid.compareTo(jumpUid);
+      if (log.isDebugEnabled()) {
+        log.debug("topKeyUid: " + myUid + "  jumpUid: " + jumpUid + "  myUid.compareTo(jumpUid)->" + ucomp);
+      }
+      if (ucomp < 0) { // need to move up
+        log.debug("my uid is less than jumpUid, topUid: " + myUid + "   jumpUid: " + jumpUid);
+        // note my internal range stays the same, I just need to move forward
+        Key startKey = new Key(topKey.getRow(), fName, new Text(fValue + NULL_BYTE + jumpKey.getColumnQualifier()));
+        Key endKey = new Key(topKey.getRow(), fName, new Text(fValue + ONE_BYTE));
+        range = new Range(startKey, true, endKey, false);
+        log.debug("Using range: " + range + " to seek");
+        // source.seek(range, EMPTY_COL_FAMS, false);
+        boolean success = jumpSeek(range);
+        if (log.isDebugEnabled() && success) {
+          log.debug("uid forced jump, found topKey: " + topKey);
+        }
+        
+        return success;
+        
+      } else { // else do nothing
+        log.debug("my uid is greater than jumpUid, topKey: " + topKey + "   jumpKey: " + jumpKey);
+        log.debug("doing nothing");
+      }
+    }
+    
+    return hasTop();
+  }
+  
+  // -------------------------------------------------------------------------
+  // ------------- Private stuff, KEEP OUT!!
+  private void setTopKey(Key key) {
+    topKey = key;
+  }
+  
+  private void setTopValue(Value v) {
+    this.topValue = v;
+  }
+  
+  private boolean canBeInNextRow() {
+    if (parentEndRow == null) {
+      return true;
+    } else if (currentRow == null) {
+      return false;
+    } else if (currentRow.compareTo(parentEndRow) <= 0) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  
+  private Range buildRange(Text rowId) {
+    if (type == ParserTreeConstants.JJTGTNODE || type == ParserTreeConstants.JJTGENODE || type == ParserTreeConstants.JJTLTNODE
+        || type == ParserTreeConstants.JJTLENODE || type == ParserTreeConstants.JJTERNODE || type == ParserTreeConstants.JJTNRNODE) {
+      Key startKey = new Key(rowId, fName);
+      Key endKey = new Key(rowId, new Text(fName + NULL_BYTE));
+      return (new Range(startKey, true, endKey, false));
+    } else {
+      // construct new range
+      Key startKey = new Key(rowId, fName, new Text(fValue + NULL_BYTE));
+      Key endKey = new Key(rowId, fName, new Text(fValue + ONE_BYTE));
+      return (new Range(startKey, true, endKey, false));
+    }
+  }
+  
+  // need to build a range starting at the end of current row and seek the
+  // source to it. If we get an IOException, that means we hit the end of the tablet.
+  private Text getNextRow() throws IOException {
+    if (log.isDebugEnabled()) {
+      log.debug("getNextRow()");
+    }
+    Key fakeKey = new Key(new Text(currentRow + NULL_BYTE));
+    Range fakeRange = new Range(fakeKey, fakeKey);
+    getSource().seek(fakeRange, EMPTY_COL_FAMS, false);
+    if (getSource().hasTop()) {
+      return getSource().getTopKey().getRow();
+    } else {
+      return null;
+    }
+  }
+  
+  private Text getFirstRow() throws IOException {
+    getSource().seek(new Range(), EMPTY_COL_FAMS, false);
+    if (getSource().hasTop()) {
+      return getSource().getTopKey().getRow();
+    } else {
+      throw new IOException();
+    }
+  }
+  
+  private boolean matches(Key k) {
+    if (log.isDebugEnabled()) {
+      log.debug("You've reached the match function!");
+    }
+    JexlContext ctx = new MapContext();
+    // Add the field value from the key to the context
+    // String fieldValue = k.getColumnQualifier().toString().split("\0")[0];
+    // String fieldValue = getFieldValueFromKey(k);
+    keyParser.parse(k);
+    String fieldValue = keyParser.getFieldValue();
+    
+    ctx.set(fNameString, fieldValue);
+    Object o = expr.evaluate(ctx);
+    if (o instanceof Boolean && (((Boolean) o) == true)) {
+      if (log.isDebugEnabled()) {
+        log.debug("matches:: fName: " + fName + " , fValue: " + fieldValue + " ,  operator: " + fOperator + " , key: " + k);
+      }
+      return true;
+    } else {
+      if (log.isDebugEnabled()) {
+        log.debug("NO MATCH:: fName: " + fName + " , fValue: " + fieldValue + " ,  operator: " + fOperator + " , key: " + k);
+      }
+      return false;
+    }
+  }
+  
+  private boolean jumpSeek(Range r) throws IOException {
+    range = r;
+    setTopKey(null);
+    setTopValue(null);
+    getSource().seek(range, EMPTY_COL_FAMS, false);
+    while (topKey == null) {
+      if (getSource().hasTop()) {
         if (log.isDebugEnabled()) {
-            log.debug("You've reached the match function!");
+          log.debug("jump, source has top: " + getSource().getTopKey());
         }
-        JexlContext ctx = new MapContext();
-        //Add the field value from the key to the context
-        //String fieldValue = k.getColumnQualifier().toString().split("\0")[0];
-        //String fieldValue = getFieldValueFromKey(k);
-        keyParser.parse(k);
-        String fieldValue = keyParser.getFieldValue();
-
-        ctx.set(fNameString, fieldValue);
-        Object o = expr.evaluate(ctx);
-        if (o instanceof Boolean && (((Boolean) o) == true)) {
+        Key k = getSource().getTopKey();
+        if (range.contains(k)) {
+          if (matches(k)) {
+            topKey = k;
+            topValue = getSource().getTopValue();
             if (log.isDebugEnabled()) {
-                log.debug("matches:: fName: " + fName + " , fValue: " + fieldValue + " ,  operator: " + fOperator + " , key: " + k);
+              log.debug("jump, source has top in valid range");
             }
-            return true;
+          } else {
+            getSource().next();
+          }
         } else {
-            if (log.isDebugEnabled()) {
-                log.debug("NO MATCH:: fName: " + fName + " , fValue: " + fieldValue + " ,  operator: " + fOperator + " , key: " + k);
+          if (log.isDebugEnabled()) {
+            log.debug("jump, top out of range");
+            String pEndRow = "empty";
+            if (parentEndRow != null) {
+              pEndRow = parentEndRow.toString();
             }
-            return false;
-        }
-    }
-
-    private boolean jumpSeek(Range r) throws IOException {
-        range = r;
-        setTopKey(null);
-        setTopValue(null);
-        getSource().seek(range, EMPTY_COL_FAMS, false);
-        while (topKey == null) {
-            if (getSource().hasTop()) {
-                if (log.isDebugEnabled()) {
-                    log.debug("jump, source has top: " + getSource().getTopKey());
-                }
-                Key k = getSource().getTopKey();
-                if (range.contains(k)) {
-                    if (matches(k)) {
-                        topKey = k;
-                        topValue = getSource().getTopValue();
-                        if (log.isDebugEnabled()) {
-                            log.debug("jump, source has top in valid range");
-                        }
-                    } else {
-                    	getSource().next();
-                    }
-                } else {
-                    if (log.isDebugEnabled()) {
-                        log.debug("jump, top out of range");
-                        String pEndRow = "empty";
-                        if (parentEndRow != null) {
-                            pEndRow = parentEndRow.toString();
-                        }
-                        log.debug("source.topKey.row: " + k.getRow() + "\t currentRow: " + currentRow + "\t parentEndRow: " + pEndRow);
-                    }
-
-                    if (parentEndRow != null) {
-
-                        if (currentRow == null) {
-                            topKey = null;
-                            topValue = null;
-                            return false;
-                        }
-                        // check it
-                        if (k.getRow().equals(currentRow)) {
-                            currentRow = getNextRow();
-                        } else if (k.getRow().compareTo(currentRow) > 0) {
-                            currentRow = k.getRow();
-                        }
-
-                        if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
-                            //you're done
-                            topKey = null;
-                            topValue = null;
-                            return false;
-                        }
-
-                    } else { // can go to end of the tablet
-                        if (currentRow == null || k.getRow() == null) {
-                            topKey = null;
-                            topValue = null;
-                            return false;
-                        }
-
-                        if (k.getRow().equals(currentRow)) {
-                            currentRow = getNextRow();
-                            if (currentRow == null) {
-                                topKey = null;
-                                topValue = null;
-                                return false;
-                            }
-                        } else if (k.getRow().compareTo(currentRow) > 0) {
-                            currentRow = k.getRow();
-                        }
-                    }
-
-                    //construct new range and seek the source
-                    range = buildRange(currentRow);
-                    if (log.isDebugEnabled()) {
-                        log.debug("jump, new build range: " + range);
-                    }
-                    getSource().seek(range, EMPTY_COL_FAMS, false);
-                }
-            } else {
-                if (log.isDebugEnabled()) {
-                    log.debug("jump, underlying source had no top key.");
-                }
+            log.debug("source.topKey.row: " + k.getRow() + "\t currentRow: " + currentRow + "\t parentEndRow: " + pEndRow);
+          }
+          
+          if (parentEndRow != null) {
+            
+            if (currentRow == null) {
+              topKey = null;
+              topValue = null;
+              return false;
+            }
+            // check it
+            if (k.getRow().equals(currentRow)) {
+              currentRow = getNextRow();
+            } else if (k.getRow().compareTo(currentRow) > 0) {
+              currentRow = k.getRow();
+            }
+            
+            if (currentRow == null || parentEndRow.compareTo(currentRow) < 0) {
+              // you're done
+              topKey = null;
+              topValue = null;
+              return false;
+            }
+            
+          } else { // can go to end of the tablet
+            if (currentRow == null || k.getRow() == null) {
+              topKey = null;
+              topValue = null;
+              return false;
+            }
+            
+            if (k.getRow().equals(currentRow)) {
+              currentRow = getNextRow();
+              if (currentRow == null) {
                 topKey = null;
                 topValue = null;
                 return false;
-            }
-        }//end while
-
-        return hasTop();
-    }
+              }
+            } else if (k.getRow().compareTo(currentRow) > 0) {
+              currentRow = k.getRow();
+            }
+          }
+          
+          // construct new range and seek the source
+          range = buildRange(currentRow);
+          if (log.isDebugEnabled()) {
+            log.debug("jump, new build range: " + range);
+          }
+          getSource().seek(range, EMPTY_COL_FAMS, false);
+        }
+      } else {
+        if (log.isDebugEnabled()) {
+          log.debug("jump, underlying source had no top key.");
+        }
+        topKey = null;
+        topValue = null;
+        return false;
+      }
+    }// end while
+    
+    return hasTop();
+  }
 }

Modified: incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/OptimizedQueryIterator.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/OptimizedQueryIterator.java?rev=1224966&r1=1224965&r2=1224966&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/OptimizedQueryIterator.java (original)
+++ incubator/accumulo/branches/1.4/contrib/accumulo_sample/query/src/main/java/iterator/OptimizedQueryIterator.java Tue Dec 27 18:19:43 2011
@@ -1,19 +1,19 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package iterator;
 
 import java.io.IOException;
@@ -22,187 +22,184 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.accumulo.core.data.ByteSequence;
 import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.PartialKey;
 import org.apache.accumulo.core.data.Range;
 import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.iterators.IteratorEnvironment;
 import org.apache.accumulo.core.iterators.OptionDescriber;
 import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.log4j.Logger;
 
 /**
- * This iterator internally uses the BooleanLogicIterator to find event UIDs in the field index
- * portion of the partition and uses the EvaluatingIterator to evaluate the events against
- * an expression. The key and value that are emitted from this iterator are the key and value
- * that come from the EvaluatingIterator.
+ * This iterator internally uses the BooleanLogicIterator to find event UIDs in the field index portion of the partition and uses the EvaluatingIterator to
+ * evaluate the events against an expression. The key and value that are emitted from this iterator are the key and value that come from the EvaluatingIterator.
  */
-public class OptimizedQueryIterator implements SortedKeyValueIterator<Key, Value>, OptionDescriber {
-
-    private static Logger log = Logger.getLogger(OptimizedQueryIterator.class);
-    private EvaluatingIterator event = null;
-    private SortedKeyValueIterator<Key, Value> index = null;
-    private Key key = null;
-    private Value value = null;
-    private boolean eventSpecificRange = false;
-
-    public IteratorOptions describeOptions() {
-        Map<String, String> options = new HashMap<String, String>();
-        options.put(EvaluatingIterator.QUERY_OPTION, "full query expression");
-        options.put(BooleanLogicIterator.FIELD_INDEX_QUERY,"modified query for the field index query portion");
-        options.put(ReadAheadIterator.QUEUE_SIZE, "parallel queue size");
-        options.put(ReadAheadIterator.TIMEOUT, "parallel iterator timeout");
-        return new IteratorOptions(getClass().getSimpleName(), "evaluates event objects against an expression using the field index",
-                options, null);
-    }
-
-    public boolean validateOptions(Map<String, String> options) {
-        if (options.containsKey(EvaluatingIterator.QUERY_OPTION) &&
-                options.containsKey(BooleanLogicIterator.FIELD_INDEX_QUERY)) {
-            return true;
-        }
-        return false;
-    }
-
-    public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env) throws IOException {
-        if (!validateOptions(options)) {
-            throw new IllegalArgumentException("Invalid options");
-        }
-
-        //Setup the EvaluatingIterator
-        event = new EvaluatingIterator();
-        event.init(source.deepCopy(env), options, env);
-
-        //if queue size and timeout are set, then use the read ahead iterator
-        if (options.containsKey(ReadAheadIterator.QUEUE_SIZE) && options.containsKey(ReadAheadIterator.TIMEOUT)) {
-            BooleanLogicIterator bli = new BooleanLogicIterator();
-            bli.init(source, options, env);
-            index = new ReadAheadIterator();
-            index.init(bli, options, env);
-        } else {
-            index = new BooleanLogicIterator();
-            //index.setDebug(Level.DEBUG);
-            index.init(source, options, env);
-        }
-
-    }
-
-    public OptimizedQueryIterator() {
-    }
-
-    public OptimizedQueryIterator(OptimizedQueryIterator other, IteratorEnvironment env) {
-        this.event = other.event;
-        this.index = other.index;
-    }
-
-    public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) {
-        return new OptimizedQueryIterator(this, env);
-    }
-
-    public Key getTopKey() {
-        if (log.isDebugEnabled()) {
-            log.debug("getTopKey: " + key);
-        }
-        return key;
-    }
-
-    public Value getTopValue() {
-        if (log.isDebugEnabled()) {
-            log.debug("getTopValue: " + value);
-        }
-        return value;
-    }
-
-    public boolean hasTop() {
-        if (log.isDebugEnabled()) {
-            log.debug("hasTop: returned: " + (key != null));
-        }
-        return (key != null);
-    }
-
-    public void next() throws IOException {
-        if (log.isDebugEnabled()) {
-            log.debug("next");
-        }
-        if (key != null) {
-            key = null;
-            value = null;
-        }
-
-        if (eventSpecificRange) {
-            //Then this will probably return nothing
-            event.next();
-            if (event.hasTop()) {
-                key = event.getTopKey();
-                value = event.getTopValue();
-            }
+public class OptimizedQueryIterator implements SortedKeyValueIterator<Key,Value>, OptionDescriber {
+  
+  private static Logger log = Logger.getLogger(OptimizedQueryIterator.class);
+  private EvaluatingIterator event = null;
+  private SortedKeyValueIterator<Key,Value> index = null;
+  private Key key = null;
+  private Value value = null;
+  private boolean eventSpecificRange = false;
+  
+  public IteratorOptions describeOptions() {
+    Map<String,String> options = new HashMap<String,String>();
+    options.put(EvaluatingIterator.QUERY_OPTION, "full query expression");
+    options.put(BooleanLogicIterator.FIELD_INDEX_QUERY, "modified query for the field index query portion");
+    options.put(ReadAheadIterator.QUEUE_SIZE, "parallel queue size");
+    options.put(ReadAheadIterator.TIMEOUT, "parallel iterator timeout");
+    return new IteratorOptions(getClass().getSimpleName(), "evaluates event objects against an expression using the field index", options, null);
+  }
+  
+  public boolean validateOptions(Map<String,String> options) {
+    if (options.containsKey(EvaluatingIterator.QUERY_OPTION) && options.containsKey(BooleanLogicIterator.FIELD_INDEX_QUERY)) {
+      return true;
+    }
+    return false;
+  }
+  
+  public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, IteratorEnvironment env) throws IOException {
+    if (!validateOptions(options)) {
+      throw new IllegalArgumentException("Invalid options");
+    }
+    
+    // Setup the EvaluatingIterator
+    event = new EvaluatingIterator();
+    event.init(source.deepCopy(env), options, env);
+    
+    // if queue size and timeout are set, then use the read ahead iterator
+    if (options.containsKey(ReadAheadIterator.QUEUE_SIZE) && options.containsKey(ReadAheadIterator.TIMEOUT)) {
+      BooleanLogicIterator bli = new BooleanLogicIterator();
+      bli.init(source, options, env);
+      index = new ReadAheadIterator();
+      index.init(bli, options, env);
+    } else {
+      index = new BooleanLogicIterator();
+      // index.setDebug(Level.DEBUG);
+      index.init(source, options, env);
+    }
+    
+  }
+  
+  public OptimizedQueryIterator() {}
+  
+  public OptimizedQueryIterator(OptimizedQueryIterator other, IteratorEnvironment env) {
+    this.event = other.event;
+    this.index = other.index;
+  }
+  
+  public SortedKeyValueIterator<Key,Value> deepCopy(IteratorEnvironment env) {
+    return new OptimizedQueryIterator(this, env);
+  }
+  
+  public Key getTopKey() {
+    if (log.isDebugEnabled()) {
+      log.debug("getTopKey: " + key);
+    }
+    return key;
+  }
+  
+  public Value getTopValue() {
+    if (log.isDebugEnabled()) {
+      log.debug("getTopValue: " + value);
+    }
+    return value;
+  }
+  
+  public boolean hasTop() {
+    if (log.isDebugEnabled()) {
+      log.debug("hasTop: returned: " + (key != null));
+    }
+    return (key != null);
+  }
+  
+  public void next() throws IOException {
+    if (log.isDebugEnabled()) {
+      log.debug("next");
+    }
+    if (key != null) {
+      key = null;
+      value = null;
+    }
+    
+    if (eventSpecificRange) {
+      // Then this will probably return nothing
+      event.next();
+      if (event.hasTop()) {
+        key = event.getTopKey();
+        value = event.getTopValue();
+      }
+    } else {
+      
+      do {
+        index.next();
+        // If the index has a match, then seek the event to the key
+        if (index.hasTop()) {
+          Key eventKey = index.getTopKey();
+          Key endKey = eventKey.followingKey(PartialKey.ROW_COLFAM);
+          Key startKey = new Key(eventKey.getRow(), eventKey.getColumnFamily());
+          Range eventRange = new Range(startKey, endKey);
+          HashSet<ByteSequence> cf = new HashSet<ByteSequence>();
+          cf.add(eventKey.getColumnFamilyData());
+          event.seek(eventRange, cf, true);
+          if (event.hasTop()) {
+            key = event.getTopKey();
+            value = event.getTopValue();
+          }
+        }
+      } while (key == null && index.hasTop());
+    }
+    // Sanity check. Make sure both returnValue and returnKey are null or both are not null
+    if (!((key == null && value == null) || (key != null && value != null))) {
+      log.warn("Key: " + ((key == null) ? "null" : key.toString()));
+      log.warn("Value: " + ((value == null) ? "null" : value.toString()));
+      throw new IOException("Return values are inconsistent");
+    }
+    
+  }
+  
+  public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
+    if (log.isDebugEnabled()) {
+      log.debug("seek, range:" + range);
+    }
+    // Test the range to see if it is event specific.
+    if (null != range.getEndKey() && range.getEndKey().getColumnFamily() != null && range.getEndKey().getColumnFamily().getLength() != 0) {
+      if (log.isDebugEnabled()) {
+        log.debug("Jumping straight to the event");
+      }
+      // Then this range is for a specific event. We don't need to use the index iterator to find it, we can just
+      // seek to it with the event iterator and evaluate it.
+      eventSpecificRange = true;
+      event.seek(range, columnFamilies, inclusive);
+      if (event.hasTop()) {
+        key = event.getTopKey();
+        value = event.getTopValue();
+      }
+    } else {
+      if (log.isDebugEnabled()) {
+        log.debug("Using BooleanLogicIteratorJexl");
+      }
+      // Seek the boolean logic iterator
+      index.seek(range, columnFamilies, inclusive);
+      
+      // If the index has a match, then seek the event to the key
+      if (index.hasTop()) {
+        Key eventKey = index.getTopKey();
+        // Range eventRange = new Range(eventKey, eventKey);
+        Range eventRange = new Range(eventKey.getRow());
+        HashSet<ByteSequence> cf = new HashSet<ByteSequence>();
+        cf.add(eventKey.getColumnFamilyData());
+        event.seek(eventRange, cf, true);
+        if (event.hasTop()) {
+          key = event.getTopKey();
+          value = event.getTopValue();
         } else {
-
-            do {
-                index.next();
-                //If the index has a match, then seek the event to the key
-                if (index.hasTop()) {
-                    Key eventKey = index.getTopKey();
-                    Range eventRange = new Range(eventKey.getRow());
-                    HashSet<ByteSequence> cf = new HashSet<ByteSequence>();
-                    cf.add(eventKey.getColumnFamilyData());
-                    event.seek(eventRange, cf, true);
-                    if (event.hasTop()) {
-                        key = event.getTopKey();
-                        value = event.getTopValue();
-                    }
-                }
-            } while (key == null && index.hasTop());
-        }
-        //Sanity check. Make sure both returnValue and returnKey are null or both are not null
-        if (!((key == null && value == null) || (key != null && value != null))) {
-            log.warn("Key: " + ((key == null) ? "null" : key.toString()));
-            log.warn("Value: " + ((value == null) ? "null" : value.toString()));
-            throw new IOException("Return values are inconsistent");
-        }
-
-    }
-
-    public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
-        if (log.isDebugEnabled()) {
-            log.debug("seek, range:" + range);
-        }
-        //Test the range to see if it is event specific.
-        if (null != range.getStartKey() && range.getStartKey().getColumnFamily() != null && !range.getStartKey().getColumnFamily().toString().equals("")) {
-            if (log.isDebugEnabled()) {
-                log.debug("Jumping straight to the event");
-            }
-            //Then this range is for a specific event. We don't need to use the index iterator to find it, we can just
-            //seek to it with the event iterator and evaluate it.
-            eventSpecificRange = true;
-            event.seek(range, columnFamilies, inclusive);
-            if (event.hasTop()) {
-                key = event.getTopKey();
-                value = event.getTopValue();
-            }
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug("Using BooleanLogicIteratorJexl");
-            }
-            //Seek the boolean logic iterator
-            index.seek(range, columnFamilies, inclusive);
-
-            //If the index has a match, then seek the event to the key
-            if (index.hasTop()) {
-                Key eventKey = index.getTopKey();
-                //Range eventRange = new Range(eventKey, eventKey);
-                Range eventRange = new Range(eventKey.getRow());
-                HashSet<ByteSequence> cf = new HashSet<ByteSequence>();
-                cf.add(eventKey.getColumnFamilyData());
-                event.seek(eventRange, cf, true);
-                if (event.hasTop()) {
-                    key = event.getTopKey();
-                    value = event.getTopValue();
-                } else {
-                    next();
-                }
-            }
+          next();
         }
+      }
     }
+  }
 }