|
|
@@ -35,9 +35,11 @@ import net.ranides.assira.generic.CompareUtils;
|
|
|
*/
|
|
|
public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
|
|
|
- private final Map<String, Object> name2index = new HashMap<>();
|
|
|
+ private final Map<String, Comparator> name2sindex = new HashMap<>();
|
|
|
|
|
|
- private final Map<Comparator, ASortedSet<V>> cindexes = new HashMap<>();
|
|
|
+ private final Map<String, IndexComparator> name2mindex = new HashMap<>();
|
|
|
+
|
|
|
+ private final Map<Comparator, RBTreeMultiSet<V>> cindexes = new HashMap<>();
|
|
|
|
|
|
private final Map<IndexComparator, RBTreeMultiMap<Object, V>> mindexes = new HashMap<>();
|
|
|
|
|
|
@@ -45,7 +47,7 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
public IndexMap<V> index(String name, Comparator<V> index) {
|
|
|
RBTreeMultiSet<V> set = new RBTreeMultiSet<>(index);
|
|
|
cindexes.put(index, set);
|
|
|
- name2index.put(name, index);
|
|
|
+ name2sindex.put(name, index);
|
|
|
for(V item : values()) {
|
|
|
set.add(item);
|
|
|
}
|
|
|
@@ -56,7 +58,7 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
public <T> IndexMap<V> index(String name, IndexComparator<V, T> index) {
|
|
|
RBTreeMultiMap<Object,V> map = new RBTreeMultiMap<>();
|
|
|
mindexes.put(index, map);
|
|
|
- name2index.put(name, index);
|
|
|
+ name2mindex.put(name, index);
|
|
|
for(V item : values()) {
|
|
|
map.put(index.apply(item),item);
|
|
|
}
|
|
|
@@ -64,12 +66,17 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected Object $index(String name) {
|
|
|
- return name2index.get(name);
|
|
|
+ protected <T> IndexComparator<V, T> mindex(String name) {
|
|
|
+ return name2mindex.get(name);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected Comparator<V> sindex(String name) {
|
|
|
+ return name2sindex.get(name);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected void $update(V value, Consumer<? super V> consumer) {
|
|
|
+ protected void update(V value, Consumer<? super V> consumer) {
|
|
|
remove(value);
|
|
|
consumer.accept(value);
|
|
|
put(value);
|
|
|
@@ -116,7 +123,7 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected void $update() {
|
|
|
+ protected void update() {
|
|
|
List<V> items = new ArrayList<>(values());
|
|
|
for(SortedSet<V> index : cindexes.values()) {
|
|
|
index.clear();
|
|
|
@@ -165,17 +172,28 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
}
|
|
|
|
|
|
private Object after(ASortedMap<Object, V> map, Object value) {
|
|
|
- Comparator<Object> cmp = map.comparator();
|
|
|
+ Comparator<Object> cmp = CompareUtils.comparator();
|
|
|
Iterator<Object> i = map.keySet().iterator(value);
|
|
|
while(i.hasNext()) {
|
|
|
Object next = i.next();
|
|
|
- if(!CompareUtils.equals(value, next)) {
|
|
|
+ if(cmp.compare(value, next)!=0) {
|
|
|
+ return next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private V after(ASortedSet<V> set, V value) {
|
|
|
+ Comparator<? super V> cmp = set.comparator();
|
|
|
+ Iterator<V> i = set.iterator(value);
|
|
|
+ while(i.hasNext()) {
|
|
|
+ V next = i.next();
|
|
|
+ if(cmp.compare(value, next)!=0) {
|
|
|
return next;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
|
|
|
private final class CHQuery extends AIndexQuery<V> {
|
|
|
|
|
|
@@ -198,70 +216,74 @@ public class CIndexTreeMap<V> extends AIndexMap<V> {
|
|
|
|
|
|
@Override
|
|
|
public Stream<V> stream() {
|
|
|
- return $select().stream();
|
|
|
+ return select().stream();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public int size() {
|
|
|
- return $select().size();
|
|
|
+ return select().size();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public Iterator<V> iterator() {
|
|
|
- return $select().iterator();
|
|
|
+ return select().iterator();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IndexQuery<V> $eq(Object index, Object value) {
|
|
|
- if(index instanceof Comparator) {
|
|
|
- return new CHQuery(this, () -> cindexes.get(index).getAll((V)value));
|
|
|
- } else {
|
|
|
- return new CHQuery(this, () -> mindexes.get(index).getAll(value));
|
|
|
- }
|
|
|
+ public IndexQuery<V> eq(Comparator<V> index, V value) {
|
|
|
+ return new CHQuery(this, () -> cindexes.get(index).getAll(value));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IndexQuery<V> $gt(Object index, Object value) {
|
|
|
- if(index instanceof Comparator) {
|
|
|
- ASortedSet<V> set = cindexes.get(index);
|
|
|
- return new CHQuery(this, () -> {
|
|
|
- V last = set.after((V)value);
|
|
|
- return last==null ? Collections.emptyList() : set.tailSet(last);
|
|
|
- });
|
|
|
- } else {
|
|
|
- RBTreeMultiMap<Object, V> map = mindexes.get(index);
|
|
|
- return new CHQuery(this, () -> {
|
|
|
- Object last = after(map,value);
|
|
|
- return last==null ? Collections.emptyList() : map.tailMap(last).values();
|
|
|
- });
|
|
|
- }
|
|
|
+ public <T> IndexQuery<V> eq(IndexComparator<V, T> index, T value) {
|
|
|
+ return new CHQuery(this, () -> mindexes.get(index).getAll(value));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IndexQuery<V> $lt(Object index, Object value) {
|
|
|
- if(index instanceof Comparator) {
|
|
|
- return new CHQuery(this, () -> cindexes.get(index).headSet((V)value));
|
|
|
- } else {
|
|
|
- return new CHQuery(this, () -> mindexes.get(index).headMap(value).values());
|
|
|
- }
|
|
|
+ public IndexQuery<V> gt(Comparator<V> index, V value) {
|
|
|
+ ASortedSet<V> set = cindexes.get(index);
|
|
|
+ return new CHQuery(this, () -> {
|
|
|
+ V last = after(set,value);
|
|
|
+ return last==null ? Collections.emptyList() : set.tailSet(last);
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IndexQuery<V> $in(Object index, Object begin, Object end) {
|
|
|
- if(index instanceof Comparator) {
|
|
|
- return new CHQuery(this, () -> cindexes.get(index).subSet((V)begin, (V)end));
|
|
|
- } else {
|
|
|
- return new CHQuery(this, () -> mindexes.get(index).subMap((V)begin, (V)end).values());
|
|
|
- }
|
|
|
+ public <T> IndexQuery<V> gt(IndexComparator<V, T> index, T value) {
|
|
|
+ RBTreeMultiMap<Object, V> map = mindexes.get(index);
|
|
|
+ return new CHQuery(this, () -> {
|
|
|
+ Object last = after(map,value);
|
|
|
+ return last==null ? Collections.emptyList() : map.tailMap(last).values();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IndexQuery<V> lt(Comparator<V> index, V value) {
|
|
|
+ return new CHQuery(this, () -> cindexes.get(index).headSet(value));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public <T> IndexQuery<V> lt(IndexComparator<V, T> index, T value) {
|
|
|
+ return new CHQuery(this, () -> mindexes.get(index).headMap(value).values());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IndexQuery<V> in(Comparator<V> index, V begin, V end) {
|
|
|
+ return new CHQuery(this, () -> cindexes.get(index).subSet(begin, end));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public <T> IndexQuery<V> in(IndexComparator<V, T> index, T begin, T end) {
|
|
|
+ return new CHQuery(this, () -> mindexes.get(index).subMap(begin, end).values());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void remove() {
|
|
|
- removeAll($select());
|
|
|
+ removeAll(select());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected Collection<V> $select() {
|
|
|
+ protected Collection<V> select() {
|
|
|
int psize = 0;
|
|
|
Collection<V> prim = null;
|
|
|
List<Collection<V>> sec = new ArrayList<>(selectors.size()-1);
|