public final class LongTree implements Cacheable {
//使用这三个数组存放数据 已经数据关系
//我们把要我们自己的数据ID放入数组keys中,leftChildren和rightSiblings是记录数组keys的数组ID之间关系
//leftChildren放置的是儿子 rightSiblings存放的是其兄弟(并列的〕
long [] keys;
//char arrays let us address get about 65K nodes.
char [] leftChildren;
char [] rightSiblings;
// Pointer to next available slot.
char nextIndex = 2;
/**
* 构造一个新的Tree只要提供两个参数:根数据ID 和 Tree结构的大小
*/
public LongTree(long rootKey, int size) {
keys = new long[size+1];
leftChildren = new char[size+1];
rightSiblings = new char[size+1];
//新Tree,第一个元素当然存放我们提供的参数:根数据ID :rootKey
// New tree, so set the fields to null at root.
keys[1] = rootKey;
leftChildren[1] = 0;
rightSiblings[1] = 0;
}
/**
* Adds a child to the tree.
*
* @param parentKey 将新的儿子加入哪个父亲下面,所以需要提供父亲的数据ID
* @param newKey 新的儿子本身的数据ID
*/
public void addChild(long parentKey, long newKey) {
// Find record for parent 检查提供的父亲是否存在
char parentIndex = findKey(parentKey, (char)1);
if (parentIndex == 0) {
throw new IllegalArgumentException("Parent key " + parentKey +
" not found when adding child " + newKey + ".");
}
// Create record for new key.加入数组 前后关系暂时设定为0
keys[nextIndex] = newKey;
leftChildren[nextIndex] = 0;
rightSiblings[nextIndex] = 0;
// Adjust references. Check to see if the parent has any children.
if (leftChildren[parentIndex] == 0) {
// No children, therefore make the new key the first child.
leftChildren[parentIndex] = nextIndex;
}
else {
// The parent has children, so find the right-most child.
//如果这个父亲有儿子了,那么找出其最右边的儿子,类似上图的 6
//这样是为了将新的儿子追加在其后面,或者说最最右边
long siblingIndex = leftChildren[parentIndex];
while (rightSiblings[new Long(siblingIndex).intValue()] != 0) {
siblingIndex = rightSiblings[new Long(siblingIndex).intValue()];
}
// Add the new entry as a sibling of that last child.
rightSiblings[new Long(siblingIndex).intValue()] = nextIndex;
}
// Finally, increment nextIndex so it's ready for next add.
nextIndex++;
}
CREATE TABLE jiveMessage (
messageID BIGINT NOT NULL,
parentMessageID BIGINT NULL, #记录当前帖子的父亲
threadID BIGINT NOT NULL, #当前帖子的threadID 就是目录ID
forumID BIGINT NOT NULL,
userID BIGINT NULL,
subject VARCHAR(255),
body TEXT,
....
)
我们看到其数据库主要用两个字段来指明这种树形结构数据的之间的关系。
再看看DbTreeWalker是怎么使用LongTree把存放在这个数据库中数据展现开来的。
public class DbTreeWalker implements TreeWalker {
/** DATABASE QUERIES SQL 语句**/
private static final String GET_MESSAGES =
"SELECT messageID, parentMessageID, creationDate FROM jiveMessage " +
"WHERE threadID=? AND parentMessageID IS NOT NULL " +
"ORDER BY creationDate ASC";
........
private long threadID;
private DbForumFactory factory;
//这里设置使用LongTree准备生成一个对象
private LongTree tree;