/*
* Copyright (C) 2006 http://www.chaidb.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
package org.chaidb.db.index.btree;
import org.apache.log4j.Logger;
import org.chaidb.db.KernelContext;
import org.chaidb.db.api.keys.NodeId;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.index.IDBIndex;
import org.chaidb.db.index.IDummyKeyBTree;
import org.chaidb.db.index.Key;
import org.chaidb.db.index.NodeIdConverter;
import org.chaidb.db.lock.LockManager;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
/**
* Path BTree specially for Path UDI
* The new added path btree focus on such aspects:
* 1. Simplify disk storage structure of original super btree
* 2. Based on this simple storage, try to support better concurrency
* 3. Support basic interface requirement from UDIndex, and meet not bad performance , especially for lookup
* 4. Low inflation ratio
* User: arefool
* Date: Mar 19, 2003
* Time: 1:29:20 PM
*/
public class PathBTree extends AbstractBTree implements IDummyKeyBTree {
private static final Logger logger = Logger.getLogger(PathBTree.class);
/**
* Sets the key size.
*
* @param keySize The key size.
*/
public void setKeySize(int keySize) {
}
/**
* returns the index type of this index
*
* @return A short integer representing the index type
*/
public short getType() {
return IDBIndex.PATH_BTREE;
}
protected AbstractBTree GenerateClonedBTree() throws ChaiDBException {
return new PathBTree();
}
protected void copyData(AbstractBTree newBTree, KernelContext kContext) throws ChaiDBException {
try {
this.acquire(kContext, LockManager.LOCK_READ);
newBTree.acquire(kContext, LockManager.LOCK_WRITE);
newBTree.setConverter(new NodeIdConverter());
Enumeration keys = keys(kContext);
if (keys == null) return;
while (keys.hasMoreElements()) {
Key key = (Key) keys.nextElement();
((PathBTree) newBTree).store(key, kContext);
}
} finally {
newBTree.release(kContext);
this.release(kContext);
}
}
/**
* Insert a value with dummy key, if there has existed same value, it will replace old value directly,
* otherwise, it will be stored.
*
* @param keyValue
* @param kContext
* @throws ChaiDBException
*/
public void store(Key keyValue, KernelContext kContext) throws ChaiDBException {
store(keyValue, keyValue, IDBIndex.STORE_INSERT, kContext);
}
public int delete(int docid, KernelContext kContext) throws ChaiDBException {
kContext.checkLock(getBTreeName());
ArrayList deleteNodes = new ArrayList();
this.getBTreeSpec().setModified(true);
try {
Enumeration enuKeys = keys(kContext);
while (enuKeys.hasMoreElements()) {
NodeId nodeid = (NodeId) enuKeys.nextElement();
if (nodeid.getDocId() == docid) {
deleteNodes.add(nodeid);
}
}//end while
int ret = 0;
Iterator itDeleteNodes = deleteNodes.iterator();
while (itDeleteNodes.hasNext()) {
NodeId nodeid = (NodeId) itDeleteNodes.next();
if (delete(nodeid, kContext)) {
ret++;
}
}
return ret;
} finally {
}
}
/**
* returns enumeration of keys.
*
* @return Enumeration of keys
*/
public Enumeration keys(KernelContext kContext) {
PathBTreeEnumerator pbEnum = null;
for (int i = 0; i < 3; i++) {
try {
kContext.checkLock(getBTreeName());
pbEnum = new PathBTreeEnumerator(this, btreeSpec, buffer, kContext);
} catch (ChaiDBException e) {
if (i == 2) {
logger.error(e);
return null;
} else {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
;
}
continue;
}
}
break;
}//end for
return pbEnum;
}
}