📄 rndbtree.java
字号:
private BtreePage pg;
private int pos;
}
public Iterator iterator() {
return iterator(null, null, ASCENT_ORDER);
}
public Iterator entryIterator() {
return entryIterator(null, null, ASCENT_ORDER);
}
class BtreeSelectionIterator implements PersistentIterator {
BtreeSelectionIterator(Key from, Key till, int order) {
this.from = from;
this.till = till;
this.order = order;
reset();
}
BtreeSelectionIterator(int order) {
this.order = order;
}
void reset() {
int i, l, r;
sp = 0;
counter = updateCounter;
if (height == 0) {
return;
}
BtreePage page = root;
int h = height;
pageStack = new BtreePage[h];
posStack = new int[h];
if (order == ASCENT_ORDER) {
if (from == null) {
while (--h > 0) {
posStack[sp] = 0;
pageStack[sp] = page;
page = (BtreePage)page.items.get(0);
sp += 1;
}
posStack[sp] = 0;
pageStack[sp] = page;
end = page.nItems;
sp += 1;
} else {
while (--h > 0) {
pageStack[sp] = page;
l = 0;
r = page.nItems;
while (l < r) {
i = (l+r) >> 1;
if (page.compare(from, i) >= from.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
posStack[sp] = r;
page = (BtreePage)page.items.get(r);
sp += 1;
}
pageStack[sp] = page;
l = 0;
r = end = page.nItems;
while (l < r) {
i = (l+r) >> 1;
if (page.compare(from, i) >= from.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
if (r == end) {
sp += 1;
gotoNextItem(page, r-1);
} else {
posStack[sp++] = r;
}
}
if (sp != 0 && till != null) {
page = pageStack[sp-1];
if (-page.compare(till, posStack[sp-1]) >= till.inclusion) {
sp = 0;
}
}
} else { // descent order
if (till == null) {
while (--h > 0) {
pageStack[sp] = page;
posStack[sp] = page.nItems;
page = (BtreePage)page.items.get(page.nItems);
sp += 1;
}
pageStack[sp] = page;
posStack[sp++] = page.nItems-1;
} else {
while (--h > 0) {
pageStack[sp] = page;
l = 0;
r = page.nItems;
while (l < r) {
i = (l+r) >> 1;
if (page.compare(till, i) >= 1-till.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
posStack[sp] = r;
page = (BtreePage)page.items.get(r);
sp += 1;
}
pageStack[sp] = page;
l = 0;
r = page.nItems;
while (l < r) {
i = (l+r) >> 1;
if (page.compare(till, i) >= 1-till.inclusion) {
l = i + 1;
} else {
r = i;
}
}
Assert.that(r == l);
if (r == 0) {
sp += 1;
gotoNextItem(page, r);
} else {
posStack[sp++] = r-1;
}
}
if (sp != 0 && from != null) {
page = pageStack[sp-1];
if (page.compare(from, posStack[sp-1]) >= from.inclusion) {
sp = 0;
}
}
}
}
public boolean hasNext() {
if (counter != updateCounter) {
if (((StorageImpl)getStorage()).concurrentIterator) {
refresh();
} else {
throw new ConcurrentModificationException();
}
}
return sp != 0;
}
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int pos = posStack[sp-1];
BtreePage pg = pageStack[sp-1];
currPos = pos;
currPage = pg;
Object curr = getCurrent(pg, pos);
if (((StorageImpl)getStorage()).concurrentIterator) {
currKey = new BtreeKey(pg.getKey(pos), pg.items.getRaw(pos));
}
gotoNextItem(pg, pos);
return curr;
}
public int nextOid() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int pos = posStack[sp-1];
BtreePage pg = pageStack[sp-1];
currPos = pos;
currPage = pg;
int oid = pg.items.getRaw(pos).getOid();
if (((StorageImpl)getStorage()).concurrentIterator) {
currKey = new BtreeKey(pg.getKey(pos), pg.items.getRaw(pos));
}
gotoNextItem(pg, pos);
return oid;
}
protected Object getCurrent(BtreePage pg, int pos) {
return pg.items.get(pos);
}
protected final void gotoNextItem(BtreePage pg, int pos)
{
if (order == ASCENT_ORDER) {
if (++pos == end) {
while (--sp != 0) {
pos = posStack[sp-1];
pg = pageStack[sp-1];
if (++pos <= pg.nItems) {
posStack[sp-1] = pos;
do {
pg = (BtreePage)pg.items.get(pos);
end = pg.nItems;
pageStack[sp] = pg;
posStack[sp] = pos = 0;
} while (++sp < pageStack.length);
break;
}
}
} else {
posStack[sp-1] = pos;
}
if (sp != 0 && till != null && -pg.compare(till, pos) >= till.inclusion) {
sp = 0;
}
} else { // descent order
if (--pos < 0) {
while (--sp != 0) {
pos = posStack[sp-1];
pg = pageStack[sp-1];
if (--pos >= 0) {
posStack[sp-1] = pos;
do {
pg = (BtreePage)pg.items.get(pos);
pageStack[sp] = pg;
posStack[sp] = pos = pg.nItems;
} while (++sp < pageStack.length);
posStack[sp-1] = --pos;
break;
}
}
} else {
posStack[sp-1] = pos;
}
if (sp != 0 && from != null && pg.compare(from, pos) >= from.inclusion) {
sp = 0;
}
}
if (((StorageImpl)getStorage()).concurrentIterator && sp != 0) {
nextKey = pg.getKey(pos);
nextObj = pg.items.getRaw(pos);
}
}
private void refresh() {
if (sp != 0) {
if (nextKey == null) {
reset();
} else {
if (order == ASCENT_ORDER) {
from = nextKey;
} else {
till = nextKey;
}
IPersistent next = nextObj;
reset();
while (true) {
int pos = posStack[sp-1];
BtreePage pg = pageStack[sp-1];
if (!pg.items.getRaw(pos).equals(next)) {
gotoNextItem(pg, pos);
} else {
break;
}
}
}
}
counter = updateCounter;
}
public void remove() {
if (currPage == null) {
throw new NoSuchElementException();
}
StorageImpl db = (StorageImpl)getStorage();
if (!db.concurrentIterator) {
if (counter != updateCounter) {
throw new ConcurrentModificationException();
}
currKey = new BtreeKey(currPage.getKey(currPos), currPage.items.getRaw(currPos));
if (sp != 0) {
int pos = posStack[sp-1];
BtreePage pg = pageStack[sp-1];
nextKey = pg.getKey(pos);
nextObj = pg.items.getRaw(pos);
}
}
RndBtree.this.removeIfExists(currKey);
refresh();
currPage = null;
}
BtreePage[] pageStack;
int[] posStack;
BtreePage currPage;
int currPos;
int sp;
int end;
Key from;
Key till;
int order;
int counter;
Key nextKey;
BtreeKey currKey;
IPersistent nextObj;
}
class BtreeSelectionEntryIterator extends BtreeSelectionIterator {
BtreeSelectionEntryIterator(Key from, Key till, int order) {
super(from, till, order);
}
BtreeSelectionEntryIterator(int order) {
super(order);
}
protected Object getCurrent(BtreePage pg, int pos) {
return new BtreeEntry(pg, pos);
}
}
class BtreeEntryStartFromIterator extends BtreeSelectionEntryIterator
{
BtreeEntryStartFromIterator(int start, int order) {
super(order);
this.start = start;
reset();
}
void reset() {
sp = 0;
counter = updateCounter;
if (height == 0 || start >= nElems) {
return;
}
BtreePage page = root;
int h = height;
int i = start;
pageStack = new BtreePage[h];
posStack = new int[h];
while (--h > 0) {
pageStack[sp] = page;
int j;
for (j = 0; i >= page.nChildren[j]; j++) {
i -= page.nChildren[j];
}
posStack[sp] = j;
page = (BtreePage) page.items.get(j);
sp += 1;
}
pageStack[sp] = page;
posStack[sp++] = i;
end = page.nItems;
}
int start;
}
public Iterator iterator(Key from, Key till, int order) {
return new BtreeSelectionIterator(checkKey(from), checkKey(till), order);
}
public Iterator prefixIterator(String prefix) {
return iterator(new Key(prefix), new Key(prefix + Character.MAX_VALUE, false), ASCENT_ORDER);
}
public Iterator entryIterator(Key from, Key till, int order) {
return new BtreeSelectionEntryIterator(checkKey(from), checkKey(till), order);
}
public Iterator select(Class cls, String predicate) {
Query query = new QueryImpl(getStorage());
return query.select(cls, iterator(), predicate);
}
public Object getAt(int i) {
if (i < 0 || i >= nElems) {
throw new IndexOutOfBoundsException("Position " + i + ", index size " + nElems);
}
return root.getAt(i, height);
}
public Iterator entryIterator(int start, int order) {
return new BtreeEntryStartFromIterator(start, order);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -