You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by be...@apache.org on 2015/08/08 12:31:22 UTC

[1/3] cassandra git commit: Introduce our own AbstractIterator, that is easier for debugging

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-3.0 8c64cefd1 -> 489a9e8fa
  refs/heads/trunk 288f2cf4f -> 05de664ac


Introduce our own AbstractIterator, that is easier for debugging

patch by benedict; reviewed by ariel for CASSANDRA-9985


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/489a9e8f
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/489a9e8f
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/489a9e8f

Branch: refs/heads/cassandra-3.0
Commit: 489a9e8fa91ab6680b2a3857ed4e97f7cf2677ba
Parents: 8c64cef
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Tue Aug 4 13:37:21 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Sat Aug 8 12:30:34 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cassandra/config/CFMetaData.java |   1 +
 .../apache/cassandra/cql3/UntypedResultSet.java |   2 +-
 .../org/apache/cassandra/db/LegacyLayout.java   |   2 +-
 .../apache/cassandra/db/RangeTombstoneList.java |   2 +-
 .../db/partitions/PartitionIterators.java       |   2 +-
 .../db/rows/AbstractUnfilteredRowIterator.java  |   2 +-
 .../cassandra/db/rows/BTreeBackedRow.java       |   2 +-
 .../LazilyInitializedUnfilteredRowIterator.java |   2 +-
 .../cassandra/hadoop/cql3/CqlRecordReader.java  |   2 +-
 .../cassandra/io/sstable/KeyIterator.java       |   2 +-
 .../io/sstable/SSTableIdentityIterator.java     |   2 +-
 .../io/sstable/SSTableSimpleIterator.java       |   2 +-
 .../io/sstable/format/big/BigTableScanner.java  |   2 +-
 .../apache/cassandra/service/StorageProxy.java  |   1 +
 .../service/pager/MultiPartitionPager.java      |   2 +-
 .../cassandra/thrift/ThriftResultsMerger.java   |   2 +-
 .../cassandra/utils/AbstractIterator.java       |  83 ++++
 .../org/apache/cassandra/utils/FBUtilities.java |   2 +-
 .../apache/cassandra/utils/IntervalTree.java    |   2 +-
 .../apache/cassandra/utils/MergeIterator.java   |   2 +-
 .../org/apache/cassandra/utils/MerkleTree.java  |   1 -
 .../cassandra/utils/AbstractIteratorTest.java   | 383 +++++++++++++++++++
 .../utils/MergeIteratorComparisonTest.java      |   2 +-
 .../cassandra/utils/MergeIteratorTest.java      |   2 +-
 .../apache/cassandra/utils/MerkleTreeTest.java  |   2 +-
 25 files changed, 488 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 0982109..1d38274 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -51,6 +51,7 @@ import org.apache.cassandra.io.util.DataInputPlus;
 import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.schema.*;
 import org.apache.cassandra.utils.*;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.github.jamm.Unmetered;
 
 /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
index 97ab60a..c652279 100644
--- a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
@@ -22,7 +22,7 @@ import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/LegacyLayout.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java
index 50e5d04..fb896f5 100644
--- a/src/java/org/apache/cassandra/db/LegacyLayout.java
+++ b/src/java/org/apache/cassandra/db/LegacyLayout.java
@@ -23,7 +23,7 @@ import java.io.IOError;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 import com.google.common.collect.PeekingIterator;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/RangeTombstoneList.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/RangeTombstoneList.java b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
index 32b3625..c92a296 100644
--- a/src/java/org/apache/cassandra/db/RangeTombstoneList.java
+++ b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java b/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
index 219aa5a..eeb6a4b 100644
--- a/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
+++ b/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
@@ -20,7 +20,7 @@ package org.apache.cassandra.db.partitions;
 import java.util.*;
 import java.security.MessageDigest;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.db.SinglePartitionReadCommand;
 import org.apache.cassandra.db.rows.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java b/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
index 1d95c97..f2389a7 100644
--- a/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
+++ b/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
@@ -17,7 +17,7 @@
  */
 package org.apache.cassandra.db.rows;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java b/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
index 8f9e921..2e0d320 100644
--- a/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
+++ b/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
@@ -22,7 +22,6 @@ import java.util.*;
 import java.util.function.Predicate;
 
 import com.google.common.base.Function;
-import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.apache.cassandra.config.CFMetaData;
@@ -31,6 +30,7 @@ import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.partitions.PartitionUpdate;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.ObjectSizes;
 import org.apache.cassandra.utils.btree.BTree;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java b/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
index 8d81898..8ba4394 100644
--- a/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
+++ b/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
@@ -17,7 +17,7 @@
  */
 package org.apache.cassandra.db.rows;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java b/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
index 6db851d..8373a2b 100644
--- a/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
+++ b/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
@@ -27,7 +27,7 @@ import java.util.*;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang3.StringUtils;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/KeyIterator.java b/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
index 8fb300b..124720e 100644
--- a/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
@@ -21,7 +21,7 @@ import java.io.DataInput;
 import java.io.File;
 import java.io.IOException;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.DecoratedKey;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java b/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
index 23224ce..793cd81 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
@@ -19,7 +19,7 @@ package org.apache.cassandra.io.sstable;
 
 import java.io.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
index 5a0a0ad..65a5259 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.io.IOError;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
index 1b3b407..d135df0 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.util.concurrent.RateLimiter;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/service/StorageProxy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java
index 1e1f847..1fc410e 100644
--- a/src/java/org/apache/cassandra/service/StorageProxy.java
+++ b/src/java/org/apache/cassandra/service/StorageProxy.java
@@ -67,6 +67,7 @@ import org.apache.cassandra.service.paxos.*;
 import org.apache.cassandra.tracing.Tracing;
 import org.apache.cassandra.triggers.TriggerExecutor;
 import org.apache.cassandra.utils.*;
+import org.apache.cassandra.utils.AbstractIterator;
 
 public class StorageProxy implements StorageProxyMBean
 {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java b/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
index e329fd5..5d06df7 100644
--- a/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
+++ b/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
@@ -19,7 +19,7 @@ package org.apache.cassandra.service.pager;
 
 import java.util.List;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.rows.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java b/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
index 59d1b68..09e8d4b 100644
--- a/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
+++ b/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
@@ -21,7 +21,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.PeekingIterator;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/AbstractIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/AbstractIterator.java b/src/java/org/apache/cassandra/utils/AbstractIterator.java
new file mode 100644
index 0000000..dd3d73c
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/AbstractIterator.java
@@ -0,0 +1,83 @@
+/*
+* 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 org.apache.cassandra.utils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.google.common.collect.PeekingIterator;
+
+public abstract class AbstractIterator<V> implements Iterator<V>, PeekingIterator<V>
+{
+
+    private static enum State { MUST_FETCH, HAS_NEXT, DONE, FAILED }
+    private State state = State.MUST_FETCH;
+    private V next;
+
+    protected V endOfData()
+    {
+        state = State.DONE;
+        return null;
+    }
+
+    protected abstract V computeNext();
+
+    public boolean hasNext()
+    {
+        switch (state)
+        {
+            case MUST_FETCH:
+                state = State.FAILED;
+                next = computeNext();
+
+            default:
+                if (state == State.DONE)
+                    return false;
+
+                state = State.HAS_NEXT;
+                return true;
+
+            case FAILED:
+                throw new IllegalStateException();
+        }
+    }
+
+    public V next()
+    {
+        if (state != State.HAS_NEXT && !hasNext())
+            throw new NoSuchElementException();
+
+        state = State.MUST_FETCH;
+        V result = next;
+        next = null;
+        return result;
+    }
+
+    public V peek()
+    {
+        if (!hasNext())
+            throw new NoSuchElementException();
+        return next;
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/FBUtilities.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java
index 9569619..d1462d2 100644
--- a/src/java/org/apache/cassandra/utils/FBUtilities.java
+++ b/src/java/org/apache/cassandra/utils/FBUtilities.java
@@ -29,7 +29,7 @@ import java.util.concurrent.*;
 import java.util.zip.Checksum;
 
 import com.google.common.base.Joiner;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/IntervalTree.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/IntervalTree.java b/src/java/org/apache/cassandra/utils/IntervalTree.java
index f40e9a3..b92112e 100644
--- a/src/java/org/apache/cassandra/utils/IntervalTree.java
+++ b/src/java/org/apache/cassandra/utils/IntervalTree.java
@@ -23,7 +23,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.*;
 
 import com.google.common.base.Joiner;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/MergeIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/MergeIterator.java b/src/java/org/apache/cassandra/utils/MergeIterator.java
index c903a0f..0cc5306 100644
--- a/src/java/org/apache/cassandra/utils/MergeIterator.java
+++ b/src/java/org/apache/cassandra/utils/MergeIterator.java
@@ -20,7 +20,7 @@ package org.apache.cassandra.utils;
 import java.io.Closeable;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 /** Merges sorted input iterators which individually contain unique items. */
 public abstract class MergeIterator<In,Out> extends AbstractIterator<Out> implements IMergeIterator<In, Out>

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/MerkleTree.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/MerkleTree.java b/src/java/org/apache/cassandra/utils/MerkleTree.java
index b4a782d..b3bccac 100644
--- a/src/java/org/apache/cassandra/utils/MerkleTree.java
+++ b/src/java/org/apache/cassandra/utils/MerkleTree.java
@@ -23,7 +23,6 @@ import java.io.Serializable;
 import java.util.*;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.PeekingIterator;
 
 import org.apache.cassandra.db.TypeSizes;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java b/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
new file mode 100644
index 0000000..b2f9433
--- /dev/null
+++ b/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed 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 org.apache.cassandra.utils;
+
+import junit.framework.TestCase;
+
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Unit test for {@code AbstractIterator}.
+ *
+ * @author Kevin Bourrillion
+ */
+@SuppressWarnings("serial") // No serialization is used in this test
+// TODO(cpovirk): why is this slow (>1m/test) under GWT when fully optimized?
+public class AbstractIteratorTest extends TestCase
+{
+
+    public void testDefaultBehaviorOfNextAndHasNext()
+    {
+
+        // This sample AbstractIterator returns 0 on the first call, 1 on the
+        // second, then signals that it's reached the end of the data
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            private int rep;
+
+            @Override
+            public Integer computeNext()
+            {
+                switch (rep++)
+                {
+                    case 0:
+                        return 0;
+                    case 1:
+                        return 1;
+                    case 2:
+                        return endOfData();
+                    default:
+                        fail("Should not have been invoked again");
+                        return null;
+                }
+            }
+        };
+
+        assertTrue(iter.hasNext());
+        assertEquals(0, (int) iter.next());
+
+        // verify idempotence of hasNext()
+        assertTrue(iter.hasNext());
+        assertTrue(iter.hasNext());
+        assertTrue(iter.hasNext());
+        assertEquals(1, (int) iter.next());
+
+        assertFalse(iter.hasNext());
+
+        // Make sure computeNext() doesn't get invoked again
+        assertFalse(iter.hasNext());
+
+        try
+        {
+            iter.next();
+            fail("no exception thrown");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testDefaultBehaviorOfPeek()
+    {
+    /*
+     * This sample AbstractIterator returns 0 on the first call, 1 on the
+     * second, then signals that it's reached the end of the data
+     */
+        AbstractIterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            private int rep;
+
+            @Override
+            public Integer computeNext()
+            {
+                switch (rep++)
+                {
+                    case 0:
+                        return 0;
+                    case 1:
+                        return 1;
+                    case 2:
+                        return endOfData();
+                    default:
+                        fail("Should not have been invoked again");
+                        return null;
+                }
+            }
+        };
+
+        assertEquals(0, (int) iter.peek());
+        assertEquals(0, (int) iter.peek());
+        assertTrue(iter.hasNext());
+        assertEquals(0, (int) iter.peek());
+        assertEquals(0, (int) iter.next());
+
+        assertEquals(1, (int) iter.peek());
+        assertEquals(1, (int) iter.next());
+
+        try
+        {
+            iter.peek();
+            fail("peek() should throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.peek();
+            fail("peek() should continue to throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.next();
+            fail("next() should throw NoSuchElementException as usual");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.peek();
+            fail("peek() should still throw NoSuchElementException after next()");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testFreesNextReference() throws InterruptedException
+    {
+        Iterator<Object> itr = new AbstractIterator<Object>()
+        {
+            @Override
+            public Object computeNext()
+            {
+                return new Object();
+            }
+        };
+        WeakReference<Object> ref = new WeakReference<Object>(itr.next());
+        while (ref.get() != null)
+        {
+            System.gc();
+            Thread.sleep(1);
+        }
+    }
+
+    public void testDefaultBehaviorOfPeekForEmptyIteration()
+    {
+
+        AbstractIterator<Integer> empty = new AbstractIterator<Integer>()
+        {
+            private boolean alreadyCalledEndOfData;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (alreadyCalledEndOfData)
+                {
+                    fail("Should not have been invoked again");
+                }
+                alreadyCalledEndOfData = true;
+                return endOfData();
+            }
+        };
+
+        try
+        {
+            empty.peek();
+            fail("peek() should throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            empty.peek();
+            fail("peek() should continue to throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testException()
+    {
+        final SomeUncheckedException exception = new SomeUncheckedException();
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            public Integer computeNext()
+            {
+                throw exception;
+            }
+        };
+
+        // It should pass through untouched
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (SomeUncheckedException e)
+        {
+            assertSame(exception, e);
+        }
+    }
+
+    public void testExceptionAfterEndOfData()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            public Integer computeNext()
+            {
+                endOfData();
+                throw new SomeUncheckedException();
+            }
+        };
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (SomeUncheckedException expected)
+        {
+        }
+    }
+
+    public void testCantRemove()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            boolean haveBeenCalled;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (haveBeenCalled)
+                {
+                    endOfData();
+                }
+                haveBeenCalled = true;
+                return 0;
+            }
+        };
+
+        assertEquals(0, (int) iter.next());
+
+        try
+        {
+            iter.remove();
+            fail("No exception thrown");
+        }
+        catch (UnsupportedOperationException expected)
+        {
+        }
+    }
+
+    public void testSneakyThrow() throws Exception
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            boolean haveBeenCalled;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (haveBeenCalled)
+                {
+                    fail("Should not have been called again");
+                }
+                else
+                {
+                    haveBeenCalled = true;
+                    sneakyThrow(new SomeCheckedException());
+                }
+                return null; // never reached
+            }
+        };
+
+        // The first time, the sneakily-thrown exception comes out
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (Exception e)
+        {
+            if (!(e instanceof SomeCheckedException))
+            {
+                throw e;
+            }
+        }
+
+        // But the second time, AbstractIterator itself throws an ISE
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (IllegalStateException expected)
+        {
+        }
+    }
+
+    public void testReentrantHasNext()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            protected Integer computeNext()
+            {
+                hasNext();
+                return null;
+            }
+        };
+        try
+        {
+            iter.hasNext();
+            fail();
+        }
+        catch (IllegalStateException expected)
+        {
+        }
+    }
+
+    /**
+     * Throws a undeclared checked exception.
+     */
+    private static void sneakyThrow(Throwable t)
+    {
+        class SneakyThrower<T extends Throwable>
+        {
+            @SuppressWarnings("unchecked")
+                // not really safe, but that's the point
+            void throwIt(Throwable t) throws T
+            {
+                throw (T) t;
+            }
+        }
+        new SneakyThrower<Error>().throwIt(t);
+    }
+
+    private static class SomeCheckedException extends Exception
+    {
+    }
+
+    private static class SomeUncheckedException extends RuntimeException
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java b/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
index 6a4bd2b..5f2de73 100644
--- a/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
+++ b/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
@@ -23,7 +23,7 @@ import java.util.*;
 
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java b/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
index b6d3d58..fe2cecf 100644
--- a/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
+++ b/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
@@ -21,7 +21,7 @@ package org.apache.cassandra.utils;
 import java.util.Arrays;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Ordering;
 import org.junit.Before;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java b/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
index d2da07b..5924de0 100644
--- a/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
+++ b/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
@@ -21,7 +21,7 @@ package org.apache.cassandra.utils;
 import java.math.BigInteger;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.junit.Before;
 import org.junit.Test;


[2/3] cassandra git commit: Introduce our own AbstractIterator, that is easier for debugging

Posted by be...@apache.org.
Introduce our own AbstractIterator, that is easier for debugging

patch by benedict; reviewed by ariel for CASSANDRA-9985


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/489a9e8f
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/489a9e8f
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/489a9e8f

Branch: refs/heads/trunk
Commit: 489a9e8fa91ab6680b2a3857ed4e97f7cf2677ba
Parents: 8c64cef
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Tue Aug 4 13:37:21 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Sat Aug 8 12:30:34 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cassandra/config/CFMetaData.java |   1 +
 .../apache/cassandra/cql3/UntypedResultSet.java |   2 +-
 .../org/apache/cassandra/db/LegacyLayout.java   |   2 +-
 .../apache/cassandra/db/RangeTombstoneList.java |   2 +-
 .../db/partitions/PartitionIterators.java       |   2 +-
 .../db/rows/AbstractUnfilteredRowIterator.java  |   2 +-
 .../cassandra/db/rows/BTreeBackedRow.java       |   2 +-
 .../LazilyInitializedUnfilteredRowIterator.java |   2 +-
 .../cassandra/hadoop/cql3/CqlRecordReader.java  |   2 +-
 .../cassandra/io/sstable/KeyIterator.java       |   2 +-
 .../io/sstable/SSTableIdentityIterator.java     |   2 +-
 .../io/sstable/SSTableSimpleIterator.java       |   2 +-
 .../io/sstable/format/big/BigTableScanner.java  |   2 +-
 .../apache/cassandra/service/StorageProxy.java  |   1 +
 .../service/pager/MultiPartitionPager.java      |   2 +-
 .../cassandra/thrift/ThriftResultsMerger.java   |   2 +-
 .../cassandra/utils/AbstractIterator.java       |  83 ++++
 .../org/apache/cassandra/utils/FBUtilities.java |   2 +-
 .../apache/cassandra/utils/IntervalTree.java    |   2 +-
 .../apache/cassandra/utils/MergeIterator.java   |   2 +-
 .../org/apache/cassandra/utils/MerkleTree.java  |   1 -
 .../cassandra/utils/AbstractIteratorTest.java   | 383 +++++++++++++++++++
 .../utils/MergeIteratorComparisonTest.java      |   2 +-
 .../cassandra/utils/MergeIteratorTest.java      |   2 +-
 .../apache/cassandra/utils/MerkleTreeTest.java  |   2 +-
 25 files changed, 488 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 0982109..1d38274 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -51,6 +51,7 @@ import org.apache.cassandra.io.util.DataInputPlus;
 import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.schema.*;
 import org.apache.cassandra.utils.*;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.github.jamm.Unmetered;
 
 /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
index 97ab60a..c652279 100644
--- a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
@@ -22,7 +22,7 @@ import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/LegacyLayout.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java
index 50e5d04..fb896f5 100644
--- a/src/java/org/apache/cassandra/db/LegacyLayout.java
+++ b/src/java/org/apache/cassandra/db/LegacyLayout.java
@@ -23,7 +23,7 @@ import java.io.IOError;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 import com.google.common.collect.PeekingIterator;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/RangeTombstoneList.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/RangeTombstoneList.java b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
index 32b3625..c92a296 100644
--- a/src/java/org/apache/cassandra/db/RangeTombstoneList.java
+++ b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java b/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
index 219aa5a..eeb6a4b 100644
--- a/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
+++ b/src/java/org/apache/cassandra/db/partitions/PartitionIterators.java
@@ -20,7 +20,7 @@ package org.apache.cassandra.db.partitions;
 import java.util.*;
 import java.security.MessageDigest;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.db.SinglePartitionReadCommand;
 import org.apache.cassandra.db.rows.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java b/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
index 1d95c97..f2389a7 100644
--- a/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
+++ b/src/java/org/apache/cassandra/db/rows/AbstractUnfilteredRowIterator.java
@@ -17,7 +17,7 @@
  */
 package org.apache.cassandra.db.rows;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java b/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
index 8f9e921..2e0d320 100644
--- a/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
+++ b/src/java/org/apache/cassandra/db/rows/BTreeBackedRow.java
@@ -22,7 +22,6 @@ import java.util.*;
 import java.util.function.Predicate;
 
 import com.google.common.base.Function;
-import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.apache.cassandra.config.CFMetaData;
@@ -31,6 +30,7 @@ import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.partitions.PartitionUpdate;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.ObjectSizes;
 import org.apache.cassandra.utils.btree.BTree;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java b/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
index 8d81898..8ba4394 100644
--- a/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
+++ b/src/java/org/apache/cassandra/db/rows/LazilyInitializedUnfilteredRowIterator.java
@@ -17,7 +17,7 @@
  */
 package org.apache.cassandra.db.rows;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java b/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
index 6db851d..8373a2b 100644
--- a/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
+++ b/src/java/org/apache/cassandra/hadoop/cql3/CqlRecordReader.java
@@ -27,7 +27,7 @@ import java.util.*;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang3.StringUtils;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/KeyIterator.java b/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
index 8fb300b..124720e 100644
--- a/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/KeyIterator.java
@@ -21,7 +21,7 @@ import java.io.DataInput;
 import java.io.File;
 import java.io.IOException;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.DecoratedKey;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java b/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
index 23224ce..793cd81 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableIdentityIterator.java
@@ -19,7 +19,7 @@ package org.apache.cassandra.io.sstable;
 
 import java.io.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
index 5a0a0ad..65a5259 100644
--- a/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableSimpleIterator.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.io.IOError;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
index 1b3b407..d135df0 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.util.concurrent.RateLimiter;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/service/StorageProxy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java
index 1e1f847..1fc410e 100644
--- a/src/java/org/apache/cassandra/service/StorageProxy.java
+++ b/src/java/org/apache/cassandra/service/StorageProxy.java
@@ -67,6 +67,7 @@ import org.apache.cassandra.service.paxos.*;
 import org.apache.cassandra.tracing.Tracing;
 import org.apache.cassandra.triggers.TriggerExecutor;
 import org.apache.cassandra.utils.*;
+import org.apache.cassandra.utils.AbstractIterator;
 
 public class StorageProxy implements StorageProxyMBean
 {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java b/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
index e329fd5..5d06df7 100644
--- a/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
+++ b/src/java/org/apache/cassandra/service/pager/MultiPartitionPager.java
@@ -19,7 +19,7 @@ package org.apache.cassandra.service.pager;
 
 import java.util.List;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.rows.*;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java b/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
index 59d1b68..09e8d4b 100644
--- a/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
+++ b/src/java/org/apache/cassandra/thrift/ThriftResultsMerger.java
@@ -21,7 +21,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.PeekingIterator;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/AbstractIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/AbstractIterator.java b/src/java/org/apache/cassandra/utils/AbstractIterator.java
new file mode 100644
index 0000000..dd3d73c
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/AbstractIterator.java
@@ -0,0 +1,83 @@
+/*
+* 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 org.apache.cassandra.utils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.google.common.collect.PeekingIterator;
+
+public abstract class AbstractIterator<V> implements Iterator<V>, PeekingIterator<V>
+{
+
+    private static enum State { MUST_FETCH, HAS_NEXT, DONE, FAILED }
+    private State state = State.MUST_FETCH;
+    private V next;
+
+    protected V endOfData()
+    {
+        state = State.DONE;
+        return null;
+    }
+
+    protected abstract V computeNext();
+
+    public boolean hasNext()
+    {
+        switch (state)
+        {
+            case MUST_FETCH:
+                state = State.FAILED;
+                next = computeNext();
+
+            default:
+                if (state == State.DONE)
+                    return false;
+
+                state = State.HAS_NEXT;
+                return true;
+
+            case FAILED:
+                throw new IllegalStateException();
+        }
+    }
+
+    public V next()
+    {
+        if (state != State.HAS_NEXT && !hasNext())
+            throw new NoSuchElementException();
+
+        state = State.MUST_FETCH;
+        V result = next;
+        next = null;
+        return result;
+    }
+
+    public V peek()
+    {
+        if (!hasNext())
+            throw new NoSuchElementException();
+        return next;
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/FBUtilities.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java
index 9569619..d1462d2 100644
--- a/src/java/org/apache/cassandra/utils/FBUtilities.java
+++ b/src/java/org/apache/cassandra/utils/FBUtilities.java
@@ -29,7 +29,7 @@ import java.util.concurrent.*;
 import java.util.zip.Checksum;
 
 import com.google.common.base.Joiner;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/IntervalTree.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/IntervalTree.java b/src/java/org/apache/cassandra/utils/IntervalTree.java
index f40e9a3..b92112e 100644
--- a/src/java/org/apache/cassandra/utils/IntervalTree.java
+++ b/src/java/org/apache/cassandra/utils/IntervalTree.java
@@ -23,7 +23,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.*;
 
 import com.google.common.base.Joiner;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/MergeIterator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/MergeIterator.java b/src/java/org/apache/cassandra/utils/MergeIterator.java
index c903a0f..0cc5306 100644
--- a/src/java/org/apache/cassandra/utils/MergeIterator.java
+++ b/src/java/org/apache/cassandra/utils/MergeIterator.java
@@ -20,7 +20,7 @@ package org.apache.cassandra.utils;
 import java.io.Closeable;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 /** Merges sorted input iterators which individually contain unique items. */
 public abstract class MergeIterator<In,Out> extends AbstractIterator<Out> implements IMergeIterator<In, Out>

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/src/java/org/apache/cassandra/utils/MerkleTree.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/MerkleTree.java b/src/java/org/apache/cassandra/utils/MerkleTree.java
index b4a782d..b3bccac 100644
--- a/src/java/org/apache/cassandra/utils/MerkleTree.java
+++ b/src/java/org/apache/cassandra/utils/MerkleTree.java
@@ -23,7 +23,6 @@ import java.io.Serializable;
 import java.util.*;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.PeekingIterator;
 
 import org.apache.cassandra.db.TypeSizes;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java b/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
new file mode 100644
index 0000000..b2f9433
--- /dev/null
+++ b/test/unit/org/apache/cassandra/utils/AbstractIteratorTest.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed 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 org.apache.cassandra.utils;
+
+import junit.framework.TestCase;
+
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Unit test for {@code AbstractIterator}.
+ *
+ * @author Kevin Bourrillion
+ */
+@SuppressWarnings("serial") // No serialization is used in this test
+// TODO(cpovirk): why is this slow (>1m/test) under GWT when fully optimized?
+public class AbstractIteratorTest extends TestCase
+{
+
+    public void testDefaultBehaviorOfNextAndHasNext()
+    {
+
+        // This sample AbstractIterator returns 0 on the first call, 1 on the
+        // second, then signals that it's reached the end of the data
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            private int rep;
+
+            @Override
+            public Integer computeNext()
+            {
+                switch (rep++)
+                {
+                    case 0:
+                        return 0;
+                    case 1:
+                        return 1;
+                    case 2:
+                        return endOfData();
+                    default:
+                        fail("Should not have been invoked again");
+                        return null;
+                }
+            }
+        };
+
+        assertTrue(iter.hasNext());
+        assertEquals(0, (int) iter.next());
+
+        // verify idempotence of hasNext()
+        assertTrue(iter.hasNext());
+        assertTrue(iter.hasNext());
+        assertTrue(iter.hasNext());
+        assertEquals(1, (int) iter.next());
+
+        assertFalse(iter.hasNext());
+
+        // Make sure computeNext() doesn't get invoked again
+        assertFalse(iter.hasNext());
+
+        try
+        {
+            iter.next();
+            fail("no exception thrown");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testDefaultBehaviorOfPeek()
+    {
+    /*
+     * This sample AbstractIterator returns 0 on the first call, 1 on the
+     * second, then signals that it's reached the end of the data
+     */
+        AbstractIterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            private int rep;
+
+            @Override
+            public Integer computeNext()
+            {
+                switch (rep++)
+                {
+                    case 0:
+                        return 0;
+                    case 1:
+                        return 1;
+                    case 2:
+                        return endOfData();
+                    default:
+                        fail("Should not have been invoked again");
+                        return null;
+                }
+            }
+        };
+
+        assertEquals(0, (int) iter.peek());
+        assertEquals(0, (int) iter.peek());
+        assertTrue(iter.hasNext());
+        assertEquals(0, (int) iter.peek());
+        assertEquals(0, (int) iter.next());
+
+        assertEquals(1, (int) iter.peek());
+        assertEquals(1, (int) iter.next());
+
+        try
+        {
+            iter.peek();
+            fail("peek() should throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.peek();
+            fail("peek() should continue to throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.next();
+            fail("next() should throw NoSuchElementException as usual");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            iter.peek();
+            fail("peek() should still throw NoSuchElementException after next()");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testFreesNextReference() throws InterruptedException
+    {
+        Iterator<Object> itr = new AbstractIterator<Object>()
+        {
+            @Override
+            public Object computeNext()
+            {
+                return new Object();
+            }
+        };
+        WeakReference<Object> ref = new WeakReference<Object>(itr.next());
+        while (ref.get() != null)
+        {
+            System.gc();
+            Thread.sleep(1);
+        }
+    }
+
+    public void testDefaultBehaviorOfPeekForEmptyIteration()
+    {
+
+        AbstractIterator<Integer> empty = new AbstractIterator<Integer>()
+        {
+            private boolean alreadyCalledEndOfData;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (alreadyCalledEndOfData)
+                {
+                    fail("Should not have been invoked again");
+                }
+                alreadyCalledEndOfData = true;
+                return endOfData();
+            }
+        };
+
+        try
+        {
+            empty.peek();
+            fail("peek() should throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+
+        try
+        {
+            empty.peek();
+            fail("peek() should continue to throw NoSuchElementException at end");
+        }
+        catch (NoSuchElementException expected)
+        {
+        }
+    }
+
+    public void testException()
+    {
+        final SomeUncheckedException exception = new SomeUncheckedException();
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            public Integer computeNext()
+            {
+                throw exception;
+            }
+        };
+
+        // It should pass through untouched
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (SomeUncheckedException e)
+        {
+            assertSame(exception, e);
+        }
+    }
+
+    public void testExceptionAfterEndOfData()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            public Integer computeNext()
+            {
+                endOfData();
+                throw new SomeUncheckedException();
+            }
+        };
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (SomeUncheckedException expected)
+        {
+        }
+    }
+
+    public void testCantRemove()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            boolean haveBeenCalled;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (haveBeenCalled)
+                {
+                    endOfData();
+                }
+                haveBeenCalled = true;
+                return 0;
+            }
+        };
+
+        assertEquals(0, (int) iter.next());
+
+        try
+        {
+            iter.remove();
+            fail("No exception thrown");
+        }
+        catch (UnsupportedOperationException expected)
+        {
+        }
+    }
+
+    public void testSneakyThrow() throws Exception
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            boolean haveBeenCalled;
+
+            @Override
+            public Integer computeNext()
+            {
+                if (haveBeenCalled)
+                {
+                    fail("Should not have been called again");
+                }
+                else
+                {
+                    haveBeenCalled = true;
+                    sneakyThrow(new SomeCheckedException());
+                }
+                return null; // never reached
+            }
+        };
+
+        // The first time, the sneakily-thrown exception comes out
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (Exception e)
+        {
+            if (!(e instanceof SomeCheckedException))
+            {
+                throw e;
+            }
+        }
+
+        // But the second time, AbstractIterator itself throws an ISE
+        try
+        {
+            iter.hasNext();
+            fail("No exception thrown");
+        }
+        catch (IllegalStateException expected)
+        {
+        }
+    }
+
+    public void testReentrantHasNext()
+    {
+        Iterator<Integer> iter = new AbstractIterator<Integer>()
+        {
+            @Override
+            protected Integer computeNext()
+            {
+                hasNext();
+                return null;
+            }
+        };
+        try
+        {
+            iter.hasNext();
+            fail();
+        }
+        catch (IllegalStateException expected)
+        {
+        }
+    }
+
+    /**
+     * Throws a undeclared checked exception.
+     */
+    private static void sneakyThrow(Throwable t)
+    {
+        class SneakyThrower<T extends Throwable>
+        {
+            @SuppressWarnings("unchecked")
+                // not really safe, but that's the point
+            void throwIt(Throwable t) throws T
+            {
+                throw (T) t;
+            }
+        }
+        new SneakyThrower<Error>().throwIt(t);
+    }
+
+    private static class SomeCheckedException extends Exception
+    {
+    }
+
+    private static class SomeUncheckedException extends RuntimeException
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java b/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
index 6a4bd2b..5f2de73 100644
--- a/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
+++ b/test/unit/org/apache/cassandra/utils/MergeIteratorComparisonTest.java
@@ -23,7 +23,7 @@ import java.util.*;
 
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java b/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
index b6d3d58..fe2cecf 100644
--- a/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
+++ b/test/unit/org/apache/cassandra/utils/MergeIteratorTest.java
@@ -21,7 +21,7 @@ package org.apache.cassandra.utils;
 import java.util.Arrays;
 import java.util.Iterator;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Ordering;
 import org.junit.Before;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/489a9e8f/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java b/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
index d2da07b..5924de0 100644
--- a/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
+++ b/test/unit/org/apache/cassandra/utils/MerkleTreeTest.java
@@ -21,7 +21,7 @@ package org.apache.cassandra.utils;
 import java.math.BigInteger;
 import java.util.*;
 
-import com.google.common.collect.AbstractIterator;
+import org.apache.cassandra.utils.AbstractIterator;
 
 import org.junit.Before;
 import org.junit.Test;


[3/3] cassandra git commit: Merge branch 'cassandra-3.0' into trunk

Posted by be...@apache.org.
Merge branch 'cassandra-3.0' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/05de664a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/05de664a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/05de664a

Branch: refs/heads/trunk
Commit: 05de664acd369d98154148dbf441accfa7f0552c
Parents: 288f2cf 489a9e8
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Sat Aug 8 12:31:04 2015 +0200
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Sat Aug 8 12:31:04 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cassandra/config/CFMetaData.java |   1 +
 .../apache/cassandra/cql3/UntypedResultSet.java |   2 +-
 .../org/apache/cassandra/db/LegacyLayout.java   |   2 +-
 .../apache/cassandra/db/RangeTombstoneList.java |   2 +-
 .../db/partitions/PartitionIterators.java       |   2 +-
 .../db/rows/AbstractUnfilteredRowIterator.java  |   2 +-
 .../cassandra/db/rows/BTreeBackedRow.java       |   2 +-
 .../LazilyInitializedUnfilteredRowIterator.java |   2 +-
 .../cassandra/hadoop/cql3/CqlRecordReader.java  |   2 +-
 .../cassandra/io/sstable/KeyIterator.java       |   2 +-
 .../io/sstable/SSTableIdentityIterator.java     |   2 +-
 .../io/sstable/SSTableSimpleIterator.java       |   2 +-
 .../io/sstable/format/big/BigTableScanner.java  |   2 +-
 .../apache/cassandra/service/StorageProxy.java  |   1 +
 .../service/pager/MultiPartitionPager.java      |   2 +-
 .../cassandra/thrift/ThriftResultsMerger.java   |   2 +-
 .../cassandra/utils/AbstractIterator.java       |  83 ++++
 .../org/apache/cassandra/utils/FBUtilities.java |   2 +-
 .../apache/cassandra/utils/IntervalTree.java    |   2 +-
 .../apache/cassandra/utils/MergeIterator.java   |   2 +-
 .../org/apache/cassandra/utils/MerkleTree.java  |   1 -
 .../cassandra/utils/AbstractIteratorTest.java   | 383 +++++++++++++++++++
 .../utils/MergeIteratorComparisonTest.java      |   2 +-
 .../cassandra/utils/MergeIteratorTest.java      |   2 +-
 .../apache/cassandra/utils/MerkleTreeTest.java  |   2 +-
 25 files changed, 488 insertions(+), 21 deletions(-)
----------------------------------------------------------------------