Stop abusing Map.Entry and declare our own Row type

Implementing Map.Entry<byte[], byte[]> is painful, and its just not a
good interface given that it has a setValue method.  Replace usages
of it in the NoSQL code with our own Row type that has a similar
API for the getters.

Change-Id: I9144d615e1fa9b5d0df9727c3d39b75db06f024a
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gwtorm/nosql/generic/GenericAccess.java b/src/main/java/com/google/gwtorm/nosql/generic/GenericAccess.java
index f82c76e..a17727b 100644
--- a/src/main/java/com/google/gwtorm/nosql/generic/GenericAccess.java
+++ b/src/main/java/com/google/gwtorm/nosql/generic/GenericAccess.java
@@ -32,7 +32,6 @@
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.Map;
 import java.util.Map.Entry;
 
 /** Base implementation for {@link Access} in a {@link GenericDatabase}. */
@@ -111,10 +110,8 @@
     b.addRaw(toKey);
     toKey = b.toByteArray();
 
-    final ResultSet<Map.Entry<byte[], byte[]>> rs =
-        db.scan(fromKey, toKey, limit, order);
-
-    final Iterator<Map.Entry<byte[], byte[]>> i = rs.iterator();
+    final ResultSet<Row> rs = db.scan(fromKey, toKey, limit, order);
+    final Iterator<Row> i = rs.iterator();
 
     return new AbstractResultSet<T>() {
       @Override
@@ -177,9 +174,8 @@
 
     SCAN: for (;;) {
       int scanned = 0;
-      ResultSet<Entry<byte[], byte[]>> rs =
-          db.scan(lastKey, toKey, limit, order);
-      for (Map.Entry<byte[], byte[]> ent : rs) {
+      ResultSet<Row> rs = db.scan(lastKey, toKey, limit, order);
+      for (Row ent : rs) {
         final byte[] idxkey = ent.getKey();
         lastKey = idxkey;
         scanned++;
diff --git a/src/main/java/com/google/gwtorm/nosql/generic/GenericSchema.java b/src/main/java/com/google/gwtorm/nosql/generic/GenericSchema.java
index e6268a7..cfbda78 100644
--- a/src/main/java/com/google/gwtorm/nosql/generic/GenericSchema.java
+++ b/src/main/java/com/google/gwtorm/nosql/generic/GenericSchema.java
@@ -26,8 +26,6 @@
 import com.google.gwtorm.schema.SequenceModel;
 
 import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Base implementation for {@link Schema} in a {@link GenericDatabase}.
@@ -130,9 +128,9 @@
     final byte[] toKey = new byte[key.length + 1];
     System.arraycopy(key, 0, toKey, 0, key.length);
 
-    ResultSet<Entry<byte[], byte[]>> r = scan(fromKey, toKey, 2, false);
+    ResultSet<Row> r = scan(fromKey, toKey, 2, false);
     try {
-      Iterator<Entry<byte[], byte[]>> i = r.iterator();
+      Iterator<Row> i = r.iterator();
       if (!i.hasNext()) {
         return null;
       }
@@ -168,8 +166,8 @@
    *         lazily filled, or filled completely.
    * @throws OrmException an error occurred preventing the scan from completing.
    */
-  public abstract ResultSet<Map.Entry<byte[], byte[]>> scan(byte[] fromKey,
-      byte[] toKey, int limit, boolean order) throws OrmException;
+  public abstract ResultSet<Row> scan(byte[] fromKey, byte[] toKey, int limit,
+      boolean order) throws OrmException;
 
   /**
    * Atomically insert one row, failing if the row already exists.
diff --git a/src/main/java/com/google/gwtorm/nosql/generic/Row.java b/src/main/java/com/google/gwtorm/nosql/generic/Row.java
new file mode 100644
index 0000000..cdeacbd
--- /dev/null
+++ b/src/main/java/com/google/gwtorm/nosql/generic/Row.java
@@ -0,0 +1,34 @@
+// Copyright 2010 Google Inc.
+//
+// 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 com.google.gwtorm.nosql.generic;
+
+/** A pairing of a row key and its value. */
+public class Row {
+  private final byte[] key;
+  private final byte[] val;
+
+  public Row(byte[] key, byte[] val) {
+    this.key = key;
+    this.val = val;
+  }
+
+  public byte[] getKey() {
+    return key;
+  }
+
+  public byte[] getValue() {
+    return val;
+  }
+}
diff --git a/src/main/java/com/google/gwtorm/nosql/heap/TreeMapSchema.java b/src/main/java/com/google/gwtorm/nosql/heap/TreeMapSchema.java
index 9b75422..239003f 100644
--- a/src/main/java/com/google/gwtorm/nosql/heap/TreeMapSchema.java
+++ b/src/main/java/com/google/gwtorm/nosql/heap/TreeMapSchema.java
@@ -20,6 +20,7 @@
 import com.google.gwtorm.client.Schema;
 import com.google.gwtorm.client.impl.ListResultSet;
 import com.google.gwtorm.nosql.generic.GenericSchema;
+import com.google.gwtorm.nosql.generic.Row;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -47,39 +48,19 @@
   }
 
   @Override
-  public ResultSet<Map.Entry<byte[], byte[]>> scan(byte[] fromKey,
-      byte[] toKey, int limit, boolean order) {
+  public ResultSet<Row> scan(byte[] fromKey, byte[] toKey, int limit,
+      boolean order) {
     db.lock.lock();
     try {
-      final List<Map.Entry<byte[], byte[]>> res =
-          new ArrayList<Map.Entry<byte[], byte[]>>();
-
+      final List<Row> res = new ArrayList<Row>();
       for (Map.Entry<byte[], byte[]> ent : entries(fromKey, toKey)) {
-        final byte[] key = ent.getKey();
-        final byte[] val = ent.getValue();
-
-        res.add(new Map.Entry<byte[], byte[]>() {
-          @Override
-          public byte[] getKey() {
-            return key;
-          }
-
-          @Override
-          public byte[] getValue() {
-            return val;
-          }
-
-          @Override
-          public byte[] setValue(byte[] value) {
-            throw new UnsupportedOperationException();
-          }
-        });
+        res.add(new Row(ent.getKey(), ent.getValue()));
 
         if (limit > 0 && res.size() == limit) {
           break;
         }
       }
-      return new ListResultSet<Entry<byte[],byte[]>>(res);
+      return new ListResultSet<Row>(res);
     } finally {
       db.lock.unlock();
     }