瀏覽代碼

review (20)

Ranides Atterwim 11 年之前
父節點
當前提交
2818e40470

+ 66 - 217
assira/src/main/java/net/ranides/assira/collection/lookups/AVLTreeLookup.java

@@ -1,26 +1,12 @@
 /*
- * @author Paolo Boldi
- * @author Sebastiano Vigna
- * @author Ranides Atterwim <contact@ranides.net>
- *
- * 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.
+ *  @author Ranides Atterwim <ranides@gmail.com>
+ *  @copyright Ranides Atterwim
+ *  @license WTFPL
+ *  @url http://ranides.net/projects/assira
  */
-
 package net.ranides.assira.collection.lookups;
 
-import net.ranides.assira.collection.IntCollection;
 import net.ranides.assira.collection.iterators.AListIterator;
-import net.ranides.assira.collection.sets.ASortedSet;
 import java.util.Comparator;
 import java.util.ListIterator;
 import java.util.Map;
@@ -182,7 +168,7 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
     protected LookupEntry<K> findEntry(K key) {
         Entry<K> entry = tree;
         int cmp;
-        while (entry != null && (cmp = ValueUtils.cmp(acmp, key, entry.key)) != 0) {
+        while (entry != null && (cmp = compare(key, entry.key)) != 0) {
             entry = cmp < 0 ? entry.left() : entry.right();
         }
         return entry;
@@ -196,17 +182,41 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
      * given key, if it present; otherwise, it will be either the smallest
      * greater key or the greatest smaller key.
      */
-	// @todo (assira # 1) move to parent
-    protected Entry<K> locateKey(K key) {
+    protected Entry<K> locateEntry(K key) {
         Entry<K> entry = tree, last = tree;
         int cmp = 0;
-        while (entry != null && (cmp = ValueUtils.cmp(acmp, key, entry.key)) != 0) {
+        while (entry != null && (cmp = compare(key, entry.key)) != 0) {
             last = entry;
             entry = cmp < 0 ? entry.left() : entry.right();
         }
         return cmp == 0 ? entry : last;
     }
+	
+	@Override
+    protected LookupEntry<K> firstEntry() {
+        if (tree == null) {
+            throw new NoSuchElementException();
+        }
+        return firstEntry;
+    }
 
+    @Override
+    protected LookupEntry<K> lastEntry() {
+        if (tree == null) {
+            throw new NoSuchElementException();
+        }
+        return lastEntry;
+    }
+
+	@Override
+	protected ListIterator<LookupEntry<K>> entryIterator() {
+		return new EntryIterator();
+	}
+	
+	@Override
+	protected ListIterator<LookupEntry<K>> entryIterator(K begin) {
+		return new EntryIterator(begin);
+	}
 
     @Override
     public int put(K key, int value) {
@@ -219,7 +229,7 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             Entry<K> p = tree, q = null, y = tree, z = null, e = null, w;
             int cmp, i = 0;
             while (true) {
-                if ((cmp = ValueUtils.cmp(acmp, key, p.key)) == 0) {
+                if ((cmp = compare(key, p.key)) == 0) {
                     int oldValue = p.value;
                     p.value = value;
                     return oldValue;
@@ -416,7 +426,7 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
         boolean dir = false;
         K kkey = (K) key;
         while (true) {
-            if ((cmp = ValueUtils.cmp(acmp, kkey, p.key)) == 0) {
+            if ((cmp = compare(kkey, p.key)) == 0) {
                 break;
             } else if (dir = cmp > 0) {
                 q = p;
@@ -966,50 +976,9 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
         return count;
     }
 
-    @Override
-    protected LookupEntry<K> firstEntry() {
-        if (tree == null) {
-            throw new NoSuchElementException();
-        }
-        return firstEntry;
-    }
-
-    @Override
-    protected LookupEntry<K> lastEntry() {
-        if (tree == null) {
-            throw new NoSuchElementException();
-        }
-        return lastEntry;
-    }
-
-	@Override
-	protected ListIterator<LookupEntry<K>> fastEntryIterator() {
-		return new EntryIterator();
-	}
-	
-	@Override
-	protected ListIterator<LookupEntry<K>> fastEntryIterator(K begin) {
-		return new EntryIterator(begin);
-	}
-
 	@Override
-	protected boolean inside(K key) {
-		return true;
-	}
-
-    @Override
-    public SortedLookup<K> headMap(K to) {
-        return new Submap((null), true, to, false);
-    }
-
-    @Override
-    public SortedLookup<K> tailMap(K from) {
-        return new Submap(from, false, (null), true);
-    }
-
-    @Override
-    public SortedLookup<K> subMap(K from, K to) {
-        return new Submap(from, false, to, false);
+    protected SortedLookup<K> submap(K begin, boolean bottom, K end, boolean top) {
+        return new Submap(begin, bottom, end, top);
     }
 
     /**
@@ -1022,90 +991,21 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
      * {@link java.util.SortedMap#firstKey()} or
      * {@link java.util.Collection#size()} must be always computed on-the-fly.
      */
-    private final class Submap extends SortedLookup<K> implements java.io.Serializable {
+    private final class Submap extends ASubmap implements java.io.Serializable {
 
-        private static final long serialVersionUID = -7046029254386353129L;
-        /**
-         * The start of the submap range, unless {@link #bottom} is true.
-         */
-        K from;
-        /**
-         * The end of the submap range, unless {@link #top} is true.
-         */
-        K to;
-        /**
-         * If true, the submap range starts from -&infin;.
-         */
-        boolean bottom;
-        /**
-         * If true, the submap range goes to &infin;.
-         */
-        boolean top;
-        /**
-         * Cached set of entries.
-         */
-        @SuppressWarnings("hiding")
-        transient volatile ASortedSet<LookupEntry<K>> entries;
-        /**
-         * Cached set of keys.
-         */
-        @SuppressWarnings("hiding")
-        transient volatile ASortedSet<K> keys;
-        /**
-         * Cached collection of values.
-         */
-        @SuppressWarnings("hiding")
-        transient volatile IntCollection values;
+        private static final long serialVersionUID = 2L;
 
-        /**
-         * Creates a new submap with given key range.
-         *
-         * @param from the start of the submap range.
-         * @param bottom if true, the first parameter is ignored and the range
-         * starts from -&infin;.
-         * @param to the end of the submap range.
-         * @param top if true, the third parameter is ignored and the range goes
-         * to &infin;.
-         */
         public Submap(K from, boolean bottom, K to, boolean top) {
-            if (!bottom && !top && ValueUtils.cmp(acmp, from, to) > 0) {
-                throw new IllegalArgumentException("Start key (" + from + ") is larger than end key (" + to + ")");
-            }
-            this.from = from;
-            this.bottom = bottom;
-            this.to = to;
-            this.top = top;
-            this.defRetValue = AVLTreeLookup.this.defRetValue;
-        }
-
-        @Override
-        public void clear() {
-            final ListIterator<LookupEntry<K>> i = fastEntryIterator();
-            while (i.hasNext()) {
-                i.next();
-                i.remove();
-            }
+			super(from, bottom, to, top);
         }
-
-        /**
-         * Checks whether a key is in the submap range.
-         *
-         * @param k a key.
-         * @return true if is the key is in the submap range.
-         */
-		@Override
-        protected boolean inside(K k) {
-            return (bottom || ValueUtils.cmp(acmp, k, from) >= 0)
-                    && (top || ValueUtils.cmp(acmp, k, to) < 0);
-        }
-
+		
 		@Override
-		protected ListIterator<LookupEntry<K>> fastEntryIterator() {
+		protected ListIterator<LookupEntry<K>> entryIterator() {
 			return new SEntryIterator();
 		}
 		
 		@Override
-		protected ListIterator<LookupEntry<K>> fastEntryIterator(K begin) {
+		protected ListIterator<LookupEntry<K>> entryIterator(K begin) {
 			return new SEntryIterator(begin);
 		}
 		
@@ -1116,71 +1016,20 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
 			}
 			return AVLTreeLookup.this.findEntry(key);
 		}
-
-        @Override
-        public int put(K k, int v) {
-            modified = false;
-            if (!inside(k)) {
-                throw new IllegalArgumentException("Key (" + k + ") out of range [" + (bottom ? "-" : String.valueOf(from)) + ", " + (top ? "-" : String.valueOf(to)) + ")");
-            }
-			return super.put(k, v);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public int removeInt(Object k) {
-            modified = false;
-            if (!inside((K) k)) {
-                return this.defRetValue;
-            }
-            int oldValue = AVLTreeLookup.this.removeInt(k);
-            return modified ? oldValue : this.defRetValue;
-        }
 		
-        @Override
-        public int size() {
-            ListIterator<LookupEntry<K>> i = fastEntryIterator();
-            int n = 0;
-            while (i.hasNext()) {
-                n++;
-                i.next();
-            }
-            return n;
-        }
-
-        @Override
-        public SortedLookup<K> headMap(K to) {
-            if (top) {
-                return new Submap(from, bottom, to, false);
-            }
-            return ValueUtils.cmp(acmp, to, this.to) < 0 ? new Submap(from, bottom, to, false) : this;
-        }
-
-        @Override
-        public SortedLookup<K> tailMap(K from) {
-            if (bottom) {
-                return new Submap(from, false, to, top);
-            }
-            return ValueUtils.cmp(acmp, from, this.from) > 0 ? new Submap(from, false, to, top) : this;
-        }
-
-        @Override
-        public SortedLookup<K> subMap(K from, K to) {
-            if (top && bottom) {
-                return new Submap(from, false, to, false);
-            }
-            if (!top) {
-                to = ValueUtils.cmp(acmp, to, this.to) < 0 ? to : this.to;
-            }
-            if (!bottom) {
-                from = ValueUtils.cmp(acmp, from, this.from) > 0 ? from : this.from;
-            }
-            if (!top && !bottom && from == this.from && to == this.to) {
-                return this;
+		@Override
+        protected AVLTreeLookup.Entry<K> locateEntry(K key) {
+            if (!inside(key) ) {
+                return null;
             }
-            return new Submap(from, false, to, false);
+            return AVLTreeLookup.this.locateEntry(key);
         }
 
+		@Override
+		protected SortedLookup<K> submap(K from, boolean bottom, K to, boolean top) {
+			return new Submap(from, bottom, to, top);
+		}
+		
         @Override
         protected AVLTreeLookup.Entry<K> firstEntry() {
             if (tree == null) {
@@ -1191,14 +1040,14 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             if (bottom) {
                 e = firstEntry;
             } else {
-                e = locateKey(from);
+                e = locateEntry(from);
                 // If we find either the start or something greater we're OK.
-                if (ValueUtils.cmp(acmp, e.key, from) < 0) {
+                if (compare(e.key, from) < 0) {
                     e = e.next();
                 }
             }
             // Finally, if this subset doesn't go to infinity, we check that the resulting key isn't greater than the end.
-            if (e == null || !top && ValueUtils.cmp(acmp, e.key, to) >= 0) {
+            if (e == null || !top && compare(e.key, to) >= 0) {
                 return null;
             }
             return e;
@@ -1214,14 +1063,14 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             if (top) {
                 e = lastEntry;
             } else {
-                e = locateKey(to);
+                e = locateEntry(to);
                 // If we find something smaller than the end we're OK.
-                if (ValueUtils.cmp(acmp, e.key, to) >= 0) {
+                if (compare(e.key, to) >= 0) {
                     e = e.prev();
                 }
             }
             // Finally, if this subset doesn't go to -infinity, we check that the resulting key isn't smaller than the start.
-            if (e == null || !bottom && ValueUtils.cmp(acmp, e.key, from) < 0) {
+            if (e == null || !bottom && compare(e.key, from) < 0) {
                 return null;
             }
             return e;
@@ -1247,13 +1096,13 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             STreeIterator(K k) {
                 this();
                 if (next != null) {
-                    if (!bottom && ValueUtils.cmp(acmp, k, next.key) < 0) {
+                    if (!bottom && compare(k, next.key) < 0) {
                         prev = null;
-                    } else if (!top && ValueUtils.cmp(acmp, k, (prev = lastEntry()).key) >= 0) {
+                    } else if (!top && compare(k, (prev = lastEntry()).key) >= 0) {
                         next = null;
                     } else {
-                        next = locateKey(k);
-                        if (ValueUtils.cmp(acmp, next.key, k) <= 0) {
+                        next = locateEntry(k);
+                        if (compare(next.key, k) <= 0) {
                             prev = next;
                             next = next.next();
                         } else {
@@ -1266,7 +1115,7 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             @Override
             void updatePrevious() {
                 prev = prev.prev();
-                if (!bottom && prev != null && ValueUtils.cmp(acmp, prev.key, from) < 0) {
+                if (!bottom && prev != null && compare(prev.key, from) < 0) {
                     prev = null;
                 }
             }
@@ -1274,7 +1123,7 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
             @Override
             void updateNext() {
                 next = next.next();
-                if (!top && next != null && ValueUtils.cmp(acmp, next.key, to) >= 0) {
+                if (!top && next != null && compare(next.key, to) >= 0) {
                     next = null;
                 }
             }
@@ -1422,8 +1271,8 @@ public final class AVLTreeLookup<K> extends SortedLookup<K> implements java.io.S
         }
 
         TreeIterator(K k) {
-            if ((next = locateKey(k)) != null) {
-                if (ValueUtils.cmp(acmp, next.key, k) <= 0) {
+            if ((next = locateEntry(k)) != null) {
+                if (compare(next.key, k) <= 0) {
                     prev = next;
                     next = next.next();
                 } else {

+ 1 - 1
assira/src/main/java/net/ranides/assira/collection/lookups/Lookup.java

@@ -27,7 +27,7 @@ public abstract class Lookup<K> implements Map<K, Integer>, java.io.Serializable
     protected Lookup() {
         // do nothing
     }
-
+	
     @Override
     public boolean containsValue(Object value) {
         return containsValue(((Integer) value).intValue());

File diff suppressed because it is too large
+ 94 - 787
assira/src/main/java/net/ranides/assira/collection/lookups/RBTreeLookup.java


+ 279 - 93
assira/src/main/java/net/ranides/assira/collection/lookups/SortedLookup.java

@@ -15,6 +15,7 @@ import net.ranides.assira.collection.sets.ASortedSet;
 import net.ranides.assira.collection.IntCollection;
 import net.ranides.assira.collection.iterators.IntIterator;
 import net.ranides.assira.collection.iterators.IntListIterator;
+import net.ranides.assira.generic.ValueUtils;
 
 /**
  * An abstract class for sorted maps with primitive int values.
@@ -23,8 +24,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 
     private static final long serialVersionUID = 2L;
 	
-	// @todo (assira # 1) acmp
-    protected Comparator<? super K> acmp;
+    private final Comparator<? super K> acmp;
 	
 	/**
      * The value of this variable remembers, after a
@@ -34,53 +34,51 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
      */
     protected transient boolean modified;
 
-    protected SortedLookup() {
-        // do nothing
+    protected SortedLookup(Comparator<? super K> comparator) {
+        this.acmp = comparator;
     }
 	
-	protected SortedLookup(Comparator<? super K> comparator) {
-		this.acmp = comparator;
-	}
+	protected abstract LookupEntry<K> findEntry(K key);
 	
-	@Override
-    public final Integer put(K key, Integer value) {
-        int oldValue = put(key, value.intValue());
-        return modified ? null : oldValue;
-    }
+	protected abstract LookupEntry<K> locateEntry(K key);
 	
-	@Override
-    public final Integer remove(Object key) {
-        int oldValue = removeInt(key);
-        return modified ? oldValue : null;
+	protected abstract LookupEntry<K> firstEntry();
+	
+	protected abstract LookupEntry<K> lastEntry();
+	
+	protected abstract ListIterator<LookupEntry<K>> entryIterator();
+	
+	protected abstract ListIterator<LookupEntry<K>> entryIterator(K begin);
+	
+	protected abstract SortedLookup<K> submap(K begin, boolean bottom, K end, boolean top);
+	
+	protected final int compare(K key1, K key2) {
+        return ValueUtils.cmp(acmp, key1, key2);
     }
-
-	@Override
-    public final boolean containsValue(int value) {
-        ValueIterator iterator = new ValueIterator(fastEntryIterator());
-        int max = size();
-        while (max-- != 0) {
-            if (iterator.nextInt() == value) {
-                return true;
-            }
-        }
-        return false;
+    
+    protected final K lower(K key1, K key2) {
+        return ValueUtils.lower(acmp, key1, key2);
     }
-
-    @Override
-    public final ASortedSet<K> keySet() {
-        return new KeySet();
+    
+    protected final K higher(K key1, K key2) {
+        return ValueUtils.higher(acmp, key1, key2);
     }
-
-    /**
-     * Returns a type-specific sorted collection.
-     * @return a type-specific collection view of the values contained in this map
+	
+	/**
+     * Returns the comparator associated with this sorted set, or null if it
+     * uses its keys' natural ordering.
+     *
+     * <P>Note that this specification strengthens the one given in
+     * {@link SortedMap#comparator()}.
+     *
+     * @see SortedMap#comparator()
      */
     @Override
-    public final IntCollection values() {
-        return new ValuesCollection();
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
+    public final Comparator<? super K> comparator() {
+		return acmp;
+	}
+	
+	@SuppressWarnings({"unchecked", "rawtypes"})
     @Override
     public final ASortedSet<Entry<K, Integer>> entrySet() {
         return (ASortedSet)fastEntrySet();
@@ -100,19 +98,20 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 		return new EntrySet();
 	} 
 	
-	// @todo (assira # 1) move to parent
-	protected abstract ListIterator<LookupEntry<K>> fastEntryIterator();
-	
-	protected abstract ListIterator<LookupEntry<K>> fastEntryIterator(K begin);
+	@Override
+    public final ASortedSet<K> keySet() {
+        return new KeySet();
+    }
 
-	protected abstract boolean inside(K key);
-	
-	protected abstract LookupEntry<K> findEntry(K key);
-	
-	protected abstract LookupEntry<K> firstEntry();
+    /**
+     * Returns a type-specific sorted collection.
+     * @return a type-specific collection view of the values contained in this map
+     */
+    @Override
+    public final IntCollection values() {
+        return new ValuesCollection();
+    }
 	
-	protected abstract LookupEntry<K> lastEntry();
-
 	@Override
 	public final K firstKey() {
 		return firstEntry().getKey();
@@ -123,43 +122,27 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 		return lastEntry().getKey();
 	}
 	
-	@SuppressWarnings("unchecked")
-    @Override
-    public final boolean containsKey(Object k) {
-        return findEntry( (K)k) != null;
+	@Override
+    public final boolean containsValue(int value) {
+        ValueIterator iterator = new ValueIterator(SortedLookup.this.entryIterator());
+        int max = size();
+        while (max-- != 0) {
+            if (iterator.nextInt() == value) {
+                return true;
+            }
+        }
+        return false;
     }
+
+    
 	
 	@SuppressWarnings("unchecked")
     @Override
-    public final int getInt(Object k) {
-        LookupEntry<K> e = findEntry((K) k);
-        return e == null ? defRetValue : e.getIntValue();
-    }
-	
-	
-    @SuppressWarnings("unchecked")
-    @Override
-    public final Integer get(Object ok) {
-        LookupEntry<K> e = findEntry((K) ok);
-        return e == null ? (null) : e.getValue();
+    public final boolean containsKey(Object k) {
+        return findEntry( (K)k) != null;
     }
-
 	
-    /**
-     * Returns the comparator associated with this sorted set, or null if it
-     * uses its keys' natural ordering.
-     *
-     * <P>Note that this specification strengthens the one given in
-     * {@link SortedMap#comparator()}.
-     *
-     * @see SortedMap#comparator()
-     */
-    @Override
-    public final Comparator<? super K> comparator() {
-		return acmp;
-	}
-
-    /**
+	/**
      * Returns a view of the portion of this sorted map whose keys range from
      * <code>fromKey</code>, inclusive, to
      * <code>toKey</code>, exclusive.
@@ -170,7 +153,9 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
      * @see SortedMap#subMap(Object,Object)
      */
     @Override
-    public abstract SortedLookup<K> subMap(K begin, K end);
+    public SortedLookup<K> subMap(K begin, K end) {
+		return submap(begin, false, end, false);
+	}
 
     /**
      * Returns a view of the portion of this sorted map whose keys are strictly
@@ -182,7 +167,9 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
      * @see SortedMap#headMap(Object)
      */
     @Override
-    public abstract SortedLookup<K> headMap(K end);
+    public SortedLookup<K> headMap(K end) {
+		return submap(null, true, end, false);
+	}
 
     /**
      * Returns a view of the portion of this sorted map whose keys are greater
@@ -195,8 +182,44 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
      * @see SortedMap#tailMap(Object)
      */
     @Override
-    public abstract SortedLookup<K> tailMap(K begin);
+    public SortedLookup<K> tailMap(K begin) {
+		return submap(begin, false, null, true);
+	}
+	
+	@SuppressWarnings("unchecked")
+    @Override
+    public final int getInt(Object k) {
+        LookupEntry<K> e = findEntry((K) k);
+        return e == null ? defRetValue : e.getIntValue();
+    }
+	
+    @SuppressWarnings("unchecked")
+    @Override
+    public final Integer get(Object ok) {
+        LookupEntry<K> e = findEntry((K) ok);
+        return e == null ? (null) : e.getValue();
+    }
+	
+	
+	@Override
+    public final Integer put(K key, Integer value) {
+        int oldValue = put(key, value.intValue());
+        return modified ? null : oldValue;
+    }
+	
+	@Override
+    public final Integer remove(Object key) {
+        int oldValue = removeInt(key);
+        return modified ? oldValue : null;
+    }
 
+	
+	
+	
+
+    
+	
+    
 
     /**
      * A wrapper exhibiting the keys of a map.
@@ -251,12 +274,12 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 
         @Override
         public Iterator<K> iterator(K from) {
-            return new KeySetIterator<>(fastEntryIterator(from));
+            return new KeySetIterator<>(entryIterator(from));
         }
 
         @Override
         public Iterator<K> iterator() {
-            return new KeySetIterator<>(fastEntryIterator());
+            return new KeySetIterator<>(SortedLookup.this.entryIterator());
         }
     }
 
@@ -297,7 +320,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 
         @Override
         public IntIterator iterator() {
-            return new ValueIterator<>(fastEntryIterator());
+            return new ValueIterator<>(entryIterator());
         }
 
         @Override
@@ -366,12 +389,12 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 		
 		@Override
 		public Iterator<LookupEntry<K>> iterator() {
-			return fastEntryIterator();
+			return entryIterator();
 		}
 
 		@Override
 		public Iterator<LookupEntry<K>> iterator(LookupEntry<K> from) {
-			return fastEntryIterator(from.getKey());
+			return entryIterator(from.getKey());
 		}
 
 		@Override
@@ -387,7 +410,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 			}
 			Map.Entry<K, Integer> entry = (Map.Entry<K, Integer>) object;
 			LookupEntry<K> found = findEntry(entry.getKey());
-			return found != null && inside(entry.getKey()) && entry.equals(found);
+			return found != null && entry.equals(found);
 		}
 
 		@SuppressWarnings("unchecked")
@@ -398,7 +421,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 			}
 			Map.Entry<K, Integer> entry = (Map.Entry<K, Integer>) o;
 			LookupEntry<K> found = findEntry((entry.getKey()));
-			if (found != null && inside(found.getKey())) {
+			if (found != null) {
 				SortedLookup.this.removeInt(found.getIntValue());
 			}
 			return found != null;
@@ -415,7 +438,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 
 		@Override
 		public boolean isEmpty() {
-			return !fastEntryIterator().hasNext();
+			return !entryIterator().hasNext();
 		}
 
 		@Override
@@ -448,5 +471,168 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 			return tailMap(from.getKey()).fastEntrySet();
 		}
 	}
+	
+	/**
+     * A submap with given range.
+     *
+     * <P>This class represents a submap. One has to specify the left/right
+     * limits (which can be set to -&infin; or &infin;). Since the submap is a
+     * view on the map, at a given moment it could happen that the limits of the
+     * range are not any longer in the main map. Thus, things such as
+     * {@link java.util.SortedMap#firstKey()} or
+     * {@link java.util.Collection#size()} must be always computed on-the-fly.
+     */
+    protected abstract class ASubmap extends SortedLookup<K> implements java.io.Serializable {
+
+        private static final long serialVersionUID = 2L;
+        /**
+         * The start of the submap range, unless {@link #bottom} is true.
+         */
+        K from;
+        /**
+         * The end of the submap range, unless {@link #top} is true.
+         */
+        K to;
+        /**
+         * If true, the submap range starts from -&infin;.
+         */
+        boolean bottom;
+        /**
+         * If true, the submap range goes to &infin;.
+         */
+        boolean top;
+        
+        /**
+         * Creates a new submap with given key range.
+         *
+         * @param from the start of the submap range.
+         * @param bottom if true, the first parameter is ignored and the range
+         * starts from -&infin;.
+         * @param to the end of the submap range.
+         * @param top if true, the third parameter is ignored and the range goes
+         * to &infin;.
+         */
+        public ASubmap(K from, boolean bottom, K to, boolean top) {
+			super(SortedLookup.this.acmp);
+            if (!bottom && !top && ValueUtils.cmp(acmp, from, to) > 0) {
+                throw new IllegalArgumentException("Start key (" + from + ") is larger than end key (" + to + ")");
+            }
+            this.from = from;
+            this.bottom = bottom;
+            this.to = to;
+            this.top = top;
+            this.defRetValue = SortedLookup.this.defRetValue;
+        }
+
+        @Override
+        public final void clear() {
+            ListIterator<LookupEntry<K>> i = entryIterator();
+            while (i.hasNext()) {
+                i.next();
+                i.remove();
+            }
+        }
+
+        /**
+         * Checks whether a key is in the submap range.
+         *
+         * @param k a key.
+         * @return true if is the key is in the submap range.
+         */
+        protected final boolean inside(K k) {
+            return (bottom || ValueUtils.cmp(acmp, k, from) >= 0)
+                    && (top || ValueUtils.cmp(acmp, k, to) < 0);
+        }
+
+		@Override
+		protected abstract ListIterator<LookupEntry<K>> entryIterator();
+		
+		@Override
+		protected abstract ListIterator<LookupEntry<K>> entryIterator(K begin);
+		
+		@Override
+        protected abstract LookupEntry<K> findEntry(K key);
+
+        @Override
+        protected abstract LookupEntry<K> locateEntry(K key);
+        
+        @Override
+        protected abstract LookupEntry<K> firstEntry();
+
+        @Override
+        protected abstract LookupEntry<K> lastEntry();
+
+        @Override
+        public final int put(K k, int v) {
+            if (!inside(k)) {
+				SortedLookup.this.modified = false;
+                throw new IllegalArgumentException("Key (" + k + ") out of range [" + (bottom ? "-" : String.valueOf(from)) + ", " + (top ? "-" : String.valueOf(to)) + ")");
+            }
+			return super.put(k, v);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public final int removeInt(Object k) {
+            if (!inside((K) k)) {
+				SortedLookup.this.modified = false;
+                return this.defRetValue;
+            }
+            return SortedLookup.this.removeInt(k);
+        }
+		
+        @Override
+        public final int size() {
+            ListIterator<LookupEntry<K>> i = entryIterator();
+            int n = 0;
+            while (i.hasNext()) {
+                n++;
+                i.next();
+            }
+            return n;
+        }
+		
+		@Override
+        public final boolean isEmpty() {
+            return !entryIterator().hasNext();
+        }
+
+        @Override
+        public final SortedLookup<K> headMap(K to) {
+            if (top) {
+                return submap(from, bottom, to, false);
+            }
+            return ValueUtils.cmp(acmp, to, this.to) < 0 ? submap(from, bottom, to, false) : this;
+        }
+
+        @Override
+        public final SortedLookup<K> tailMap(K from) {
+            if (bottom) {
+                return submap(from, false, to, top);
+            }
+            return ValueUtils.cmp(acmp, from, this.from) > 0 ? submap(from, false, to, top) : this;
+        }
+
+        @Override
+        public final SortedLookup<K> subMap(K from, K to) {
+            if (top && bottom) {
+                return submap(from, false, to, false);
+            }
+            if (!top) {
+                to = ValueUtils.cmp(acmp, to, this.to) < 0 ? to : this.to;
+            }
+            if (!bottom) {
+                from = ValueUtils.cmp(acmp, from, this.from) > 0 ? from : this.from;
+            }
+            if (!top && !bottom && from == this.from && to == this.to) {
+                return this;
+            }
+            return submap(from, false, to, false);
+        }
+		
+		protected abstract SortedLookup<K> submap(K from, boolean bottom, K to, boolean top);
+
+    }
+	
 
 }

+ 1 - 3
assira/src/main/java/net/ranides/assira/collection/maps/ASortedMap.java

@@ -297,8 +297,6 @@ public abstract class ASortedMap<K, V> extends AMap<K, V> implements SortedMap<K
     
     protected class EntrySet extends ASortedSet<Entry<K, V>> {
 
-        // @todo (assira # 2) cmp / move end parent
-        
         final Comparator<? super Entry<K, V>> ecmp = new Comparator<Entry<K, V>>() {
             @Override
             public int compare(Entry<K, V> x, Entry<K, V> y) {
@@ -386,7 +384,7 @@ public abstract class ASortedMap<K, V> extends AMap<K, V> implements SortedMap<K
      * A submap with given range.
      *
      * <P>This class represents a submap. One has end specify the left/right
- limits (which can be set end -&infin; or &infin;). Since the submap is a
+     * limits (which can be set end -&infin; or &infin;). Since the submap is a
      * view on the map, at a given moment it could happen that the limits of the
      * range are not any longer in the main map. Thus, things such as
      * {@link java.util.SortedMap#firstKey()} or