📄 btree.java
字号:
public T set(Object key, T obj) {
return set(getKeyFromObject(key), obj);
}
public void remove(Object key, T obj) {
remove(getKeyFromObject(key), obj);
}
public T removeKey(Object key) {
return remove(getKeyFromObject(key));
}
public T remove(String key) {
return remove(new Key(key));
}
public int size() {
return nElems;
}
public void clear() {
if (root != 0) {
BtreePage.purge((StorageImpl)getStorage(), root, type, height);
root = 0;
nElems = 0;
height = 0;
updateCounter += 1;
modify();
}
}
public IPersistent[] toPersistentArray() {
IPersistent[] arr = new IPersistent[nElems];
if (root != 0) {
BtreePage.traverseForward((StorageImpl)getStorage(), root, type, height, arr, 0);
}
return arr;
}
public Object[] toArray() {
return toPersistentArray();
}
public <E> E[] toArray(E[] arr) {
if (arr.length < nElems) {
arr = (E[])Array.newInstance(arr.getClass().getComponentType(), nElems);
}
if (root != 0) {
BtreePage.traverseForward((StorageImpl)getStorage(), root, type, height, (IPersistent[])arr, 0);
}
if (arr.length > nElems) {
arr[nElems] = null;
}
return arr;
}
public void deallocate() {
if (root != 0) {
BtreePage.purge((StorageImpl)getStorage(), root, type, height);
}
super.deallocate();
}
public int markTree()
{
if (root != 0) {
return BtreePage.markPage((StorageImpl)getStorage(), root, type, height);
}
return 0;
}
protected Object unpackEnum(int val)
{
// Base B-Tree class has no information about particular enum type
// so it is not able to correctly unpack enum key
return (Object)val;
}
public void export(XMLExporter exporter) throws java.io.IOException
{
if (root != 0) {
BtreePage.exportPage((StorageImpl)getStorage(), exporter, root, type, height);
}
}
static class BtreeEntry<T> implements Map.Entry<Object,T> {
public Object getKey() {
return key;
}
public T getValue() {
return (T)db.lookupObject(oid, null);
}
public T setValue(T value) {
throw new UnsupportedOperationException();
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry e = (Map.Entry)o;
return (getKey() == null ? e.getKey() == null : getKey().equals(e.getKey()))
&& (getValue() == null ? e.getValue() == null : getValue().equals(e.getValue()));
}
public int hashCode() {
return ((getKey() == null) ? 0 : getKey().hashCode()) ^
((getValue() == null) ? 0 : getValue().hashCode());
}
public String toString() {
return getKey() + "=" + getValue();
}
BtreeEntry(StorageImpl db, Object key, int oid) {
this.db = db;
this.key = key;
this.oid = oid;
}
private Object key;
private StorageImpl db;
private int oid;
}
Object unpackKey(StorageImpl db, Page pg, int pos) {
byte[] data = pg.data;
int offs = BtreePage.firstKeyOffs + pos*ClassDescriptor.sizeof[type];
switch (type) {
case ClassDescriptor.tpBoolean:
return Boolean.valueOf(data[offs] != 0);
case ClassDescriptor.tpByte:
return new Byte(data[offs]);
case ClassDescriptor.tpShort:
return new Short(Bytes.unpack2(data, offs));
case ClassDescriptor.tpChar:
return new Character((char)Bytes.unpack2(data, offs));
case ClassDescriptor.tpInt:
return new Integer(Bytes.unpack4(data, offs));
case ClassDescriptor.tpObject:
return db.lookupObject(Bytes.unpack4(data, offs), null);
case ClassDescriptor.tpLong:
return new Long(Bytes.unpack8(data, offs));
case ClassDescriptor.tpDate:
return new Date(Bytes.unpack8(data, offs));
case ClassDescriptor.tpFloat:
return new Float(Float.intBitsToFloat(Bytes.unpack4(data, offs)));
case ClassDescriptor.tpDouble:
return new Double(Double.longBitsToDouble(Bytes.unpack8(data, offs)));
case ClassDescriptor.tpEnum:
return unpackEnum(Bytes.unpack4(data, offs));
case ClassDescriptor.tpString:
return unpackStrKey(pg, pos);
case ClassDescriptor.tpArrayOfByte:
return unpackByteArrayKey(pg, pos);
default:
Assert.failed("Invalid type");
}
return null;
}
static String unpackStrKey(Page pg, int pos) {
int len = BtreePage.getKeyStrSize(pg, pos);
int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
byte[] data = pg.data;
char[] sval = new char[len];
for (int j = 0; j < len; j++) {
sval[j] = (char)Bytes.unpack2(data, offs);
offs += 2;
}
return new String(sval);
}
Object unpackByteArrayKey(Page pg, int pos) {
int len = BtreePage.getKeyStrSize(pg, pos);
int offs = BtreePage.firstKeyOffs + BtreePage.getKeyStrOffs(pg, pos);
byte[] val = new byte[len];
System.arraycopy(pg.data, offs, val, 0, len);
return val;
}
public Iterator<T> iterator() {
return iterator(null, null, ASCENT_ORDER);
}
public IterableIterator<Map.Entry<Object,T>> entryIterator() {
return entryIterator(null, null, ASCENT_ORDER);
}
final int compareByteArrays(Key key, Page pg, int i) {
return compareByteArrays((byte[])key.oval,
pg.data,
BtreePage.getKeyStrOffs(pg, i) + BtreePage.firstKeyOffs,
BtreePage.getKeyStrSize(pg, i));
}
class BtreeSelectionIterator<E> extends IterableIterator<E> implements PersistentIterator {
BtreeSelectionIterator(Key from, Key till, int order) {
this.from = from;
this.till = till;
this.order = order;
reset();
}
void reset() {
int i, l, r;
sp = 0;
counter = updateCounter;
if (height == 0) {
return;
}
int pageId = root;
StorageImpl db = (StorageImpl)getStorage();
if (db == null) {
throw new StorageError(StorageError.DELETED_OBJECT);
}
int h = height;
pageStack = new int[h];
posStack = new int[h];
if (type == ClassDescriptor.tpString) {
if (order == ASCENT_ORDER) {
if (from == null) {
while (--h >= 0) {
posStack[sp] = 0;
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
pageId = BtreePage.getKeyStrOid(pg, 0);
end = BtreePage.getnItems(pg);
db.pool.unfix(pg);
sp += 1;
}
} else {
while (--h > 0) {
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r) {
i = (l+r) >> 1;
if (BtreePage.compareStr(from, pg, i) >= from.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
posStack[sp] = r;
pageId = BtreePage.getKeyStrOid(pg, r);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
l = 0;
end = r = BtreePage.getnItems(pg);
while (l < r) {
i = (l+r) >> 1;
if (BtreePage.compareStr(from, pg, i) >= from.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
if (r == end) {
sp += 1;
gotoNextItem(pg, r-1);
} else {
posStack[sp++] = r;
db.pool.unfix(pg);
}
}
if (sp != 0 && till != null) {
Page pg = db.getPage(pageStack[sp-1]);
if (-BtreePage.compareStr(till, pg, posStack[sp-1]) >= till.inclusion) {
sp = 0;
}
db.pool.unfix(pg);
}
} else { // descent order
if (till == null) {
while (--h > 0) {
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
posStack[sp] = BtreePage.getnItems(pg);
pageId = BtreePage.getKeyStrOid(pg, posStack[sp]);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
posStack[sp++] = BtreePage.getnItems(pg)-1;
db.pool.unfix(pg);
} else {
while (--h > 0) {
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r) {
i = (l+r) >> 1;
if (BtreePage.compareStr(till, pg, i) >= 1-till.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
posStack[sp] = r;
pageId = BtreePage.getKeyStrOid(pg, r);
db.pool.unfix(pg);
sp += 1;
}
pageStack[sp] = pageId;
Page pg = db.getPage(pageId);
l = 0;
r = BtreePage.getnItems(pg);
while (l < r) {
i = (l+r) >> 1;
if (BtreePage.compareStr(till, pg, i) >= 1-till.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -