📄 thickindex.java
字号:
package org.garret.perst.impl;
import org.garret.perst.*;
import java.util.*;
class ThickIndex<T extends IPersistent> extends PersistentCollection<T> implements Index<T> {
private Index<IPersistent> index;
private int nElems;
static final int BTREE_THRESHOLD = 128;
ThickIndex(Class keyType, StorageImpl db) {
super(db);
index = db.<IPersistent>createIndex(keyType, true);
}
ThickIndex() {}
public T get(Key key) {
IPersistent s = index.get(key);
if (s == null) {
return null;
}
if (s instanceof Relation) {
Relation r = (Relation)s;
if (r.size() == 1) {
return (T)r.get(0);
}
}
throw new StorageError(StorageError.KEY_NOT_UNIQUE);
}
public T get(Object key) {
return get(Btree.getKeyFromObject(key));
}
public ArrayList<T> getList(Key from, Key till) {
return extendList(index.getList(from, till));
}
public ArrayList<T> getList(Object from, Object till) {
return extendList(index.getList(from, till));
}
public IPersistent[] get(Key from, Key till) {
return extend(index.get(from, till));
}
public IPersistent[] get(Object from, Object till) {
return extend(index.get(from, till));
}
private ArrayList<T> extendList(ArrayList s) {
ArrayList<T> list = new ArrayList<T>();
for (int i = 0, n = s.size(); i < n; i++) {
list.addAll((Collection<T>)s.get(i));
}
return list;
}
private IPersistent[] extend( IPersistent[] s) {
ArrayList list = new ArrayList();
for (int i = 0; i < s.length; i++) {
list.addAll((Collection)s[i]);
}
return (IPersistent[])list.toArray(new IPersistent[list.size()]);
}
public T get(String key) {
return get(new Key(key));
}
public IPersistent[] getPrefix(String prefix) {
return extend(index.getPrefix(prefix));
}
public ArrayList<T> getPrefixList(String prefix) {
return extendList(index.getPrefixList(prefix));
}
public IPersistent[] prefixSearch(String word) {
return extend(index.prefixSearch(word));
}
public ArrayList<T> prefixSearchList(String word) {
return extendList(index.prefixSearchList(word));
}
public int size() {
return nElems;
}
public void clear() {
for (IPersistent p : index) {
p.deallocate();
}
index.clear();
nElems = 0;
modify();
}
public IPersistent[] toPersistentArray() {
return extend(index.toPersistentArray());
}
public Object[] toArray() {
return toPersistentArray();
}
public <E> E[] toArray(E[] arr) {
ArrayList<E> list = new ArrayList<E>();
for (IPersistent c : index) {
list.addAll((Collection<E>)c);
}
return list.toArray(arr);
}
static class ExtendIterator<E extends IPersistent> extends IterableIterator<E> implements PersistentIterator {
public boolean hasNext() {
return inner != null;
}
public E next() {
E obj = inner.next();
if (!inner.hasNext()) {
if (outer.hasNext()) {
inner = ((Iterable<E>)outer.next()).iterator();
} else {
inner = null;
}
}
return obj;
}
public int nextOid() {
int oid = ((PersistentIterator)inner).nextOid();
if (!inner.hasNext()) {
if (outer.hasNext()) {
Object p = outer.next();
inner = ((Iterable<E>)outer.next()).iterator();
} else {
inner = null;
}
}
return oid;
}
public void remove() {
throw new UnsupportedOperationException();
}
ExtendIterator(IterableIterator<?> iterable) {
this(iterable.iterator());
}
ExtendIterator(Iterator<?> iterator) {
outer = iterator;
if (iterator.hasNext()) {
inner = ((Iterable<E>)iterator.next()).iterator();
}
}
private Iterator outer;
private Iterator<E> inner;
}
static class ExtendEntry<E extends IPersistent> implements Map.Entry<Object,E> {
public Object getKey() {
return key;
}
public E getValue() {
return value;
}
public E setValue(E value) {
throw new UnsupportedOperationException();
}
ExtendEntry(Object key, E value) {
this.key = key;
this.value = value;
}
private Object key;
private E value;
}
static class ExtendEntryIterator<E extends IPersistent> extends IterableIterator<Map.Entry<Object,E>> {
public boolean hasNext() {
return inner != null;
}
public Map.Entry<Object,E> next() {
ExtendEntry<E> curr = new ExtendEntry<E>(key, inner.next());
if (!inner.hasNext()) {
if (outer.hasNext()) {
Map.Entry entry = (Map.Entry)outer.next();
key = entry.getKey();
inner = ((Iterable<E>)entry.getValue()).iterator();
} else {
inner = null;
}
}
return curr;
}
public void remove() {
throw new UnsupportedOperationException();
}
ExtendEntryIterator(IterableIterator<?> iterator) {
outer = iterator;
if (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
key = entry.getKey();
inner = ((Iterable<E>)entry.getValue()).iterator();
}
}
private Iterator outer;
private Iterator<E> inner;
private Object key;
}
class ExtendEntryStartFromIterator extends ExtendEntryIterator<T> {
ExtendEntryStartFromIterator(int start, int order) {
super(entryIterator(null, null, order));
int skip = (order == ASCENT_ORDER) ? start : nElems - start - 1;
while (--skip >= 0 && hasNext()) {
next();
}
}
}
public Iterator<T> iterator() {
return new ExtendIterator<T>(index.iterator());
}
public IterableIterator<Map.Entry<Object,T>> entryIterator() {
return new ExtendEntryIterator<T>(index.entryIterator());
}
public IterableIterator<T> iterator(Key from, Key till, int order) {
return new ExtendIterator<T>(index.iterator(from, till, order));
}
public IterableIterator<T> iterator(Object from, Object till, int order) {
return new ExtendIterator<T>(index.iterator(from, till, order));
}
public IterableIterator<Map.Entry<Object,T>> entryIterator(Key from, Key till, int order) {
return new ExtendEntryIterator<T>(index.entryIterator(from, till, order));
}
public IterableIterator<Map.Entry<Object,T>> entryIterator(Object from, Object till, int order) {
return new ExtendEntryIterator<T>(index.entryIterator(from, till, order));
}
public IterableIterator<T> prefixIterator(String prefix) {
return new ExtendIterator<T>(index.prefixIterator(prefix));
}
public Class getKeyType() {
return index.getKeyType();
}
public Class[] getKeyTypes() {
return new Class[]{getKeyType()};
}
public boolean put(Key key, T obj) {
IPersistent s = index.get(key);
if (s == null) {
Relation<T,ThickIndex> r = getStorage().<T,ThickIndex>createRelation(null);
r.add(obj);
index.put(key, r);
} else if (s instanceof Relation) {
Relation r = (Relation)s;
if (r.size() == BTREE_THRESHOLD) {
IPersistentSet<T> ps = getStorage().<T>createSet();
for (int i = 0; i < BTREE_THRESHOLD; i++) {
ps.add((T)r.get(i));
}
ps.add(obj);
index.set(key, ps);
r.deallocate();
} else {
r.add(obj);
}
} else {
((IPersistentSet<T>)s).add(obj);
}
nElems += 1;
modify();
return true;
}
public T set(Key key, T obj) {
IPersistent s = index.get(key);
if (s == null) {
Relation<T,ThickIndex> r = getStorage().<T,ThickIndex>createRelation(null);
r.add(obj);
index.put(key, r);
nElems += 1;
modify();
return null;
} else if (s instanceof Relation) {
Relation r = (Relation)s;
if (r.size() == 1) {
IPersistent prev = r.get(0);
r.set(0, obj);
return (T)prev;
}
}
throw new StorageError(StorageError.KEY_NOT_UNIQUE);
}
public void remove(Key key, T obj) {
IPersistent s = index.get(key);
if (s instanceof Relation) {
Relation r = (Relation)s;
int i = r.indexOf(obj);
if (i >= 0) {
r.remove(i);
if (r.size() == 0) {
index.remove(key, r);
r.deallocate();
}
nElems -= 1;
modify();
return;
}
} else if (s instanceof IPersistentSet) {
IPersistentSet ps = (IPersistentSet)s;
if (ps.remove(obj)) {
if (ps.size() == 0) {
index.remove(key, ps);
ps.deallocate();
}
nElems -= 1;
modify();
return;
}
}
throw new StorageError(StorageError.KEY_NOT_FOUND);
}
public T remove(Key key) {
throw new StorageError(StorageError.KEY_NOT_UNIQUE);
}
public boolean put(Object key, T obj) {
return put(Btree.getKeyFromObject(key), obj);
}
public T set(Object key, T obj) {
return set(Btree.getKeyFromObject(key), obj);
}
public void remove(Object key, T obj) {
remove(Btree.getKeyFromObject(key), obj);
}
public T remove(String key) {
throw new StorageError(StorageError.KEY_NOT_UNIQUE);
}
public T removeKey(Object key) {
throw new StorageError(StorageError.KEY_NOT_UNIQUE);
}
public void deallocate() {
clear();
index.deallocate();
super.deallocate();
}
public T getAt(int i) {
IterableIterator<Map.Entry<Object,T>> iterator;
if (i < 0 || i >= nElems) {
throw new IndexOutOfBoundsException("Position " + i + ", index size " + nElems);
}
if (i <= (nElems/2)) {
iterator = entryIterator(null, null, ASCENT_ORDER);
while (--i >= 0) {
iterator.next();
}
} else {
iterator = entryIterator(null, null, DESCENT_ORDER);
i -= nElems;
while (++i < 0) {
iterator.next();
}
}
return iterator.next().getValue();
}
public IterableIterator<Map.Entry<Object,T>> entryIterator(int start, int order) {
return new ExtendEntryStartFromIterator(start, order);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -