/*
* 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.bufmgr;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.exception.ErrorCode;
/**
* (file number,page number) reference one page in storagespace.
*/
public class PageNumber {
private int treeid; //not store in a file
private int fileNumber;
private int pageinfile;
private static final int MAX_FILE_NUMBER = 0x7f;//127
private static final int MAX_FILESIZE_IN_PAGE = Storage.MAX_FILESIZE_IN_PAGE;
private static PageBufferManager bpm = PageBufferManager.getInstance();
/**
* Constructor
*/
public PageNumber() {
}
public PageNumber(int tid, int fno, int pno) {
if (fno >= 0) fileNumber = fno & MAX_FILE_NUMBER;
pageinfile = (pno >= 0) ? pno & 0xffffff : -1;
treeid = (tid >= 0) ? tid : -1;
}
public PageNumber(int pagenumber) {
setPageNumber(pagenumber);
}
public PageNumber(PageNumber p) {
treeid = p.getTreeId();
fileNumber = p.getFileNumber();
pageinfile = p.getPageInFile();
}
public void setPageNumber(int pn) {
if (pn >= 0) {
fileNumber = (pn >> 24) & MAX_FILE_NUMBER;
pageinfile = pn & 0xffffff;
} else {
pageinfile = -1;
}
}
public void setPageNumber(PageNumber pn) {
this.treeid = pn.getTreeId();
this.fileNumber = pn.getFileNumber();
this.pageinfile = pn.getPageInFile();
}
public int getPageNumber() {
if (fileNumber >= 0 && pageinfile >= 0) return ((fileNumber << 24) & 0xff000000 | (pageinfile & 0xffffff));
else return -1;
}
public int getFileNumber() {
return fileNumber;
}
public int getPageInFile() {
return pageinfile;
}
public void add(int inc) throws ChaiDBException {
pageinfile += inc;
if (MAX_FILESIZE_IN_PAGE > 0 && pageinfile >= MAX_FILESIZE_IN_PAGE) {
fileNumber += pageinfile / MAX_FILESIZE_IN_PAGE;
pageinfile = pageinfile % MAX_FILESIZE_IN_PAGE + 1;
if (fileNumber >= MAX_FILE_NUMBER + 1) {
// details -ranjeet
String details = "Reached the file number limit of 127.";
throw new ChaiDBException(ErrorCode.BTREE_FILENUMBER_OVERFLOW, details);
}
}
}
/**
* add by Stanley
* 2005-07-09
* skip the pageNo left and jump to the next fileNo when there is a file whose name is filename + filenumber;
*
* @throws ChaiDBException
*/
public void jumpToNextFile() throws ChaiDBException {
if (pageinfile > 1) {
pageinfile = 1;
fileNumber++;
}
if (fileNumber >= MAX_FILE_NUMBER + 1) {
// details -ranjeet
String details = "Reached the file number limit of 127.";
throw new ChaiDBException(ErrorCode.BTREE_FILENUMBER_OVERFLOW, details);
}
}
public int getTreeId() {
return treeid;
}
public void setTreeId(int id) {
treeid = id;
}
public boolean equ(PageNumber p) {
return ((treeid == p.treeid) && (fileNumber == p.fileNumber) && (pageinfile == p.pageinfile));
}
/**
* hash code of pageNumber. This is as same as Long.hashCode.
*/
public int hashCode() {
return (fileNumber << 24 | pageinfile) ^ treeid;
}
public String toString() {
return new StringBuffer().append(treeid).append("-").append(fileNumber).append("-").append(pageinfile).toString();
}
/**
* get the unique id of a page
*/
public long uniqueID() throws ChaiDBException {
String btree = bpm.getBTreeName(treeid);
return ((((long) btree.hashCode() & 0xffffffff) << 32) & 0xffffffff00000000L) | ((((long) fileNumber & MAX_FILE_NUMBER) << 24) & 0xff000000) | (((long) pageinfile) & 0xffffff);
}
public boolean equals(Object obj) {
if (obj instanceof PageNumber) return this.equ((PageNumber) obj);
else return false;
}
public String toHexString() {
return "0x" + Integer.toHexString(treeid) + "-" + Integer.toHexString(fileNumber) + "-" + Integer.toHexString(pageinfile);
}
/**
* Just for test.
* @param args
*/
/*
public static void main(String args[]){
PageNumber pgno = new PageNumber(0x22, 1, 2);
System.out.println(pgno.getPageNumber());
//index= (high 7 bits | file number <<7) & 0xfff
//then it must be lower than 0x1000 (4096).
int index = pgno.getPageInFile() >> 12; // index = pgno / 4096
index |= pgno.getFileNumber() << 7;
index &= 0xfff; //index %= 4096
}
*/
}