Ranides Atterwim 11 лет назад
Родитель
Сommit
3151c54a21

+ 3 - 1
.gitignore

@@ -1,4 +1,6 @@
 /assira/target/
 /assira.asm/target/
 /assira.rules/target/
-/assira.rules.test/target/
+/assira.rules.test/target/
+/assira/nbproject/
+/assira.junit/target/

+ 30 - 0
assira.junit/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>net.ranides</groupId>
+        <artifactId>assira.common</artifactId>
+        <version>2.0.0</version>
+    </parent>
+    <name>assira.junit</name>
+    <groupId>net.ranides</groupId>
+    <artifactId>assira.junit</artifactId>
+    <version>2.0.0</version>
+    <packaging>jar</packaging>
+
+    <repositories>
+        <repository>
+            <id>ranides.net</id>
+            <name>ranides.net</name>
+            <url>http://maven.ranides.net</url>
+        </repository>
+    </repositories>
+    
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.10</version>
+        </dependency>
+    </dependencies>
+</project>

+ 34 - 0
assira.junit/src/main/java/net/ranides/assira/junit/QAssert.java

@@ -0,0 +1,34 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class QAssert {
+    
+    private QAssert() { }
+    
+    public static void assertThrows(Class<? extends Throwable> error, Action action) {
+        try {
+            action.run();
+            fail(error + " expected");
+        } catch(Throwable cause) {
+            assertEquals(error, cause.getClass());
+        }
+    }
+    
+    public interface Action {
+        
+        Object run() throws Exception;
+        
+    }
+}

+ 10 - 4
assira/pom.xml

@@ -26,6 +26,12 @@
             <groupId>net.ranides</groupId>
             <version>5.0.4</version>
         </dependency>
+        <dependency>
+            <groupId>eu.vitaliy</groupId>
+            <artifactId>mazovia-charset</artifactId>
+            <version>1.0</version>
+            <optional>true</optional>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -33,10 +39,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>eu.vitaliy</groupId>
-            <artifactId>mazovia-charset</artifactId>
-            <version>1.0</version>
-            <optional>true</optional>
+            <groupId>net.ranides</groupId>
+            <artifactId>assira.junit</artifactId>
+            <version>2.0.0</version>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 </project>

+ 31 - 22
assira/src/main/java/net/ranides/assira/collection/lookups/AHashLookup.java

@@ -29,48 +29,48 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
     /**
      * The array of mkeys.
      */
-    protected transient K[] keys;
+    private transient K[] keys;
     /**
      * The array of mvalues.
      */
-    protected transient int[] values;
+    private transient int[] values;
     /**
      * The array telling whether a position is used.
      */
-    protected transient boolean used[];
+    private transient boolean used[];
     /**
      * The acceptable load factor.
      */
-    protected float factor;
+    private final float factor;
     /**
      * The current table size.
      */
-    protected transient int n;
+    private transient int n;
     /**
      * Threshold after which we rehash. It must be the table size times
      * {@link #factor}.
      */
-    protected transient int capacity;
+    private transient int capacity;
     /**
      * The mask for wrapping a position counter.
      */
-    protected transient int mask;
+    private transient int mask;
     /**
      * Number of mentries in the set.
      */
-    protected int size;
+    private int size;
     /**
      * Cached set of mentries.
      */
-    protected transient volatile Set<LookupEntry<K>> mentries;
+    private transient volatile Set<LookupEntry<K>> mentries;
     /**
      * Cached set of mkeys.
      */
-    protected transient volatile Set<K> mkeys;
+    private transient volatile Set<K> mkeys;
     /**
      * Cached collection of mvalues.
      */
-    protected transient volatile IntCollection mvalues;
+    private transient volatile IntCollection mvalues;
 
     /**
      * Creates a new hash map.
@@ -126,7 +126,7 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
     @Override
     public final Integer remove(Object key) {
         int pos = ifind((K)key);
-        return used[pos] ? ishift(pos) : defRetValue;
+        return used[pos] ? ishift(pos) : null;
     }
 
     @SuppressWarnings("unchecked")
@@ -136,6 +136,15 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
         return used[pos] ? values[pos] : defRetValue; 
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public Integer get(Object key) {
+        int pos = ifind((K)key);
+        return used[pos] ? values[pos] : null; 
+    }
+    
+    
+
     @SuppressWarnings("unchecked")
     @Override
     public boolean containsKey(Object key) {
@@ -566,9 +575,9 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
             // We are just enumerating elements from the wrapped list.
             if (pos < 0) {
                 K ckey = wrapped.get(-(last = --pos) - 2);
-				int pos = ifind(ckey);
-                if(used[pos]) {
-                    return pos;
+				int ipos = ifind(ckey);
+                if(used[ipos]) {
+                    return ipos;
                 }
             }
             last = pos;
@@ -582,23 +591,23 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
         }
 
         protected final int ishift(int pos) {
-            int last;
+            int ilast;
             for (;;) {
-                last = pos;
-                pos = inext(last);
+                ilast = pos;
+                pos = inext(ilast);
                 if (!used[ pos]) {
                     break;
                 }
-                if (pos < last) {
+                if (pos < ilast) {
                     if (wrapped == null) {
                         wrapped = new ArrayList<>();
                     }
                     wrapped.add(keys[pos]);
                 }
-                imove(last, pos);
+                imove(ilast, pos);
             }
-            iclear(last);
-            return last;
+            iclear(ilast);
+            return ilast;
         }
 
         @SuppressWarnings("unchecked")

+ 0 - 5
assira/src/main/java/net/ranides/assira/collection/lookups/CustomLookup.java

@@ -15,11 +15,6 @@ import net.ranides.assira.collection.utils.HashCollection;
  * A type-specific hash map with primitive int values, whose
  * {@linkplain HashComparator hashing strategy} is specified at creation time.
  */
-@SuppressWarnings({
-    "PMD.AvoidReassigningParameters",
-    "PMD.OverrideBothEqualsAndHashcode",
-    "EqualsAndHashcode"
-})
 public final class CustomLookup<K> extends AHashLookup<K> {
 
     private static final long serialVersionUID = 2L;

+ 0 - 24
assira/src/test/java/net/ranides/assira/collection/DummyTest.java

@@ -1,24 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection;
-
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- * @todo (assira # 9) test
- */
-public class DummyTest {
- 
-    @Test
-    public void testDummy() {
-        assertTrue(true);
-    }
-    
-}

+ 109 - 0
assira/src/test/java/net/ranides/assira/collection/lookups/CustomLookupTest.java

@@ -0,0 +1,109 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.lookups;
+
+import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.ALookupTester;
+import java.util.Map;
+import net.ranides.assira.collection.mockup.TPoint;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static net.ranides.assira.junit.QAssert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class CustomLookupTest {
+    
+    private final ALookupTester tester = new ALookupTester(new TPointGenerator());
+
+    @Test
+    public void testConstruct() {
+        assertNotNull( new CustomLookup<>(32, 0.75f, TPoint.SUM) );
+        assertNotNull( new CustomLookup<>(32, TPoint.SUM) );
+        assertNotNull( new CustomLookup<>(TPoint.SUM) );
+
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(32, 0.0f, TPoint.SUM)
+        );
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(32, -1.0f, TPoint.SUM)
+        );
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(32, 1.1f, TPoint.SUM)
+        );
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(32, 2.0f, TPoint.SUM)
+        );
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(-1, 0.5f, TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testConstructCopy() {
+        TPointGenerator generator = new TPointGenerator();
+        Map<TPoint, Integer> imap = generator.map(generator.ukeys(60));
+        
+        assertEquals(120, new CustomLookup<>(imap, TPoint.SUM).size());
+        
+        assertEquals(120, new CustomLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.SUM).size());
+        assertEquals(120, new CustomLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.STD).size());
+        assertEquals(120, new CustomLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.SUM).size());
+        assertEquals(180, new CustomLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.STD).size());
+        
+        assertEquals(120, new CustomLookup<>(generator.ukeys(60), generator.values(180), TPoint.SUM).size());
+        
+        assertThrows(IllegalArgumentException.class, () -> 
+            new CustomLookup<>(generator.ukeys(60), generator.values(10), TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testPut() {
+        tester.basicPutInt(new CustomLookup<>(TPoint.SUM));
+        tester.basicPutInt(new CustomLookup<>(TPoint.SUM), 128);
+        tester.basicReplaceInt(new CustomLookup<>(TPoint.SUM), 40);
+        
+        tester.basicPutInteger(new CustomLookup<>(TPoint.SUM));
+        tester.basicPutInteger(new CustomLookup<>(TPoint.SUM), 128);
+        tester.basicReplaceInteger(new CustomLookup<>(TPoint.SUM), 40);
+        
+        assertTrue(true);
+    }
+
+    @Test
+    public void testRemove() {
+        tester.basicRemoveInt(new CustomLookup<>(TPoint.SUM));
+        tester.basicRemoveInt(new CustomLookup<>(TPoint.SUM), 97);
+        tester.logicRemoveInt(new CustomLookup<>(TPoint.SUM));
+        
+        tester.basicRemoveInteger(new CustomLookup<>(TPoint.SUM));
+        tester.basicRemoveInteger(new CustomLookup<>(TPoint.SUM), 97);
+        tester.logicRemoveInteger(new CustomLookup<>(TPoint.SUM));
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testGet() {
+        tester.basicGetInt( new CustomLookup<>(TPoint.SUM) );
+        tester.basicGetInteger( new CustomLookup<>(TPoint.SUM) );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testContainsValue() {
+        tester.basicContainsInt( new CustomLookup<>(TPoint.SUM) );
+        tester.basicContainsInteger( new CustomLookup<>(TPoint.SUM) );
+        
+        assertTrue(true);
+    }
+    
+}

+ 293 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/ALookupTester.java

@@ -0,0 +1,293 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.mockup;
+
+import java.util.Map;
+import net.ranides.assira.collection.lookups.Lookup;
+import static net.ranides.assira.collection.mockup.TPointEnum.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class ALookupTester extends TPointTester {
+    
+    public ALookupTester(TPointGenerator generator) {
+        super(generator);
+    }
+    
+    public void put(Map<TPoint, Integer> target, TPointEnum... items) {
+        for(TPointEnum item : items) {
+            target.put($key(item), $value(item));
+        }
+    }
+
+    public void basicPutInt(Lookup<TPoint> target, int count) {
+        int prev = target.size();
+        int value = 200;
+        for (TPoint point : $keys(count)) {
+            target.put(point, value++);
+        }
+        assertEquals(prev + count, target.size());
+        
+        basicPutInt(target);
+    }
+    
+    public void basicPutInteger(Map<TPoint, Integer> target, int count) {
+        int prev = target.size();
+        int value = 200;
+        for (TPoint point : $keys(count)) {
+            target.put(point, value++);
+        }
+        assertEquals(prev + count, target.size());
+        
+        basicPutInteger(target);
+    }
+
+    public void basicPutInt(Lookup<TPoint> target) {
+        int prev = target.size();
+        target.put($key(A1), $value(A1));
+        assertEquals(prev + 1, target.size());
+        
+        target.put($key(A1_EQ), $value(A1_EQ)); // identical hash & eq
+        assertEquals(prev + 1, target.size());
+        
+        target.put($key(A1_NE), $value(A1_NE)); // identical hash but not eq
+        assertEquals(prev + 2, target.size());
+    }
+    
+    public void basicPutInteger(Map<TPoint, Integer> target) {
+        int prev = target.size();
+        target.put($key(A1), $object(A1));
+        assertEquals(prev + 1, target.size());
+        
+        target.put($key(A1_EQ), $object(A1_EQ)); // identical hash & eq
+        assertEquals(prev + 1, target.size());
+        
+        target.put($key(A1_NE), $object(A1_NE)); // identical hash but not eq
+        assertEquals(prev + 2, target.size());
+    }
+
+    public void basicReplaceInt(Lookup<TPoint> target, int count) {
+        int prev = target.size();
+        for (TPoint point : $ukeys(count)) {
+            target.put(point, $value(B1));
+        }
+        assertEquals(prev + (2 * count), target.size());
+    }
+
+
+    public void basicReplaceInteger(Map<TPoint, Integer> target, int count) {
+        int prev = target.size();
+        for (TPoint point : $ukeys(count)) {
+            target.put(point, $object(B1));
+        }
+        assertEquals(prev + (2 * count), target.size());
+    }
+    
+    public void basicRemoveInt(Lookup<TPoint> target) {
+        target.defaultReturnValue(-1);
+        put(target, A1, B1, C1);
+        
+        assertNotRemoveInt(target, A1_NE);
+        
+        assertRemoveInt(target, A1_EQ, A1);
+        assertRemoveInt(target, B1, B1);
+        assertRemoveInt(target, C1, C1);
+        
+        assertEquals(0, target.size());
+        
+        assertNotRemoveInt(target, C1);
+    }
+    
+    public void basicRemoveInteger(Map<TPoint, Integer> target) {
+        put(target, A1, B1, C1);
+        
+        assertNotRemoveInteger(target, A1_NE);
+        
+        assertRemoveInteger(target, A1_EQ, A1);
+        assertRemoveInteger(target, B1, B1);
+        assertRemoveInteger(target, C1, C1);
+        
+        assertEquals(0, target.size());
+        
+        assertNotRemoveInteger(target, C1);
+    }
+    
+    public void basicRemoveInt(Lookup<TPoint> target, int count) {
+        assertEquals(0, target.size());
+        TPoint[] keys = $keys(count);
+        int[] values = $values(count);
+        
+        for(int i=0; i<count; i++) {
+            target.put(keys[i], values[i]);
+        }
+        assertEquals(count, target.size());
+        
+        for(int i=0; i<count; i++) {
+            assertEquals(values[i], target.removeInt(keys[i]));
+            assertEquals(count-i-1, target.size());
+        }
+        assertEquals(0, target.size());
+    }
+    
+    public void basicRemoveInteger(Map<TPoint, Integer> target, int count) {
+        assertEquals(0, target.size());
+        TPoint[] keys = $keys(count);
+        Integer[] values = $objects(count);
+        
+        for(int i=0; i<count; i++) {
+            target.put(keys[i], values[i]);
+        }
+        assertEquals(count, target.size());
+        
+        for(int i=0; i<count; i++) {
+            assertEquals(values[i], target.remove(keys[i]));
+            assertEquals(count-i-1, target.size());
+        }
+        assertEquals(0, target.size());
+    }
+
+    public void basicGetInt(Lookup<TPoint> target) {
+        assertEquals(0, target.getInt($key(A1)));
+        
+        put(target, A1, B1, C1);
+        
+        assertEquals(0, target.getInt($key(A1_NE)));
+        
+        assertEquals($value(A1), target.getInt($key(A1)));
+        assertEquals($value(A1), target.getInt($key(A1_EQ)));
+        assertEquals($value(B1), target.getInt($key(B1)));
+        assertEquals($value(C1), target.getInt($key(C1)));
+    }
+    
+    public void basicGetInteger(Map<TPoint, Integer> target) {
+        assertEquals(null, target.get($key(A1)));
+        
+        put(target, A1, B1, C1);
+        
+        assertEquals(null, target.get($key(A1_NE)));
+        
+        assertEquals($object(A1), target.get($key(A1)));
+        assertEquals($object(A1), target.get($key(A1_EQ)));
+        assertEquals($object(B1), target.get($key(B1)));
+        assertEquals($object(C1), target.get($key(C1)));
+    }
+    
+    public void logicRemoveInt(Lookup<TPoint> target) {
+        target.defaultReturnValue(-1);
+        put(target, A1, B1, C1);
+        
+        assertEquals(-1, target.removeInt($key(A1_NE)));
+        assertEquals(3, target.size());
+
+        assertContainsInt(target, A1_EQ, A1);
+        assertContainsInt(target, A1, A1);
+        assertRemoveInt(target, A1_EQ, A1);
+        assertNotContainsInt(target, A1_EQ);
+        assertNotContainsInt(target, A1);
+        
+        assertContainsInt(target, B1, B1);
+        assertRemoveInt(target, B1, B1);
+        assertNotContainsInt(target, B1);
+        
+        assertContainsInt(target, C1, C1);
+        assertRemoveInt(target, C1, C1);
+        assertNotContainsInt(target, C1);
+    }
+    
+    public void logicRemoveInteger(Map<TPoint, Integer> target) {
+        put(target, A1, B1, C1);
+        
+        assertEquals(null, target.remove($key(A1_NE)));
+        assertEquals(3, target.size());
+
+        assertContainsInteger(target, A1_EQ, A1);
+        assertContainsInteger(target, A1, A1);
+        assertRemoveInteger(target, A1_EQ, A1);
+        assertNotContainsInteger(target, A1_EQ);
+        assertNotContainsInteger(target, A1);
+        
+        assertContainsInteger(target, B1, B1);
+        assertRemoveInteger(target, B1, B1);
+        assertNotContainsInteger(target, B1);
+        
+        assertContainsInteger(target, C1, C1);
+        assertRemoveInteger(target, C1, C1);
+        assertNotContainsInteger(target, C1);
+    }
+    
+    public void basicContainsInt(Lookup<TPoint> target) {
+        assertEquals(0, target.size());
+        put(target, A1, B1);
+        
+        assertEquals(true, target.containsValue($value(A1)));
+        assertEquals(true, target.containsValue($value(B1)));
+        
+        assertEquals(false, target.containsValue($value(A1_EQ)));
+        assertEquals(false, target.containsValue($value(A1_NE)));
+        assertEquals(false, target.containsValue($value(C1)));
+    }
+    
+    public void basicContainsInteger(Map<TPoint, Integer> target) {
+        assertEquals(0, target.size());
+        put(target, A1, B1);
+        
+        assertEquals(true, target.containsValue($object(A1)));
+        assertEquals(true, target.containsValue($object(B1)));
+        
+        assertEquals(false, target.containsValue($object(A1_EQ)));
+        assertEquals(false, target.containsValue($object(A1_NE)));
+        assertEquals(false, target.containsValue($object(C1)));
+    }
+    
+    protected void assertRemoveInt(Lookup<TPoint> target, TPointEnum key, TPointEnum prev) {
+        int size = target.size();
+        assertEquals($value(prev), target.removeInt($key(key)));
+        assertEquals(size-1, target.size());
+    }
+    
+    protected void assertNotRemoveInt(Lookup<TPoint> target, TPointEnum key) {
+        int size = target.size();
+        assertEquals(target.defaultReturnValue(), target.removeInt($key(key)));
+        assertEquals(size, target.size());
+    }
+    
+    protected void assertContainsInt(Lookup<TPoint> target, TPointEnum key, TPointEnum value) {
+        assertEquals(true, target.containsKey($key(key)));
+        assertEquals($value(value), target.getInt($key(key)));
+    }
+    
+    protected void assertNotContainsInt(Lookup<TPoint> target, TPointEnum key) {
+        assertEquals(false, target.containsKey($key(key)));
+        assertEquals(target.defaultReturnValue(), target.getInt($key(key)));
+    }
+    
+    protected void assertRemoveInteger(Map<TPoint, Integer> target, TPointEnum key, TPointEnum prev) {
+        int size = target.size();
+        assertEquals($object(prev), target.remove($key(key)));
+        assertEquals(size-1, target.size());
+    }
+    
+    protected void assertNotRemoveInteger(Map<TPoint, Integer> target, TPointEnum key) {
+        int size = target.size();
+        assertEquals(null, target.remove($key(key)));
+        assertEquals(size, target.size());
+    }
+    
+    protected void assertContainsInteger(Map<TPoint, Integer> target, TPointEnum key, TPointEnum value) {
+        assertEquals(true, target.containsKey($key(key)));
+        assertEquals($object(value), target.get($key(key)));
+    }
+    
+    protected void assertNotContainsInteger(Map<TPoint, Integer> target, TPointEnum key) {
+        assertEquals(false, target.containsKey($key(key)));
+        assertEquals(null, target.get($key(key)));
+    }
+    
+}

+ 99 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPoint.java

@@ -0,0 +1,99 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.mockup;
+
+import java.util.Comparator;
+import net.ranides.assira.collection.HashComparator;
+import net.ranides.assira.collection.utils.HashUtils;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class TPoint {
+
+    private final int x;
+    private final int y;
+    private final int z;
+
+    public TPoint(int x, int y, int z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashUtils.hashValues(3, 37, x, y, z);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object == null) {
+            return false;
+        }
+        if (getClass() != object.getClass()) {
+            return false;
+        }
+        return STD.equals(this, (TPoint)object);
+    }
+
+    @Override
+    public String toString() {
+        return "(" + x + ":" + y + ":" + z + ")";
+    }
+    
+    public static abstract class PointComparator implements HashComparator<TPoint>, Comparator<TPoint> {
+    
+    }
+    
+    public static final PointComparator SUM = new PointComparator() {
+        @Override
+        public int hashCode(TPoint object) {
+            return object.x;
+        }
+
+        @Override
+        public boolean equals(TPoint value1, TPoint value2) {
+            return 0 == compare(value1,value2);
+        }
+
+        @Override
+        public int compare(TPoint value1, TPoint value2) {
+            int a = value1.x + value1.y + value1.z;
+            int b = value2.x + value2.y + value2.z;
+            return a-b;
+        }
+        
+        
+    };
+    
+    public static final PointComparator STD = new PointComparator() {
+        @Override
+        public int hashCode(TPoint object) {
+            return HashUtils.hashValues(1, 1199, object.x, object.y, object.z);
+        }
+
+        @Override
+        public boolean equals(TPoint value1, TPoint value2) {
+            return 0 == compare(value1,value2);
+        }
+
+        @Override
+        public int compare(TPoint value1, TPoint value2) {
+            int dx = value1.x - value2.x;
+            int dy = value1.y - value2.y;
+            int dz = value1.z - value2.z;
+            return dx!=0 ? dx : (dy!=0 ? dy : dz);
+        }
+        
+    };
+
+}

+ 19 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPointEnum.java

@@ -0,0 +1,19 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.mockup;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public enum TPointEnum {
+    A1,
+    A1_EQ,
+    A1_NE,
+    B1,
+    C1
+}

+ 132 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPointGenerator.java

@@ -0,0 +1,132 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.mockup;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class TPointGenerator {
+    
+    // zarezerwowane:
+    //      punkty hashcode < 100
+    //      punkty suma < 100
+    //      wartości mniejsze < 100
+    
+    private final TPoint[] mkeys = new TPoint[]{
+        new TPoint(7, 4, 6), 
+        new TPoint(7, 1, 9), 
+        new TPoint(7, 1, 2), 
+        new TPoint(8, 4, 5),
+        new TPoint(9, 4, 13)
+    };
+    
+    private final int[] mvalues = new int[]{
+        17, 
+        19, 
+        20, 
+        21,
+        22
+    };
+
+    public TPoint key(TPointEnum type) {
+        return mkeys[type.ordinal()];
+    }
+
+    public TPoint[] keys(int count) {
+        int x = 250;
+        int y = 100;
+        int z = 100;
+        TPoint[] array = new TPoint[count];
+        for (int i = 0; i < count; i++) {
+            array[i] = new TPoint(x++, y++, z++);
+        }
+        return array;
+    }
+
+    /**
+     * Zwraca listę 3*count elementów, w której punkty są częściowo równe:
+     * A B1 C, A B1 C, A B1 C, ...
+     * gdzie
+     *    A - punkt oryginalny
+     *    B1 - punkty równy
+     *    C - punkt różny ale ten sam hashcode
+     * @param count
+     * @return
+     */
+    public TPoint[] ukeys(int count) {
+        int x = 250;
+        int y = 100;
+        int z = 100;
+        int n = 3 * count;
+        TPoint[] array = new TPoint[n];
+        for (int i = 0; i < n; i += 3) {
+            array[i + 0] = new TPoint(x, y, z);
+            array[i + 1] = new TPoint(x, y + 1, z - 1);
+            array[i + 2] = new TPoint(x, y + 2, z + 2);
+            x++;
+            y += 3;
+            z += 3;
+        }
+        return array;
+    }
+
+    public int value(TPointEnum type) {
+        return mvalues[type.ordinal()];
+    }
+
+    public int[] values(int count) {
+        int[] array = new int[count];
+        int value = 200;
+        for (int i = 0; i < count; i++) {
+            array[i] = (value++);
+        }
+        return array;
+    }
+
+    public Integer object(TPointEnum type) {
+        return mvalues[type.ordinal()];
+    }
+
+    public Integer[] objects(int count) {
+        Integer[] array = new Integer[count];
+        int value = 200;
+        for (int i = 0; i < count; i++) {
+            array[i] = (value++);
+        }
+        return array;
+    }
+
+    public Map<TPoint, Integer> map(TPoint[] keys) {
+        Map<TPoint, Integer> target = new TreeMap<>(TPoint.STD);
+        int[] values = values(keys.length);
+        for (int i = 0; i < keys.length; i++) {
+            target.put(keys[i], values[i]);
+        }
+        return target;
+    }
+
+    public Map<TPoint, Integer> map(TPoint[] points, int[] values) {
+        Map<TPoint, Integer> target = new TreeMap<>(TPoint.STD);
+        for (int i = 0; i < points.length; i++) {
+            target.put(points[i], values[i]);
+        }
+        return target;
+    }
+
+    public Map<TPoint, Integer> map(TPoint[] points, Integer[] values) {
+        Map<TPoint, Integer> target = new TreeMap<>(TPoint.STD);
+        for (int i = 0; i < points.length; i++) {
+            target.put(points[i], values[i]);
+        }
+        return target;
+    }
+    
+}

+ 63 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPointTester.java

@@ -0,0 +1,63 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.mockup;
+
+import java.util.Map;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public abstract class TPointTester {
+    
+    private final TPointGenerator generator;
+
+    public TPointTester(TPointGenerator generator) {
+        this.generator = generator;
+    }
+    
+    protected TPoint $key(TPointEnum type) {
+        return generator.key(type);
+    }
+
+    protected TPoint[] $keys(int count) {
+        return generator.keys(count);
+    }
+
+    protected TPoint[] $ukeys(int count) {
+        return generator.ukeys(count);
+    }
+
+    protected int $value(TPointEnum type) {
+        return generator.value(type);
+    }
+
+    protected int[] $values(int count) {
+        return generator.values(count);
+    }
+
+    protected Integer $object(TPointEnum type) {
+        return generator.object(type);
+    }
+
+    protected Integer[] $objects(int count) {
+        return generator.objects(count);
+    }
+
+    protected Map<TPoint, Integer> $map(TPoint[] keys) {
+        return generator.map(keys);
+    }
+
+    protected Map<TPoint, Integer> $map(TPoint[] points, int[] values) {
+        return generator.map(points, values);
+    }
+
+    protected Map<TPoint, Integer> $map(TPoint[] points, Integer[] values) {
+        return generator.map(points, values);
+    }
+    
+}

+ 0 - 1
assira1/src/main/java/net/ranides/assira/events/EventDispatcher.java

@@ -132,7 +132,6 @@ public class EventDispatcher implements EventRouter {
     }
 
     @SuppressWarnings("unchecked")
-    @edu.umd.cs.findbugs.annotations.SuppressWarnings({"REC_CATCH_EXCEPTION"})
     protected void dispatchEvent(Event event, boolean direct) {
         Object[] array;
         // read updated