Commits

Rhys ! committed 2ac174a Draft

generating map (key, value) tuples at write instead of immediately (memory usage improvement)

  • Participants
  • Parent commits af16f88

Comments (0)

Files changed (3)

File src/org/bert_rpc/Encoder.java

 
     private <K, V> void writeMap(Map<K, V> map)
             throws IOException, EncodingException {
-        List<Tuple> pairs = new ArrayList<Tuple>(map.size());
-        for (Map.Entry<K, V> o : map.entrySet()) {
-            pairs.add(new Tuple(o.getKey(), o.getValue()));
-        }
-
-        this.writeComplexTuple(
-                new Tuple(Constants.$bert, Constants.$dict, pairs));
+        this.writeComplexTuple(new Tuple(Constants.$bert, Constants.$dict,
+                new TwoTupleMapTransformer<K, V>(map)));
     }
 
     public void encode(Date date) throws IOException {

File src/org/bert_rpc/TwoTupleMapIterator.java

+package org.bert_rpc;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Iterator that produces Tuple(key, value) pairs from a Map.Entry iterator.
+ *
+ * @param <K> The map key type.
+ * @param <V> The map value type.
+ */
+class TwoTupleMapIterator<K, V> implements Iterator<Tuple> {
+    private final Iterator<Map.Entry<K, V>> mapIterator;
+
+    public TwoTupleMapIterator(Iterator<Map.Entry<K, V>> mapIterator) {
+        this.mapIterator = mapIterator;
+    }
+
+    @Override
+    public boolean hasNext() {
+        return this.mapIterator.hasNext();
+    }
+
+    @Override
+    public Tuple next() {
+        if (this.hasNext()) {
+            Map.Entry nxt = this.mapIterator.next();
+            return new Tuple(nxt.getKey(), nxt.getValue());
+        } else {
+            throw new NoSuchElementException();
+        }
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+}

File src/org/bert_rpc/TwoTupleMapTransformer.java

+package org.bert_rpc;
+
+import java.util.AbstractList;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Collection that produces Tuple(key, value) pairs from a map. Only a list
+ * because that's what Encoder#encodeUnknownType checks for; calling get(int)
+ * will throw an UnsupportedOperationException.
+ *
+ * @param <K> The map key type.
+ * @param <V> The map value type.
+ */
+class TwoTupleMapTransformer<K, V> extends AbstractList<Tuple> {
+    private final Map<K, V> map;
+
+    public TwoTupleMapTransformer(Map<K, V> map) {
+        this.map = map;
+    }
+
+    @Override
+    public int size() {
+        return this.map.size();
+    }
+
+    @Override
+    public Iterator<Tuple> iterator() {
+        return new TwoTupleMapIterator<K, V>(this.map.entrySet().iterator());
+    }
+
+    @Override
+    public Tuple get(int index) {
+        throw new UnsupportedOperationException();
+    }
+}