|
@@ -1,433 +1,434 @@
|
|
|
-/*
|
|
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
- * @copyright Ranides Atterwim
|
|
|
|
|
- * @license WTFPL
|
|
|
|
|
- * @url http://ranides.net/projects/assira
|
|
|
|
|
- */
|
|
|
|
|
-package net.ranides.assira.test;
|
|
|
|
|
-
|
|
|
|
|
-import java.io.PrintStream;
|
|
|
|
|
-import java.io.Serializable;
|
|
|
|
|
-import java.util.AbstractMap;
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.Comparator;
|
|
|
|
|
-import java.util.Iterator;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-import java.util.Map.Entry;
|
|
|
|
|
-import java.util.Random;
|
|
|
|
|
-import net.ranides.assira.collection.HashComparator;
|
|
|
|
|
-import net.ranides.assira.collection.Swapper;
|
|
|
|
|
-import net.ranides.assira.collection.arrays.ArrayUtils;
|
|
|
|
|
-import net.ranides.assira.collection.arrays.NativeArrayAllocator;
|
|
|
|
|
-import net.ranides.assira.collection.lookups.ALookup;
|
|
|
|
|
-import net.ranides.assira.collection.lookups.Lookup.LookupEntry;
|
|
|
|
|
-import net.ranides.assira.collection.maps.HashMap;
|
|
|
|
|
-import net.ranides.assira.collection.maps.AIntMap;
|
|
|
|
|
-import net.ranides.assira.collection.maps.IntMap;
|
|
|
|
|
-import net.ranides.assira.collection.maps.IntMap.IntEntry;
|
|
|
|
|
-import net.ranides.assira.generic.CompareUtils;
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- *
|
|
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
- */
|
|
|
|
|
-public abstract class TMap<K,V> implements Serializable {
|
|
|
|
|
-
|
|
|
|
|
- private final TCollection<K> kgen = new TCollection<K>() {
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public K value(int index, int n) {
|
|
|
|
|
- return TMap.this.item(index, n).key();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(K a, K b) {
|
|
|
|
|
- return TMap.this.cmp(a, b);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(K value) {
|
|
|
|
|
- return TMap.this.hash(value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- private final TCollection<Entry<K,V>> egen = new TCollection<Entry<K,V>>() {
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public Entry<K,V> value(int index, int n) {
|
|
|
|
|
- return TMap.this.item(index, n).entry();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(Entry<K, V> a, Entry<K, V> b) {
|
|
|
|
|
- return TMap.this.cmp(a.getKey(),b.getKey());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(Entry<K, V> value) {
|
|
|
|
|
- return value.hashCode();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- private final TCollection<IntEntry<V>> eigen = new TCollection<IntEntry<V>>() {
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public IntEntry<V> value(int index, int n) {
|
|
|
|
|
- return TMap.this.item(index, n).entryInt();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(IntEntry<V> a, IntEntry<V> b) {
|
|
|
|
|
- return TMap.this.cmp((K)(Object)a.getKey(),(K)(Object)b.getKey());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(IntEntry<V> value) {
|
|
|
|
|
- return value.hashCode();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- private final TCollection<LookupEntry<K>> lgen = new TCollection<LookupEntry<K>>() {
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public LookupEntry<K> value(int index, int n) {
|
|
|
|
|
- return TMap.this.item(index, n).lookup();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(LookupEntry<K> a, LookupEntry<K> b) {
|
|
|
|
|
- return TMap.this.cmp(a.getKey(),b.getKey());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(LookupEntry<K> value) {
|
|
|
|
|
- return value.hashCode();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- private final TCollection<V> vgen = new TCollection<V>() {
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public V value(int index, int n) {
|
|
|
|
|
- return TMap.this.item(index,n).value();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(V a, V b) {
|
|
|
|
|
- return CompareUtils.cmp(a, b);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(V value) {
|
|
|
|
|
- return value.hashCode();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- public static final class TItem<K,V> {
|
|
|
|
|
-
|
|
|
|
|
- private final TMap<K,V> that;
|
|
|
|
|
-
|
|
|
|
|
- private final K key;
|
|
|
|
|
-
|
|
|
|
|
- private final V value;
|
|
|
|
|
-
|
|
|
|
|
- protected TItem(TMap<K,V> that, K key, V value) {
|
|
|
|
|
- this.that = that;
|
|
|
|
|
- this.key = key;
|
|
|
|
|
- this.value = value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public K key() {
|
|
|
|
|
- return key;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public V value() {
|
|
|
|
|
- return value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public int keyInt() {
|
|
|
|
|
- return (Integer)key;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public int valueInt() {
|
|
|
|
|
- return (Integer)value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public Entry<K,V> entry() {
|
|
|
|
|
- return new AbstractMap.SimpleImmutableEntry<>(key, value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public IntMap.Entry<K,V> entry(int value) {
|
|
|
|
|
- return new AbstractMap.SimpleImmutableEntry<>(key, that.value(value));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public IntEntry<V> entryInt() {
|
|
|
|
|
- return new AIntMap.BasicEntry<>(keyInt(), value());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public IntMap.IntEntry<V> entryInt(int value) {
|
|
|
|
|
- return new AIntMap.BasicEntry<>(keyInt(), that.value(value));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public LookupEntry<K> lookup(int value) {
|
|
|
|
|
- return new ALookup.BasicEntry<>(key, that.item(value).valueInt());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public LookupEntry<K> lookup() {
|
|
|
|
|
- return new ALookup.BasicEntry<>(key, valueInt());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public <M extends Map<K,V>> M into(M target) {
|
|
|
|
|
- target.put(key(), value());
|
|
|
|
|
- return target;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public static final class TItems<K,V> implements Iterable<TItem<K,V>> {
|
|
|
|
|
-
|
|
|
|
|
- protected final TMap<K,V> that;
|
|
|
|
|
-
|
|
|
|
|
- protected final List<TItem<K,V>> data = new ArrayList<>();
|
|
|
|
|
-
|
|
|
|
|
- protected TItems(TMap<K,V> that) {
|
|
|
|
|
- this.that = that;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public K[] keys() {
|
|
|
|
|
- K[] array = NativeArrayAllocator.forComponent(that.key(0).getClass(), data.size());
|
|
|
|
|
- for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).key();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public V[] values() {
|
|
|
|
|
- V[] array = NativeArrayAllocator.forComponent(that.value(0).getClass(), data.size());
|
|
|
|
|
- for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).value();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public int[] keysInt() {
|
|
|
|
|
- int[] array = new int[data.size()];
|
|
|
|
|
- for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).keyInt();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public int[] valuesInt() {
|
|
|
|
|
- int[] array = new int[data.size()];
|
|
|
|
|
- for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).valueInt();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public Entry<K,V>[] entries() {
|
|
|
|
|
- Entry<K,V> array[] = new Entry[data.size()];
|
|
|
|
|
- for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).entry();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public IntEntry<V>[] entriesInt() {
|
|
|
|
|
- IntEntry<V> array[] = new IntEntry[data.size()];
|
|
|
|
|
- for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).entryInt();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
|
|
- public LookupEntry<K>[] lookups() {
|
|
|
|
|
- LookupEntry<K> array[] = new LookupEntry[data.size()];
|
|
|
|
|
- for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
- array[i] = data.get(i).lookup();
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> sort(Comparator<K> cmp) {
|
|
|
|
|
- TItems<K,V> items = new TItems<>(that);
|
|
|
|
|
- items.data.addAll(data);
|
|
|
|
|
- items.data.sort((a,b)->cmp.compare(a.key(), b.key()));
|
|
|
|
|
- return items;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> shuffle(long seed) {
|
|
|
|
|
- ArrayUtils.shuffle(data.size(), new Random(seed), Swapper.swapper(data));
|
|
|
|
|
- return this;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> item(int item) {
|
|
|
|
|
- data.add(that.item(item,0));
|
|
|
|
|
- return this;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> item(int item, int n) {
|
|
|
|
|
- data.add(that.item(item,n));
|
|
|
|
|
- return this;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- public Iterator<TItem<K,V>> iterator() {
|
|
|
|
|
- return data.iterator();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItem<K,V> at(int index) {
|
|
|
|
|
- return data.get(index);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public <M extends Map<K,V>> M into(M target) {
|
|
|
|
|
- for(TItem<K,V> item : data) {
|
|
|
|
|
- target.put(item.key(), item.value());
|
|
|
|
|
- }
|
|
|
|
|
- return target;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void dump(PrintStream out) {
|
|
|
|
|
- out.printf("TItems(%d)%n", data.size());
|
|
|
|
|
- for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
- out.printf(" - %3d. %s%n", i, data.get(i).key());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- protected abstract K key(int index, int n);
|
|
|
|
|
-
|
|
|
|
|
- protected abstract V value(int index, int n);
|
|
|
|
|
-
|
|
|
|
|
- protected abstract int cmp(K a, K b);
|
|
|
|
|
-
|
|
|
|
|
- protected abstract int hash(K key);
|
|
|
|
|
-
|
|
|
|
|
- protected K key(int index) {
|
|
|
|
|
- return key(index, 0);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- protected V value(int index) {
|
|
|
|
|
- return value(index, 0);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public HashComparator<K> comparator() {
|
|
|
|
|
- return kgen.comparator();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItem<K,V> item(int index) {
|
|
|
|
|
- return item(index, 0);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItem<K,V> item(int index, int n) {
|
|
|
|
|
- return new TItem<>(this, key(index, n), value(index, n));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> list(int... indexes) {
|
|
|
|
|
- TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
- for(int i=0; i<indexes.length; i++) {
|
|
|
|
|
- ret.data.add(item(indexes[i]));
|
|
|
|
|
- }
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> range(int begin, int end) {
|
|
|
|
|
- TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
- for(int i=begin; i<end; i++) {
|
|
|
|
|
- ret.data.add(item(i));
|
|
|
|
|
- }
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> range(int count) {
|
|
|
|
|
- return range(0,count);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> urange(int begin, int end) {
|
|
|
|
|
- TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
- for(int i=begin; i<end; i++) {
|
|
|
|
|
- ret.data.add(item(i,0));
|
|
|
|
|
- ret.data.add(item(i,0));
|
|
|
|
|
- ret.data.add(item(i,1));
|
|
|
|
|
- }
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TItems<K,V> urange(int count) {
|
|
|
|
|
- return urange(0,count);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TCollection<K> keys() {
|
|
|
|
|
- return kgen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TCollection<V> values() {
|
|
|
|
|
- return vgen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TCollection<Entry<K,V>> entries() {
|
|
|
|
|
- return egen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TCollection<IntEntry<V>> entriesInt() {
|
|
|
|
|
- return eigen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TCollection<LookupEntry<K>> lookups() {
|
|
|
|
|
- return lgen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public TMap<K,V> asIdentity() {
|
|
|
|
|
- return new TIdentityMap();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private class TIdentityMap extends TMap<K, V> {
|
|
|
|
|
-
|
|
|
|
|
- private final HashMap<Integer, TItem<K,V>> emap = new HashMap<>();
|
|
|
|
|
- private final HashMap<K, Integer> imap = new HashMap<>();
|
|
|
|
|
-
|
|
|
|
|
- private TItem<K,V> iitem(int index, int n) {
|
|
|
|
|
- if(n != 0) {
|
|
|
|
|
- throw new UnsupportedOperationException("NO TEST");
|
|
|
|
|
- }
|
|
|
|
|
- if(!emap.containsKey(index)) {
|
|
|
|
|
- emap.put(index, TMap.this.item(index));
|
|
|
|
|
- imap.put(emap.get(index).key(), index);
|
|
|
|
|
- }
|
|
|
|
|
- return emap.get(index);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected K key(int index, int n) {
|
|
|
|
|
- return iitem(index, n).key();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected V value(int index, int n) {
|
|
|
|
|
- return iitem(index, n).value();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int cmp(K a, K b) {
|
|
|
|
|
- return imap.get(a) - imap.get(b);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Override
|
|
|
|
|
- protected int hash(K key) {
|
|
|
|
|
- return System.identityHashCode(key);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
+ * @copyright Ranides Atterwim
|
|
|
|
|
+ * @license WTFPL
|
|
|
|
|
+ * @url http://ranides.net/projects/assira
|
|
|
|
|
+ */
|
|
|
|
|
+package net.ranides.assira.test;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.PrintStream;
|
|
|
|
|
+import java.io.Serializable;
|
|
|
|
|
+import java.util.AbstractMap;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Comparator;
|
|
|
|
|
+import java.util.Iterator;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Map.Entry;
|
|
|
|
|
+import java.util.Random;
|
|
|
|
|
+import net.ranides.assira.collection.HashComparator;
|
|
|
|
|
+import net.ranides.assira.collection.Swapper;
|
|
|
|
|
+import net.ranides.assira.collection.arrays.ArrayUtils;
|
|
|
|
|
+import net.ranides.assira.collection.arrays.NativeArrayAllocator;
|
|
|
|
|
+import net.ranides.assira.collection.lookups.ALookup;
|
|
|
|
|
+import net.ranides.assira.collection.lookups.Lookup.LookupEntry;
|
|
|
|
|
+import net.ranides.assira.collection.maps.HashMap;
|
|
|
|
|
+import net.ranides.assira.collection.maps.AIntMap;
|
|
|
|
|
+import net.ranides.assira.collection.maps.IntMap;
|
|
|
|
|
+import net.ranides.assira.collection.maps.IntMap.IntEntry;
|
|
|
|
|
+import net.ranides.assira.generic.CompareUtils;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
+ */
|
|
|
|
|
+public abstract class TMap<K,V> implements Serializable {
|
|
|
|
|
+
|
|
|
|
|
+ private final TCollection<K> kgen = new TCollection<K>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public K value(int index, int n) {
|
|
|
|
|
+ return TMap.this.item(index, n).key();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(K a, K b) {
|
|
|
|
|
+ return TMap.this.cmp(a, b);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(K value) {
|
|
|
|
|
+ return TMap.this.hash(value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ private final TCollection<Entry<K,V>> egen = new TCollection<Entry<K,V>>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Entry<K,V> value(int index, int n) {
|
|
|
|
|
+ return TMap.this.item(index, n).entry();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(Entry<K, V> a, Entry<K, V> b) {
|
|
|
|
|
+ return TMap.this.cmp(a.getKey(),b.getKey());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(Entry<K, V> value) {
|
|
|
|
|
+ return value.hashCode();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ private final TCollection<IntEntry<V>> eigen = new TCollection<IntEntry<V>>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IntEntry<V> value(int index, int n) {
|
|
|
|
|
+ return TMap.this.item(index, n).entryInt();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(IntEntry<V> a, IntEntry<V> b) {
|
|
|
|
|
+ return TMap.this.cmp((K)(Object)a.getKey(),(K)(Object)b.getKey());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(IntEntry<V> value) {
|
|
|
|
|
+ return value.hashCode();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ private final TCollection<LookupEntry<K>> lgen = new TCollection<LookupEntry<K>>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public LookupEntry<K> value(int index, int n) {
|
|
|
|
|
+ return TMap.this.item(index, n).lookup();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(LookupEntry<K> a, LookupEntry<K> b) {
|
|
|
|
|
+ return TMap.this.cmp(a.getKey(),b.getKey());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(LookupEntry<K> value) {
|
|
|
|
|
+ return value.hashCode();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ private final TCollection<V> vgen = new TCollection<V>() {
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public V value(int index, int n) {
|
|
|
|
|
+ return TMap.this.item(index,n).value();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(V a, V b) {
|
|
|
|
|
+ return CompareUtils.cmp(a, b);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(V value) {
|
|
|
|
|
+ return value.hashCode();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ public static final class TItem<K,V> {
|
|
|
|
|
+
|
|
|
|
|
+ private final TMap<K,V> that;
|
|
|
|
|
+
|
|
|
|
|
+ private final K key;
|
|
|
|
|
+
|
|
|
|
|
+ private final V value;
|
|
|
|
|
+
|
|
|
|
|
+ protected TItem(TMap<K,V> that, K key, V value) {
|
|
|
|
|
+ this.that = that;
|
|
|
|
|
+ this.key = key;
|
|
|
|
|
+ this.value = value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public K key() {
|
|
|
|
|
+ return key;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public V value() {
|
|
|
|
|
+ return value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public int keyInt() {
|
|
|
|
|
+ return (Integer)key;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public int valueInt() {
|
|
|
|
|
+ return (Integer)value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public Entry<K,V> entry() {
|
|
|
|
|
+ return new AbstractMap.SimpleImmutableEntry<>(key, value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public IntMap.Entry<K,V> entry(int value) {
|
|
|
|
|
+ return new AbstractMap.SimpleImmutableEntry<>(key, that.value(value));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public IntEntry<V> entryInt() {
|
|
|
|
|
+ return new AIntMap.BasicEntry<>(keyInt(), value());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public IntMap.IntEntry<V> entryInt(int value) {
|
|
|
|
|
+ return new AIntMap.BasicEntry<>(keyInt(), that.value(value));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public LookupEntry<K> lookup(int value) {
|
|
|
|
|
+ return new ALookup.BasicEntry<>(key, that.item(value).valueInt());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public LookupEntry<K> lookup() {
|
|
|
|
|
+ return new ALookup.BasicEntry<>(key, valueInt());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public <M extends Map<K,V>> M into(M target) {
|
|
|
|
|
+ target.put(key(), value());
|
|
|
|
|
+ return target;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static final class TItems<K,V> implements Iterable<TItem<K,V>> {
|
|
|
|
|
+
|
|
|
|
|
+ protected final TMap<K,V> that;
|
|
|
|
|
+
|
|
|
|
|
+ protected final List<TItem<K,V>> data = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ protected TItems(TMap<K,V> that) {
|
|
|
|
|
+ this.that = that;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public K[] keys() {
|
|
|
|
|
+ K[] array = NativeArrayAllocator.forComponent(that.key(0).getClass(), data.size());
|
|
|
|
|
+ for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).key();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public V[] values() {
|
|
|
|
|
+ V[] array = NativeArrayAllocator.forComponent(that.value(0).getClass(), data.size());
|
|
|
|
|
+ for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).value();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public int[] keysInt() {
|
|
|
|
|
+ int[] array = new int[data.size()];
|
|
|
|
|
+ for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).keyInt();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public int[] valuesInt() {
|
|
|
|
|
+ int[] array = new int[data.size()];
|
|
|
|
|
+ for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).valueInt();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public Entry<K,V>[] entries() {
|
|
|
|
|
+ Entry<K,V> array[] = new Entry[data.size()];
|
|
|
|
|
+ for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).entry();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public IntEntry<V>[] entriesInt() {
|
|
|
|
|
+ IntEntry<V> array[] = new IntEntry[data.size()];
|
|
|
|
|
+ for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).entryInt();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public LookupEntry<K>[] lookups() {
|
|
|
|
|
+ LookupEntry<K> array[] = new LookupEntry[data.size()];
|
|
|
|
|
+ for(int i=0, n=data.size(); i<n; i++) {
|
|
|
|
|
+ array[i] = data.get(i).lookup();
|
|
|
|
|
+ }
|
|
|
|
|
+ return array;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> sort(Comparator<K> cmp) {
|
|
|
|
|
+ TItems<K,V> items = new TItems<>(that);
|
|
|
|
|
+ items.data.addAll(data);
|
|
|
|
|
+ items.data.sort((a,b)->cmp.compare(a.key(), b.key()));
|
|
|
|
|
+ return items;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> shuffle(long seed) {
|
|
|
|
|
+ ArrayUtils.shuffle(data.size(), new Random(seed), Swapper.swapper(data));
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> item(int item) {
|
|
|
|
|
+ data.add(that.item(item,0));
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> item(int item, int n) {
|
|
|
|
|
+ data.add(that.item(item,n));
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Iterator<TItem<K,V>> iterator() {
|
|
|
|
|
+ return data.iterator();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItem<K,V> at(int index) {
|
|
|
|
|
+ return data.get(index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public <M extends Map<K,V>> M into(M target) {
|
|
|
|
|
+ for(TItem<K,V> item : data) {
|
|
|
|
|
+ target.put(item.key(), item.value());
|
|
|
|
|
+ }
|
|
|
|
|
+ return target;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void dump(PrintStream out) {
|
|
|
|
|
+ out.printf("TItems(%d)%n", data.size());
|
|
|
|
|
+ for(int i=0,n=data.size(); i<n; i++) {
|
|
|
|
|
+ out.printf(" - %3d. %s%n", i, data.get(i).key());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract K key(int index, int n);
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract V value(int index, int n);
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract int cmp(K a, K b);
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract int hash(K key);
|
|
|
|
|
+
|
|
|
|
|
+ protected K key(int index) {
|
|
|
|
|
+ return key(index, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected V value(int index) {
|
|
|
|
|
+ return value(index, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public HashComparator<K> comparator() {
|
|
|
|
|
+ return kgen.comparator();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItem<K,V> item(int index) {
|
|
|
|
|
+ return item(index, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItem<K,V> item(int index, int n) {
|
|
|
|
|
+ return new TItem<>(this, key(index, n), value(index, n));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> list(int... indexes) {
|
|
|
|
|
+ TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
+ for(int i=0; i<indexes.length; i++) {
|
|
|
|
|
+ ret.data.add(item(indexes[i]));
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> range(int begin, int end) {
|
|
|
|
|
+ TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
+ for(int i=begin; i<end; i++) {
|
|
|
|
|
+ ret.data.add(item(i));
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> range(int count) {
|
|
|
|
|
+ return range(0,count);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> urange(int begin, int end) {
|
|
|
|
|
+ TItems<K,V> ret = new TItems<>(this);
|
|
|
|
|
+ for(int i=begin; i<end; i++) {
|
|
|
|
|
+ ret.data.add(item(i,0));
|
|
|
|
|
+ ret.data.add(item(i,0));
|
|
|
|
|
+ ret.data.add(item(i,1));
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TItems<K,V> urange(int count) {
|
|
|
|
|
+ return urange(0,count);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TCollection<K> keys() {
|
|
|
|
|
+ return kgen;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TCollection<V> values() {
|
|
|
|
|
+ return vgen;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TCollection<Entry<K,V>> entries() {
|
|
|
|
|
+ return egen;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TCollection<IntEntry<V>> entriesInt() {
|
|
|
|
|
+ return eigen;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TCollection<LookupEntry<K>> lookups() {
|
|
|
|
|
+ return lgen;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public TMap<K,V> asIdentity() {
|
|
|
|
|
+ return new TIdentityMap();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private class TIdentityMap extends TMap<K, V> {
|
|
|
|
|
+
|
|
|
|
|
+ private final HashMap<Integer, TItem<K,V>> emap = new HashMap<>();
|
|
|
|
|
+ private final HashMap<K, Integer> imap = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ private TItem<K,V> iitem(int index, int n) {
|
|
|
|
|
+ if(n != 0) {
|
|
|
|
|
+ throw new UnsupportedOperationException("NO TEST");
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!emap.containsKey(index)) {
|
|
|
|
|
+ emap.put(index, TMap.this.item(index));
|
|
|
|
|
+ imap.put(emap.get(index).key(), index);
|
|
|
|
|
+ }
|
|
|
|
|
+ return emap.get(index);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected K key(int index, int n) {
|
|
|
|
|
+ return iitem(index, n).key();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected V value(int index, int n) {
|
|
|
|
|
+ return iitem(index, n).value();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int cmp(K a, K b) {
|
|
|
|
|
+ return imap.get(a) - imap.get(b);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int hash(K key) {
|
|
|
|
|
+ return System.identityHashCode(key);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|