You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jd...@apache.org on 2009/11/04 06:10:56 UTC

svn commit: r832659 - in /hadoop/hbase/trunk: CHANGES.txt src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java

Author: jdcryans
Date: Wed Nov  4 05:10:56 2009
New Revision: 832659

URL: http://svn.apache.org/viewvc?rev=832659&view=rev
Log:
HBASE-1781  Weird behavior of WildcardColumnTracker.checkColumn(), 
               looks like recursive loop

Modified:
    hadoop/hbase/trunk/CHANGES.txt
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java
    hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java

Modified: hadoop/hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=832659&r1=832658&r2=832659&view=diff
==============================================================================
--- hadoop/hbase/trunk/CHANGES.txt (original)
+++ hadoop/hbase/trunk/CHANGES.txt Wed Nov  4 05:10:56 2009
@@ -92,6 +92,8 @@
    HBASE-1919  code: HRS.delete seems to ignore exceptions it shouldnt
    HBASE-1951  Stack overflow when calling HTable.checkAndPut() 
                when deleting a lot of values
+   HBASE-1781  Weird behavior of WildcardColumnTracker.checkColumn(), 
+               looks like recursive loop
 
   IMPROVEMENTS
    HBASE-1760  Cleanup TODOs in HTable

Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java?rev=832659&r1=832658&r2=832659&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/WildcardColumnTracker.java Wed Nov  4 05:10:56 2009
@@ -89,94 +89,57 @@
    * @return MatchCode telling QueryMatcher what action to take
    */
   public MatchCode checkColumn(byte [] bytes, int offset, int length) {
+    boolean recursive = false;
+    do {
 
-    // Nothing to match against, add to new and include
-    if(this.column == null && this.newColumn == null) {
-      newColumns.add(new ColumnCount(bytes, offset, length, 1));
-      this.newColumn = newColumns.get(newIndex);
-      return MatchCode.INCLUDE;
-    }
-    
-    // Nothing old, compare against new
-    if(this.column == null && this.newColumn != null) {
-      int ret = Bytes.compareTo(newColumn.getBuffer(), newColumn.getOffset(), 
-          newColumn.getLength(), bytes, offset, length);
-      
-      // Same column
-      if(ret == 0) {
-        if(newColumn.increment() > this.maxVersions) {
-          return MatchCode.SKIP;
-        }
+      // Nothing to match against, add to new and include
+      if(this.column == null && this.newColumn == null) {
+        newColumns.add(new ColumnCount(bytes, offset, length, 1));
+        this.newColumn = newColumns.get(newIndex);
         return MatchCode.INCLUDE;
       }
-      
-      // Specified column is bigger than current column
-      // Move down current column and check again
-      if(ret <= -1) {
-        if(++newIndex == newColumns.size()) {
-          // No more, add to end and include
-          newColumns.add(new ColumnCount(bytes, offset, length, 1));
-          this.newColumn = newColumns.get(newIndex);
+
+      // Nothing old, compare against new
+      if(this.column == null && this.newColumn != null) {
+        int ret = Bytes.compareTo(newColumn.getBuffer(), newColumn.getOffset(),
+            newColumn.getLength(), bytes, offset, length);
+
+        // Same column
+        if(ret == 0) {
+          if(newColumn.increment() > this.maxVersions) {
+            return MatchCode.SKIP;
+          }
           return MatchCode.INCLUDE;
         }
-        this.newColumn = newColumns.get(newIndex);
-        return checkColumn(bytes, offset, length);
-      }
-      
-      // ret >= 1
-      // Specified column is smaller than current column
-      // Nothing to match against, add to new and include
-      newColumns.add(new ColumnCount(bytes, offset, length, 1));
-      this.newColumn = newColumns.get(++newIndex);
-      return MatchCode.INCLUDE;
-    }
-    
-    // Nothing new, compare against old
-    if(this.newColumn == null && this.column != null) {
-      int ret = Bytes.compareTo(column.getBuffer(), column.getOffset(), 
-          column.getLength(), bytes, offset, length);
-      
-      // Same column
-      if(ret == 0) {
-        if(column.increment() > this.maxVersions) {
-          return MatchCode.SKIP;
-        }
-        return MatchCode.INCLUDE;
-      }
-      
-      // Specified column is bigger than current column
-      // Move down current column and check again
-      if(ret <= -1) {
-        if(++index == columns.size()) {
-          // No more, add to new and include (new was empty prior to this)
-          newColumns.add(new ColumnCount(bytes, offset, length, 1));
+
+        // Specified column is bigger than current column
+        // Move down current column and check again
+        if(ret <= -1) {
+          if(++newIndex == newColumns.size()) {
+            // No more, add to end and include
+            newColumns.add(new ColumnCount(bytes, offset, length, 1));
+            this.newColumn = newColumns.get(newIndex);
+            return MatchCode.INCLUDE;
+          }
           this.newColumn = newColumns.get(newIndex);
-          this.column = null;
-          return MatchCode.INCLUDE;
+          //return checkColumn(bytes, offset, length);
+          recursive = true;
+          continue;
         }
-        this.column = columns.get(index);
-        return checkColumn(bytes, offset, length);
+
+        // ret >= 1
+        // Specified column is smaller than current column
+        // Nothing to match against, add to new and include
+        newColumns.add(new ColumnCount(bytes, offset, length, 1));
+        this.newColumn = newColumns.get(++newIndex);
+        return MatchCode.INCLUDE;
       }
-      
-      // ret >= 1
-      // Specified column is smaller than current column
-      // Nothing to match against, add to new and include
-      newColumns.add(new ColumnCount(bytes, offset, length, 1));
-      this.newColumn = newColumns.get(newIndex);
-      return MatchCode.INCLUDE;
-    }
 
-    if (column != null && newColumn != null) {
-      // There are new and old, figure which to check first
-      int ret = Bytes.compareTo(column.getBuffer(), column.getOffset(), 
-        column.getLength(), newColumn.getBuffer(), newColumn.getOffset(), 
-        newColumn.getLength());
-        
-      // Old is smaller than new, compare against old
-      if(ret <= -1) {
-        ret = Bytes.compareTo(column.getBuffer(), column.getOffset(), 
-          column.getLength(), bytes, offset, length);
-      
+      // Nothing new, compare against old
+      if(this.newColumn == null && this.column != null) {
+        int ret = Bytes.compareTo(column.getBuffer(), column.getOffset(),
+            column.getLength(), bytes, offset, length);
+
         // Same column
         if(ret == 0) {
           if(column.increment() > this.maxVersions) {
@@ -184,57 +147,105 @@
           }
           return MatchCode.INCLUDE;
         }
-      
+
         // Specified column is bigger than current column
         // Move down current column and check again
         if(ret <= -1) {
           if(++index == columns.size()) {
+            // No more, add to new and include (new was empty prior to this)
+            newColumns.add(new ColumnCount(bytes, offset, length, 1));
+            this.newColumn = newColumns.get(newIndex);
             this.column = null;
-          } else {
-            this.column = columns.get(index);
+            return MatchCode.INCLUDE;
           }
-          return checkColumn(bytes, offset, length);
+          this.column = columns.get(index);
+          //return checkColumn(bytes, offset, length);
+          recursive = true;
+          continue;
         }
-      
+
         // ret >= 1
         // Specified column is smaller than current column
         // Nothing to match against, add to new and include
         newColumns.add(new ColumnCount(bytes, offset, length, 1));
+        this.newColumn = newColumns.get(newIndex);
         return MatchCode.INCLUDE;
       }
-    }
 
-    if (newColumn != null) {
-      // Cannot be equal, so ret >= 1
-      // New is smaller than old, compare against new
-      int ret = Bytes.compareTo(newColumn.getBuffer(), newColumn.getOffset(), 
-        newColumn.getLength(), bytes, offset, length);
-    
-      // Same column
-      if(ret == 0) {
-        if(newColumn.increment() > this.maxVersions) {
-          return MatchCode.SKIP;
+      if (column != null && newColumn != null) {
+        // There are new and old, figure which to check first
+        int ret = Bytes.compareTo(column.getBuffer(), column.getOffset(),
+          column.getLength(), newColumn.getBuffer(), newColumn.getOffset(),
+          newColumn.getLength());
+
+        // Old is smaller than new, compare against old
+        if(ret <= -1) {
+          ret = Bytes.compareTo(column.getBuffer(), column.getOffset(),
+            column.getLength(), bytes, offset, length);
+
+          // Same column
+          if(ret == 0) {
+            if(column.increment() > this.maxVersions) {
+              return MatchCode.SKIP;
+            }
+            return MatchCode.INCLUDE;
+          }
+
+          // Specified column is bigger than current column
+          // Move down current column and check again
+          if(ret <= -1) {
+            if(++index == columns.size()) {
+              this.column = null;
+            } else {
+              this.column = columns.get(index);
+            }
+            //return checkColumn(bytes, offset, length);
+            recursive = true;
+            continue;
+          }
+
+          // ret >= 1
+          // Specified column is smaller than current column
+          // Nothing to match against, add to new and include
+          newColumns.add(new ColumnCount(bytes, offset, length, 1));
+          return MatchCode.INCLUDE;
         }
-        return MatchCode.INCLUDE;
       }
-    
-      // Specified column is bigger than current column
-      // Move down current column and check again
-      if(ret <= -1) {
-        if(++newIndex == newColumns.size()) {
-          this.newColumn = null;
-        } else {
-          this.newColumn = newColumns.get(newIndex);
+
+      if (newColumn != null) {
+        // Cannot be equal, so ret >= 1
+        // New is smaller than old, compare against new
+        int ret = Bytes.compareTo(newColumn.getBuffer(), newColumn.getOffset(),
+          newColumn.getLength(), bytes, offset, length);
+
+        // Same column
+        if(ret == 0) {
+          if(newColumn.increment() > this.maxVersions) {
+            return MatchCode.SKIP;
+          }
+          return MatchCode.INCLUDE;
         }
-        return checkColumn(bytes, offset, length);
+
+        // Specified column is bigger than current column
+        // Move down current column and check again
+        if(ret <= -1) {
+          if(++newIndex == newColumns.size()) {
+            this.newColumn = null;
+          } else {
+            this.newColumn = newColumns.get(newIndex);
+          }
+          //return checkColumn(bytes, offset, length);
+          recursive = true;
+          continue;
+        }
+
+        // ret >= 1
+        // Specified column is smaller than current column
+        // Nothing to match against, add to new and include
+        newColumns.add(new ColumnCount(bytes, offset, length, 1));
+        return MatchCode.INCLUDE;
       }
-    
-      // ret >= 1
-      // Specified column is smaller than current column
-      // Nothing to match against, add to new and include
-      newColumns.add(new ColumnCount(bytes, offset, length, 1));
-      return MatchCode.INCLUDE;
-    }
+    } while(recursive);
 
     // No match happened, add to new and include
     newColumns.add(new ColumnCount(bytes, offset, length, 1));

Modified: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java?rev=832659&r1=832658&r2=832659&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java (original)
+++ hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestWildcardColumnTracker.java Wed Nov  4 05:10:56 2009
@@ -329,6 +329,23 @@
       }
     }
   }
+
+  // HBASE-1781
+  public void testStackOverflow(){
+    int maxVersions = 1;
+
+    ColumnTracker wild = new WildcardColumnTracker(maxVersions);
+    for(int i = 0; i < 100000; i+=2) {
+      byte [] col = Bytes.toBytes("col"+i);
+      wild.checkColumn(col, 0, col.length);
+    }
+    wild.update();
+
+    for(int i = 1; i < 100000; i+=2) {
+      byte [] col = Bytes.toBytes("col"+i);
+      wild.checkColumn(col, 0, col.length);
+    }
+  }