findFirst() {
- Page currentPage = this.pageStorage.get(rootNum);
- //pin
- currentPage.pin();
- long nextPageNum = 0;
- while (getPageType(currentPage) != PageType.LEAF) {
- nextPageNum = getMinChild(currentPage);
- //unpin
- currentPage.unpin();
- currentPage = this.pageStorage.get(nextPageNum);
- //pin
- currentPage.pin();
- }
- Iterator res= new BPlusTreeIterator(this,currentPage, 0);
- currentPage.unpin();
- return res;
- }
-
- /**
- * 用于Internal节点找到最小的儿子,服务于findFirst()
- * @param page 儿子的页号
- * @return
- */
- private long getMinChild(Page page) {
- return ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),BPlusTreeIndex.PAGE_BEGIN_POSTION + 8,8));
- }
-
- /**
- * LEAF节点的指定key的最前面的位置,服务于findFirst(dataHash)
- * @return key的位置
- */
- private int queryKeyPos(Page page, long key) throws ItemInNextPageException {
- if ( key > getMaxKey(page) ) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
- while (i < j) {
- if (getKeyByPosition(page, temp) > key){
- j = temp;
- }else if (getKeyByPosition(page, temp) < key){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- while (temp > 0 && getKeyByPosition(page, temp-1) >= key){
- temp--;
- }
- return temp;
- }
-
- /**
- * LEAF节点的指定大于key的最前面的位置,服务于findUpperbound(dataHash)
- * @param page
- * @param key
- * @return
- */
- private int queryUpperboundKeyPos(Page page, long key) throws ItemInNextPageException {
- if ( key >= getMaxKey(page) ) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
- while (i < j) {
- if (getKeyByPosition(page, temp) > key){
- j = temp;
- }else if (getKeyByPosition(page, temp) < key){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- while (temp < itemNum - 1){
- if (getKeyByPosition(page, temp) > key) {
- break;
- }
- temp++;
- }
- return temp;
- }
-
- /**
- * 获取一个新页,并元页总页数自动加一
- * @return 新页的页号
- * @throws PageTypeException
- */
- private long getRawPageNum() {
- Page page = this.pageStorage.get(0);
- //pin
- page.pin();
- if (getPageType(page) != PageType.META) {
- try {
- throw new PageTypeException(2);
- } catch (PageTypeException e) {
- //unpin
- page.unpin();
- e.printStackTrace();
- throw new RuntimeException();
- }
- }
- long res = ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),4,8));
- byte[] bs = ByteUtil.long2Bytes(res + 1);
- try {
- page.patchData(4,bs);
- } catch (PageException e) {
- e.printStackTrace();
- } finally {
- //unpin
- page.unpin();
- }
- return res;
- }
-
- /**
- * 将根,从LEAF节点变为INTERNAL节点
- * @param minKey 通过minKey初始化根节点
- * @param minPageNum 小于minKey的页的页号
- * @param maxPageNum 大于minKey的页的页号
- */
- private void initRootAsInternal(long minKey, long minPageNum, long maxPageNum) {
- //pin
- Page page = this.pageStorage.get(rootNum);
- page.pin();
- setPageType(page, PageType.INTERNAL);
- setPageItemNum(page, 2);
- setMaxKey(page, Long.MAX_VALUE);
- byte[] inserted;
- try {
- inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(minKey), ByteUtil.long2Bytes(minPageNum));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION,inserted);
- inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(Long.MAX_VALUE), ByteUtil.long2Bytes(maxPageNum));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- } finally {
- //flush
- try {
- page.flush();
- } catch (FileException e) {
- e.printStackTrace();
- }
- //unpin
- page.unpin();
- }
- }
-
- /**
- * 将一个页初始化为根,且为LEAF节点
- */
- private void initRootAsLeaf() {
- //pin
- Page page = this.pageStorage.get(rootNum);
- page.pin();
- setPageType(page, PageType.LEAF);
- setPageItemNum(page, 0);
- setMaxKey(page, Long.MAX_VALUE);
- setPageNextPage(page, 0);
- //flush
- try {
- page.flush();
- } catch (FileException e) {
- e.printStackTrace();
- }
- //unpin
- page.unpin();
- }
-
- /**
- *将internal节点的一个key(如果存在重复的key,指第一个)指向的页面替换成新的子页,同时在该条目前插入新的key.主要服务于于分裂操作
- * 如果满了或要插入的值
- *
- * oldKey - oldPageNum
- * >>>
- * newKey - oldPageNum
- * oldKey - replacePageNum
- *
- * @param page
- * @param oldKey 待替换的key
- * @param replacePageNum 替换的新子页号
- * @param newKey 新插入的key
- * @param oldPageNum 待替换的页号
- * @return
- */
- private void insertInternalItem(Page page, long oldKey, long oldPageNum, long replacePageNum, long newKey) throws PageFullException, ItemInNextPageException {
- if ( oldKey > getMaxKey(page) ) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- if ( itemNum >= BPlusTreeIndex.MAX_PAGE_ITEM ) {
- throw new PageFullException(1);
- }
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
- while (i < j) {
- if (getKeyByPosition(page, temp) > oldKey){
- j = temp;
- }else if (getKeyByPosition(page, temp) < oldKey){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- int low = temp, high = temp + 1;
- boolean isFind = false;
- while (getKeyByPosition(page, low) == oldKey && low >= 0){
- if(getValByPosition(page, low) == oldPageNum) {
- temp = low;
- isFind = true;
- break;
- }
- low--;
- }
- while (getKeyByPosition(page, high) == oldKey && !isFind && high <= (BPlusTreeIndex.MAX_PAGE_ITEM - 1)) {
- if(getValByPosition(page, high) == oldPageNum) {
- temp = high;
- isFind = true;
- break;
- }
- high++;
- }
- if (!isFind) {
- throw new ItemInNextPageException(1,getPageNextPage(page));
- }
-
- try {
- byte[] bytes = ByteUtil.long2Bytes(replacePageNum);
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16 + 8, bytes);
- byte[] bs = new byte[16];
- for (int k = itemNum; k > temp; k--) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_BEGIN_POSTION + (k - 1) * 16 , bs, 0, 16);
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16 ,bs);
- }
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(newKey), ByteUtil.long2Bytes(oldPageNum));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(page, itemNum + 1);
- }
-
- /**
- *将一个满的internal节点的一个key(如果存在重复的key,指第一个)指向的页面替换成新的子页,同时在该条目前插入新的key.主要服务于于分裂操作
- *
- * oldKey - oldPageNum
- * >>>
- * newKey - oldPageNum
- * oldKey - replacePageNum
- *
- * @param page
- * @param newPage
- * @param newPageNum 新页的页号
- * @param oldKey 带替换的key
- * @param oldPageNum 待替换的页号
- * @param replacePageNum 替换的新子页号
- * @param newKey 新插入的key
- * @return 为分裂后新的key
- */
- private long insertFullInternal(Page page, Page newPage, long newPageNum, long oldKey, long oldPageNum, long replacePageNum, long newKey) {
- if ( oldKey > getMaxKey(page)) {
- try {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- } catch (ItemInNextPageException e) {
- e.printStackTrace();
- }
- }
- setPageType(newPage, PageType.INTERNAL);
- setMaxKey(newPage, getMaxKey(page));
- setPageNextPage(newPage, getPageNextPage(page));
- setPageNextPage(page, newPageNum);
- int i = 0,j = BPlusTreeIndex.MAX_PAGE_ITEM;
- int temp = (i + j)/2;
- while (i < j) {
- if (getKeyByPosition(page, temp) > oldKey){
- j = temp;
- }else if (getKeyByPosition(page, temp) < oldKey){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- int low = temp, high = temp + 1;
- boolean isFind = false;
- while (getKeyByPosition(page, low) == oldKey && low >= 0){
- if(getValByPosition(page, low) == oldPageNum) {
- temp = low;
- isFind = true;
- break;
- }
- low--;
- }
- while (getKeyByPosition(page, high) == oldKey && !isFind && high <= (BPlusTreeIndex.MAX_PAGE_ITEM - 1)) {
- if(getValByPosition(page, high) == oldPageNum) {
- temp = high;
- isFind = true;
- break;
- }
- high++;
- }
- if (!isFind) {
- try {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- } catch (ItemInNextPageException e) {
- e.printStackTrace();
- }
- }
- //先对半分
- byte[] bs = new byte[16];
- try {
- for (int k = 0; k < BPlusTreeIndex.MAX_PAGE_ITEM/2; k++) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_MID_POSTION + k * 16, bs, 0, 16);
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- }
- catch (PageException e) {
- e.printStackTrace();
- }
- //在根据temp的取值情况分别处理
- if (temp < (BPlusTreeIndex.MAX_PAGE_ITEM)/2) {
- try {
- for (int k = BPlusTreeIndex.MAX_PAGE_ITEM/2; k > temp; k--) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_BEGIN_POSTION + (k - 1) * 16, bs, 0, 16);
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + (temp + 1) * 16 + 8,ByteUtil.long2Bytes(replacePageNum));
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(newKey), ByteUtil.long2Bytes(oldPageNum));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(page, BPlusTreeIndex.MAX_PAGE_ITEM/2 + 1);
- setPageItemNum(newPage,BPlusTreeIndex.MAX_PAGE_ITEM/2);
- long newKey0 = getKeyByPosition(page, BPlusTreeIndex.MAX_PAGE_ITEM/2);
- setMaxKey(page, newKey0);
- return newKey0;
- } else {
- temp = temp - BPlusTreeIndex.MAX_PAGE_ITEM/2;
- try {
- for (int k = BPlusTreeIndex.MAX_PAGE_ITEM/2; k > temp; k--) {
- System.arraycopy(newPage.getDataBytes(), BPlusTreeIndex.PAGE_BEGIN_POSTION + (k - 1) * 16, bs, 0, 16);
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + (temp + 1) * 16 + 8,ByteUtil.long2Bytes(replacePageNum));
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(newKey), ByteUtil.long2Bytes(oldPageNum));
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(page, BPlusTreeIndex.MAX_PAGE_ITEM/2);
- setPageItemNum(newPage,BPlusTreeIndex.MAX_PAGE_ITEM/2 + 1);
- long newKey0 = getKeyByPosition(page, BPlusTreeIndex.MAX_PAGE_ITEM/2 - 1);
- setMaxKey(page, newKey0);
- return newKey0;
- }
- }
-
- /**
- * 在internal节点中找到第一个keyHash有关的下一个节点,如果不满maxKey检验,则表明搜索的条目不再此页,抛出异常
- * @param page
- * @param keyHash
- * @return 相应儿子节点页号
- */
- private long queryFirstInternalItem(Page page, long keyHash) throws ItemInNextPageException {
- if ( keyHash > getMaxKey(page) ) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
-// try {
- while (i < j ) {
- if (getKeyByPosition(page, temp) > keyHash){
- j = temp;
- }else if (getKeyByPosition(page, temp) < keyHash){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
-// }catch (ArrayIndexOutOfBoundsException e) {
-// System.out.println("werwe");
-// }
- while (temp >= 1 && getKeyByPosition(page, temp-1) >= keyHash){
- temp--;
- }
- return getValByPosition(page, temp);
- }
-
- /**
- * 在internal节点中找到大于keyHash有关的下一个节点,如果不满maxKey检验,则表明搜索的条目不再此页,抛出异常
- * @param page
- * @param keyHash
- * @return 相应儿子节点页号
- */
- private long queryUpperboundInternal(Page page, long keyHash) throws ItemInNextPageException {
- if ( keyHash > getMaxKey(page) ) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
- while (i < j ) {
- if (getKeyByPosition(page, temp) > keyHash){
- j = temp;
- }else if (getKeyByPosition(page, temp) < keyHash){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- while (temp < itemNum && getKeyByPosition(page, temp) <= keyHash){
- temp++;
- }
- return getValByPosition(page, temp);
- }
-
- /**
- * 对树叶节点插入item,相应会抛出页满,条目不在相应页的异常
- * @param page
- * @param keyHash
- * @param uuid
- * @return
- */
- private void insertLeafItem(Page page, long keyHash, long uuid) throws ItemInNextPageException, PageFullException {
- if ( keyHash > getMaxKey(page)) {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- }
- int itemNum = getPageItemNum(page);
- if ( itemNum >= BPlusTreeIndex.MAX_PAGE_ITEM ) {
- throw new PageFullException(1);
- }
- int i = 0,j = itemNum;
- int temp = (i + j)/2;
- while (i < j ) {
- long cmp = getKeyByPosition(page, temp);
-// long cmp0 = getKeyByPosition(page, temp - 1);
-// long cmp1 = getKeyByPosition(page, temp - 2);
- if (cmp > keyHash){
- j = temp;
- }else if (cmp < keyHash){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- try {
- byte[] bs = new byte[16];
- for (int k = itemNum; k > temp; k--) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_BEGIN_POSTION + (k - 1) * 16, bs, 0, 16);
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(keyHash), ByteUtil.long2Bytes(uuid));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(page, itemNum + 1);
- }
-
- /**
- *对一个已经满了的叶插入item
- * @param page 待分裂已满的页
- * @param newPage 一个未用过的新的页,用于分裂
- * @param newPageNum 新页的页号
- * @param keyHash 分裂时顺便插入的条目的键
- * @param uuid 分裂时顺便插入的条目的值
- * @return 为分裂后新的key
- */
- private long insertFullLeaf(Page page, Page newPage, long newPageNum, long keyHash, long uuid) {
- if ( keyHash > getMaxKey(page)) {
- try {
- throw new ItemInNextPageException(1, getPageNextPage(page));
- } catch (ItemInNextPageException e) {
- e.printStackTrace();
- }
- }
- setPageType(newPage, PageType.LEAF);
-// setPageItemNum(newPage,(BPlusTreeIndex.MAX_PAGE_ITEM + 1)/2);
- setMaxKey(newPage, getMaxKey(page));
- setPageNextPage(newPage, getPageNextPage(page));
- setPageNextPage(page, newPageNum);
- int i = 0,j = BPlusTreeIndex.MAX_PAGE_ITEM;
- int temp = (i + j)/2;
- while (i < j) {
- if (getKeyByPosition(page, temp) > keyHash){
- j = temp;
- }else if (getKeyByPosition(page, temp) < keyHash){
- i = temp + 1;
- }else {
- break;
- }
- temp = (i + j ) / 2;
- }
- if (temp < (BPlusTreeIndex.MAX_PAGE_ITEM)/2) {
- byte[] bs = new byte[16];
- try {
- for (int k = 0; k < BPlusTreeIndex.MAX_PAGE_ITEM/2; k++) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_MID_POSTION + k * 16, bs, 0, 16);
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16, bs);
- }
- }
- catch (PageException e) {
- e.printStackTrace();
- }
- try {
- for (int k = BPlusTreeIndex.MAX_PAGE_ITEM/2; k > temp; k--) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_BEGIN_POSTION + (k - 1) * 16, bs, 0, 16);
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(keyHash), ByteUtil.long2Bytes(uuid));
- page.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + temp * 16,inserted);
- } catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(newPage,BPlusTreeIndex.MAX_PAGE_ITEM/2);
- setPageItemNum(page, BPlusTreeIndex.MAX_PAGE_ITEM/2 + 1);
- long newKey = ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(), BPlusTreeIndex.PAGE_MID_POSTION,8));
- setMaxKey(page, newKey);
- return newKey;
- } else {
- byte[] bs = new byte[16];
- try {
- boolean isInsert = false;
- for (int k = 0; k < BPlusTreeIndex.MAX_PAGE_ITEM/2; k++) {
- System.arraycopy(page.getDataBytes(), BPlusTreeIndex.PAGE_MID_POSTION + k * 16, bs, 0, 16);
- if (keyHash < ByteUtil.bytes2Long(ByteUtil.subByte(bs, 0, 8)) && !isInsert) {
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(keyHash), ByteUtil.long2Bytes(uuid));
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,inserted);
- isInsert = true;
- }
- if (isInsert) {
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + ( k + 1 ) * 16,bs);
- } else {
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + k * 16,bs);
- }
- }
- if (!isInsert) {
- byte[] inserted = ByteUtil.byteMerger(ByteUtil.long2Bytes(keyHash), ByteUtil.long2Bytes(uuid));
- newPage.patchData(BPlusTreeIndex.PAGE_BEGIN_POSTION + BPlusTreeIndex.MAX_PAGE_ITEM/2 * 16,inserted);
- }
- }
- catch (PageException e) {
- e.printStackTrace();
- }
- setPageItemNum(newPage,BPlusTreeIndex.MAX_PAGE_ITEM/2 + 1);
- setPageItemNum(page, BPlusTreeIndex.MAX_PAGE_ITEM/2);
- long newKey = ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),BPlusTreeIndex.PAGE_MID_POSTION - 16,8));
- setMaxKey(page, newKey);
- return newKey;
- }
- }
-
- /**
- * 通过位置获得key
- * @param page
- * @param position
- * @return
- */
- private long getKeyByPosition(Page page, int position) {
- int pos = BPlusTreeIndex.PAGE_BEGIN_POSTION + 16*position;
- return ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),pos,8));
- }
-
- private long getValByPosition(Page page, int position) {
- int pos = BPlusTreeIndex.PAGE_BEGIN_POSTION + 16*position + 8;
- return ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),pos,8));
- }
-
- /**
- * 设置页的最大key字段
- * @param page
- * @param maxKey
- */
- private void setMaxKey(Page page, long maxKey) {
- byte[] bs = ByteUtil.long2Bytes(maxKey);
- try {
- page.patchData(16,bs);
- } catch (PageException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 读取页的最大key字段
- * @param page
- * @return
- */
- private long getMaxKey(Page page) {
- return ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),16,8));
- }
-
- /**
- * 设置某页的项目数量
- * @param page
- * @param itemNum
- */
- private void setPageItemNum(Page page, int itemNum) {
- byte[] bs = ByteUtil.int2Bytes(itemNum);
- try {
- page.patchData(4,bs);
- } catch (PageException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 获得某页的项目数量
- * @param page
- * @return
- */
- private int getPageItemNum(Page page) {
- return ByteUtil.bytes2Int(ByteUtil.subByte(page.getDataBytes(),4,4));
- }
-
- /**
- * 设置某页的下一页的页码
- * @param page
- * @param pageNum
- */
- private void setPageNextPage(Page page, long pageNum) {
- byte[] bs = ByteUtil.long2Bytes(pageNum);
- try {
- page.patchData(8,bs);
- } catch (PageException e) {
- e.printStackTrace();
- }
- }
-
- /**
- *
- * @param page
- * @return 返回下一页的页码
- */
- private long getPageNextPage(Page page) {
- return ByteUtil.bytes2Long(ByteUtil.subByte(page.getDataBytes(),8,8));
- }
-
- /**
- *
- * @param page 页
- * @param pageType 设置页的类型
- */
- private void setPageType(Page page, PageType pageType) {
- int temp = pageType.ordinal();
- byte[] bs = ByteUtil.int2Bytes(temp);
- try {
- page.patchData(0,bs);
- } catch (PageException e) {
- e.printStackTrace();
- }
- }
-
- /**
- *
- * @param page 页
- * @return 页的类型,如果不存在对应页类型,则抛出异常
- */
- public PageType getPageType(Page page) {
- int typeNum = ByteUtil.bytes2Int(ByteUtil.subByte(page.getDataBytes(),0,4));
- if (typeNum == PageType.INTERNAL.ordinal()) {
- return PageType.INTERNAL;
- } else if (typeNum == PageType.LEAF.ordinal()) {
- return PageType.LEAF;
- } else if (typeNum == PageType.META.ordinal()) {
- return PageType.META;
- }
- try {
- throw new PageTypeException(1);
- } catch (PageTypeException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- private class BPlusTreeIterator implements Iterator {
- BPlusTreeIndex bPlusTreeIndex;
- Page currentPage;
- int currentPosition;
- int currentPageItemNum;
- boolean isEnd = false;
-
- public BPlusTreeIterator(BPlusTreeIndex bPlusTreeIndex, Page currentPage, int currentPosition) {
- this.bPlusTreeIndex = bPlusTreeIndex;
- this.currentPage = currentPage;
- //pin 双重pin 传进来之前已经pin过次此来
- currentPage.pin();
- this.currentPosition = currentPosition;
- this.currentPageItemNum = getPageItemNum(currentPage);
- }
-
- @Override
- public boolean hasNext() {
- synchronized (bPlusTreeIndex) {
- if (currentPageItemNum > currentPosition) {
- return true;
- } else {
- if (!isEnd && getPageNextPage(currentPage) != 0) {
- return true;
- } else{
- return false;
- }
- }
- }
- }
-
- @Override
- public Pair next() {
- synchronized (bPlusTreeIndex) {
- if ( currentPageItemNum > currentPosition ) {
- Pair res = new Pair(getKeyByPosition(currentPage,currentPosition), getValByPosition(currentPage,currentPosition));
- currentPosition++;
- return res;
- }
- else {
- long nextPageNum = getPageNextPage(currentPage);
- if (nextPageNum == 0) {
- if (isEnd) {
- isEnd = true;
- //unpin
- currentPage.unpin();
- }
- return null;
- } else {
- log.debug("nextPage, num = {}", nextPageNum);
- //unpin
- currentPage.unpin();
- currentPage = this.bPlusTreeIndex.pageStorage.get(nextPageNum);
- //pin
- currentPage.pin();
- currentPageItemNum = getPageItemNum(currentPage);
- currentPosition = 0;
- Pair res = new Pair(getKeyByPosition(currentPage,currentPosition), getValByPosition(currentPage,currentPosition));
- currentPosition++;
- return res;
- }
- }
- }
- }
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/btree/ByteUtil.java b/src/main/java/net/kaaass/rumbase/index/btree/ByteUtil.java
deleted file mode 100644
index 057b474..0000000
--- a/src/main/java/net/kaaass/rumbase/index/btree/ByteUtil.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package net.kaaass.rumbase.index.btree;
-
-/**
- *下面为byte[]与其他类型有关的转化关系代码内容
- *
- * @author 无索魏
- */
-
-public class ByteUtil {
-
- /**
- * 合并byte[]数组 (不改变原数组)
- * @param byte_1
- * @param byte_2
- * @return 合并后的数组
- */
- public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){
- byte[] byte_3 = new byte[byte_1.length+byte_2.length];
- System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
- System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
- return byte_3;
- }
-
- /**
- * 截取byte数组 不改变原数组
- * @param b 原数组
- * @param off 偏差值(索引)
- * @param length 长度
- * @return 截取后的数组
- */
- public static byte[] subByte(byte[] b,int off,int length){
- byte[] b1 = new byte[length];
- System.arraycopy(b, off, b1, 0, length);
- return b1;
- }
-
- /**
- * Long 转 byte[]
- * @return
- */
- public static byte[] long2Bytes(long num) {
- byte[] byteNum = new byte[8];
- for (int ix = 0; ix < 8; ++ix) {
- int offset = 64 - (ix + 1) * 8;
- byteNum[ix] = (byte) ((num >> offset) & 0xff);
- }
- return byteNum;
- }
-
- /**
- * byte[] 转 Long
- * @return
- */
- public static long bytes2Long(byte[] byteNum) {
- long num = 0;
- for (int ix = 0; ix < 8; ++ix) {
- num <<= 8;
- num |= (byteNum[ix] & 0xff);
- }
- return num;
- }
-
- /**
- * byte 转 Int
- * @param byteNum
- * @return
- */
- public static int bytes2Int(byte[] byteNum) {
- int num = 0;
- for (int ix = 0; ix < 4; ++ix) {
- num <<= 8;
- num |= (byteNum[ix] & 0xff);
- }
- return num;
- }
-
- /**
- * Int 转 byte[]
- * @param num
- * @return
- */
- public static byte[] int2Bytes(int num) {
- byte[] byteNum = new byte[4];
- for (int ix = 0; ix < 4; ++ix) {
- int offset = 32 - (ix + 1) * 8;
- byteNum[ix] = (byte) ((num >> offset) & 0xff);
- }
- return byteNum;
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/exception/IndexAlreadyExistException.java b/src/main/java/net/kaaass/rumbase/index/exception/IndexAlreadyExistException.java
deleted file mode 100644
index 1c9a4c3..0000000
--- a/src/main/java/net/kaaass/rumbase/index/exception/IndexAlreadyExistException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.kaaass.rumbase.index.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 当根据文件名创建一个新的空索引时,如果相应的文件名已经存在了索引,则不能创建新的空索引,并抛出此异常
- * @author 无索魏
- */
-public class IndexAlreadyExistException extends RumbaseException {
-
- public static final Map REASONS = new HashMap<>() {{
- put(1, "索引已经存在");
- }};
-
- /**
- * 构造Rumbase异常
- *
- * @param mainId 主错误号
- * @param subId 子错误号
- * @param reason 错误原因
- */
- private IndexAlreadyExistException(int mainId, int subId, String reason) {
- super(mainId, subId, reason);
- }
-
- /**
- * 索引不存在
- *
- * @param subId 子错误号
- */
- public IndexAlreadyExistException(int subId) {
- super(9002, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/exception/IndexNotFoundException.java b/src/main/java/net/kaaass/rumbase/index/exception/IndexNotFoundException.java
deleted file mode 100644
index e7cdf60..0000000
--- a/src/main/java/net/kaaass/rumbase/index/exception/IndexNotFoundException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.kaaass.rumbase.index.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 当加载一个索引时,如果索引实现不存在相应的持久化信息,则无法加载,并抛出此异常
- * @author 无索魏
- */
-public class IndexNotFoundException extends RumbaseException {
- /**
- * 构造Rumbase异常
- *
- * @param mainId 主错误号
- * @param subId 子错误号
- * @param reason 错误原因
- */
- public IndexNotFoundException(int mainId, int subId, String reason) {
- super(mainId, subId, reason);
- }
-
- public static final Map REASONS = new HashMap<>() {{
- put(1, "索引不存在");
- }};
-
- /**
- * 索引不存在
- *
- * @param subId 子错误号
- */
- public IndexNotFoundException(int subId) {
- super(9001, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/exception/ItemInNextPageException.java b/src/main/java/net/kaaass/rumbase/index/exception/ItemInNextPageException.java
deleted file mode 100644
index cfa392f..0000000
--- a/src/main/java/net/kaaass/rumbase/index/exception/ItemInNextPageException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.kaaass.rumbase.index.exception;
-
-import lombok.Getter;
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 要找的条目不在本页,而下一页
- * @author 无索魏
- */
-public class ItemInNextPageException extends RumbaseException {
-
- @Getter
- private long nextPageNum;
-
- /**
- * 构造Rumbase异常
- *
- * @param mainId 主错误号
- * @param subId 子错误号
- * @param reason 错误原因
- */
- public ItemInNextPageException(int mainId, int subId, String reason) {
- super(mainId, subId, reason);
- }
-
- public static final Map REASONS = new HashMap<>() {{
- put(1, "页类型不存在");
- }};
-
- /**
- * 条目不在本页
- *
- * @param subId 子错误号
- */
- public ItemInNextPageException(int subId, long nextPageNum) {
- super(9004, subId, REASONS.get(subId));
- this.nextPageNum = nextPageNum;
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/exception/PageFullException.java b/src/main/java/net/kaaass/rumbase/index/exception/PageFullException.java
deleted file mode 100644
index e26f94a..0000000
--- a/src/main/java/net/kaaass/rumbase/index/exception/PageFullException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.kaaass.rumbase.index.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 页已经满了,无法进行原先的插入操作
- * @author 无索魏
- */
-public class PageFullException extends RumbaseException {
- /**
- * 构造Rumbase异常
- *
- * @param mainId 主错误号
- * @param subId 子错误号
- * @param reason 错误原因
- */
- public PageFullException(int mainId, int subId, String reason) {
- super(mainId, subId, reason);
- }
-
- public static final Map REASONS = new HashMap<>() {{
- put(1, "页已满,无法插入");
- }};
-
- /**
- * 索引不存在
- *
- * @param subId 子错误号
- */
- public PageFullException(int subId) {
- super(9005, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/exception/PageTypeException.java b/src/main/java/net/kaaass/rumbase/index/exception/PageTypeException.java
deleted file mode 100644
index d0942db..0000000
--- a/src/main/java/net/kaaass/rumbase/index/exception/PageTypeException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.kaaass.rumbase.index.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- * @author 无索魏
- */
-public class PageTypeException extends RumbaseException {
- /**
- * 构造Rumbase异常
- *
- * @param mainId 主错误号
- * @param subId 子错误号
- * @param reason 错误原因
- */
- public PageTypeException(int mainId, int subId, String reason) {
- super(mainId, subId, reason);
- }
-
- public static final Map REASONS = new HashMap<>() {{
- put(1, "页类型不存在");
- put(2, "非MEAT页不能读取文件总页数");
- }};
-
- /**
- * 索引不存在
- *
- * @param subId 子错误号
- */
- public PageTypeException(int subId) {
- super(9003, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/mock/MockBtreeIndex.java b/src/main/java/net/kaaass/rumbase/index/mock/MockBtreeIndex.java
deleted file mode 100644
index a37d75f..0000000
--- a/src/main/java/net/kaaass/rumbase/index/mock/MockBtreeIndex.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package net.kaaass.rumbase.index.mock;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import net.kaaass.rumbase.index.Index;
-import net.kaaass.rumbase.index.Pair;
-
-import java.util.*;
-
-/**
- * @author 无索魏
- */
-@RequiredArgsConstructor
-public class MockBtreeIndex implements Index {
- /**
- * 内存中创建的MockBtreeIndex
- */
- public static Map MOCK_BTREE_INDEX_MAP = new HashMap<>();
-
- @Getter
- private HashMap> hashMap = new HashMap<>();
-
- @Override
- public void replace(Map uuidMap) {
- var values = hashMap.values();
- for (List value : values) {
- for (Long old : value) {
- if (uuidMap.containsKey(old)) {
- value.remove(old);
- value.add(uuidMap.get(old));
- }
- }
- }
- }
-
- @Override
- public void insert(long dataHash, long uuid) {
- hashMap.computeIfAbsent(dataHash, k -> new ArrayList<>()).add(uuid);
- }
-
- @Override
- public List query(long dataHash) {
- return hashMap.get(dataHash) == null ? new LinkedList<>() : hashMap.get(dataHash);
- }
-
- @Override
- public Iterator findFirst(long keyHash) {
- return new MockIterator(this, keyHash, true);
- }
-
- @Override
- public Iterator findUpperbound(long keyHash) {
- return new MockIterator(this, keyHash, false);
- }
-
- @Override
- public Iterator findFirst() {
- return new MockIterator(this);
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/index/mock/MockIterator.java b/src/main/java/net/kaaass/rumbase/index/mock/MockIterator.java
deleted file mode 100644
index 239114a..0000000
--- a/src/main/java/net/kaaass/rumbase/index/mock/MockIterator.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package net.kaaass.rumbase.index.mock;
-
-import net.kaaass.rumbase.index.Pair;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author 无索魏
- */
-public class MockIterator implements Iterator {
- private Iterator>> indexIterator;
- private Iterator tempIterator;
- private long tempKey;
- private boolean state = true;
-
- public MockIterator(MockBtreeIndex mockBtreeIndex) {
- indexIterator = mockBtreeIndex.getHashMap().entrySet().iterator();
- if (!indexIterator.hasNext()) {
- state = false;
- return;
- }
- var f = indexIterator.next();
- tempIterator = f.getValue().iterator();
- tempKey = f.getKey();
- }
-
- public MockIterator(MockBtreeIndex mockBtreeIndex, long keyHash, boolean isWith) {
- indexIterator = mockBtreeIndex.getHashMap().entrySet().iterator();
- if (isWith == true) {
- do {
- var v = indexIterator.next();
- if (v == null) {
- state = false;
- break;
- }
- tempIterator = v.getValue().iterator();
- tempKey = v.getKey();
- } while (tempKey < keyHash);
- } else {
- do {
- var v = indexIterator.next();
- if (v == null) {
- state = false;
- break;
- }
- tempIterator = v.getValue().iterator();
- tempKey = v.getKey();
- } while (tempKey <= keyHash);
- }
- }
-
- @Override
- public boolean hasNext() {
- return indexIterator.hasNext() || (tempIterator != null && tempIterator.hasNext());
- }
-
-
- @Override
- public Pair next() {
- if (state == false) {
- return null;
- }
- Pair res = new Pair(tempKey, tempIterator.next());
- if (!tempIterator.hasNext()) {
- if (!indexIterator.hasNext()) {
- state = false;
- return res;
- }
- var v = indexIterator.next();
- tempIterator = v.getValue().iterator();
- tempKey = v.getKey();
- }
- return res;
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/Page.java b/src/main/java/net/kaaass/rumbase/page/Page.java
deleted file mode 100644
index 77b13b3..0000000
--- a/src/main/java/net/kaaass/rumbase/page/Page.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package net.kaaass.rumbase.page;
-
-import net.kaaass.rumbase.page.exception.FileException;
-import net.kaaass.rumbase.page.exception.PageException;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-/**
- * 单页管理
- *
- * Page对象通过PageCache获得。获得的对象【不可以长期保存】(如保存在对象中作为对象的字段)。
- * 使用页面需要注意使用pin,以防止Page对象被提前回收。
- *
- * var page = pageCache.get(1);
- * page.pin();
- * // ...
- * page.getData();
- * // ...
- * // 如果不pin,则此处page对象可能因为被淘汰失效
- * page.patchData(2, patch);
- * page.unpin();
- *
- * 如果操作有错误风险(有可能发生不造成停机的错误),必须加上try-catch-finally
- *
- * var page = pageCache.get(1);
- * page.pin();
- * try {
- * page.getData();
- * // ...
- * page.patchData(2, patch);
- * } catch (Exception e) {
- * // ...
- * } finally {
- * page.unpin(); // 重要:防止内存泄漏,必须在finally释放
- * }
- *
- * 若操作数量为1,不复用Page对象的情形,可以忽略。
- *
- * pageCache.get(1).getData();
- *
- *
- * @author XuanLaoYee
- */
-public interface Page {
-
- /**
- * (性能原因,建议使用getData)获得页内数据
- *
- * @return 字节数组,通常为4K
- */
- byte[] getDataBytes();
-
- /**
- * 获得页内数据的字节流
- *
- * 目前使用default方法实现,留作将来优化性能用
- *
- * @return 字节流
- */
- default InputStream getData() {
- return new ByteArrayInputStream(getDataBytes());
- }
-
- /**
- * 将字节数据写入页
- *
- * @param data 待写入字节数据
- * @throws PageException 若写入的数据超出页的范围则抛出异常
- */
- default void writeData(byte[] data) throws PageException {
- patchData(0, data);
- }
-
- /**
- * 在页指定位置写入数据
- *
- * @param offset 页内偏移值,以字节为单位
- * @param data 待写入数据
- * @throws PageException 若写入的数据超出页的范围则抛出异常
- */
- void patchData(int offset, byte[] data) throws PageException;
-
- void flush() throws FileException;
-
- /**
- * 将页固定在内存中
- *
- * 操作规约:必须在系列操作之前使用pin,以防止页被回收
- */
- void pin();
-
- /**
- * 将页从内存中取消固定
- *
- * 操作规约:必须在系列操作之后使用unpin,以防止内存泄露
- */
- void unpin();
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/PageManager.java b/src/main/java/net/kaaass/rumbase/page/PageManager.java
deleted file mode 100644
index ba4e166..0000000
--- a/src/main/java/net/kaaass/rumbase/page/PageManager.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package net.kaaass.rumbase.page;
-
-import net.kaaass.rumbase.page.exception.FileException;
-import net.kaaass.rumbase.page.mock.MockPageStorage;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author XuanLaoYee
- */
-public class PageManager {
- public static int PAGE_SIZE = 1024 * 4; // 页面大小是4KB
- public static long FILE_HEAD_SIZE = 5; // 文件头留5页
- public static int BUFFER_SIZE = 1000; //缓冲大小,单位是页,页的大小不可以超过524287
- public static int BYTE_BUFFER_SIZE = 1024 * 4 * BUFFER_SIZE;
-
- /**
- * 取数据库文件生成文件管理的对象
- *
- * @param filepath 每个表文件路径
- * @return
- * @throws FileException 若文件不存在则创建,创建过程中出现错误会抛出错误
- */
- public static PageStorage fromFile(String filepath) throws FileException {
- PageStorage storage = new RumPageStorage(filepath);
- storages.add(storage);
- return storage;
- }
- /**
- * 取数据库文件生成文件管理的对象
- */
- public static void flush(){
- for(PageStorage storage : storages){
- storage.flush();
- }
- }
- public static List storages = new ArrayList<>();
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/PageStorage.java b/src/main/java/net/kaaass/rumbase/page/PageStorage.java
deleted file mode 100644
index 5d67685..0000000
--- a/src/main/java/net/kaaass/rumbase/page/PageStorage.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package net.kaaass.rumbase.page;
-
-/**
- * 用于管理一系列连续页的存储对象,隐藏任何关于存储的物理细节
- *
- * @author XuanLaoYee
- */
-public interface PageStorage {
-
- /**
- * 获取该页存储中的某一页
- *
- * @param pageId 页号
- * @return 该页页对象
- */
- Page get(long pageId);
-
- /**
- * 将页存储中的所有脏页写回文件
- */
- void flush();
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/Replacer.java b/src/main/java/net/kaaass/rumbase/page/Replacer.java
deleted file mode 100644
index 283fc4c..0000000
--- a/src/main/java/net/kaaass/rumbase/page/Replacer.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package net.kaaass.rumbase.page;
-
-import net.kaaass.rumbase.page.exception.BufferException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class Replacer {
- private static Replacer instance = null;
- private Replacer() {
- this.head = null;
- this.tail = null;
- this.table = new HashMap<>();
- }
-
- public static Replacer getInstance() {
- if (instance == null) {
- synchronized (Replacer.class) {
- if (instance == null) {
- instance = new Replacer();
- }
- }
- }
- return instance;
- }
-
- public void insert(RumPage value) {
- synchronized (this) {
- if (!this.table.containsKey(value)) {//如果页没在内存中
- Node tmp = new Node(value, null);
- if(head==null){
- this.head = tmp;
- this.tail = tmp;
- }else{
- this.tail.next = tmp;
- this.tail = this.tail.next;
- this.table.put(value, this.tail);
- }
- ++size;
- } else {
- Node hitNode = this.table.get(value);
- hit(hitNode);
- }
- }
- }
-
- /**
- * 从链表中取出受害者页,若链表为空则返回null
- * @return 返回受害者页面
- * @throws BufferException 若链表中所有的页均被钉住,则抛出异常
- */
- public RumPage victim() throws BufferException {
- synchronized (this) {
- if (size == 0) {
- return null;
- }
- Node tmp = head;
- while (tmp != null && tmp.pinned()){
- tmp = tmp.next;
- }
- if(tmp == null){
- throw new BufferException(2);
- }
- Node pre = head;//找tmp上一个节点
- if(pre!=tmp){
- while(pre.next != tmp){
- pre = pre.next;
- }
- }
- if(tmp == head){
- head = head.next;
- size--;
- return tmp.getData();
- }else{
- pre.next = tmp.next;
- size--;
- return tmp.getData();
- }
- }
- }
-
- public int size() {
- return size;
- }
-
- /**
- * 将命中的页移至链表尾
- *
- * @param p 命中的节点
- */
- private void hit(Node p) {
- Node tmp = head;
- while (tmp.next != null) {
- if (tmp.next == p) {
- break;
- } else {
- tmp = tmp.next;
- }
- }
- if (p.next != null) {
- tmp.next = p.next;
- this.tail.next = p;
- this.tail = this.tail.next;
- }
- }
-
- private int size;
- Node tail;
- Node head;
- Map table;
-
-}
-
-class Node {
- private final RumPage data;
- Node next = null;
-
- public Node(RumPage data, Node p) {
- this.data = data;
- this.next = p;
- }
-
- public boolean pinned(){
- return data.pinned();
- }
-
- public RumPage getData(){
- return data;
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/RumBuffer.java b/src/main/java/net/kaaass/rumbase/page/RumBuffer.java
deleted file mode 100644
index 5f1b909..0000000
--- a/src/main/java/net/kaaass/rumbase/page/RumBuffer.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package net.kaaass.rumbase.page;
-
-import net.kaaass.rumbase.page.exception.BufferException;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * 内存管理
- *
- * 使用单例模式,使用byte数组开辟连续空间,内存的大小不得超过BYTE_BUFFER_SIZE,RumBuffer在操作时直接将整块内存锁住
- *
- * @author XuanLaoYee
- */
-public class RumBuffer {
- private static RumBuffer instance = null;
- private int size = 0;
- private ReentrantLock lock = null;
- private final byte[] byteBuffer = new byte[PageManager.BYTE_BUFFER_SIZE];
- private List freePage = null;
-
- private RumBuffer(){
- this.lock = new ReentrantLock();
- this.size = PageManager.BUFFER_SIZE;
- this.freePage = new ArrayList<>();
- for(int i=0;i
- * 页持有的是整个缓冲区的指针和偏移。页在patchData时本身并不加锁,如果防止冲突需要在上层加锁。
- *
- * @author XuanLaoYee
- */
-public class RumPage implements Page {
- public RumPage(byte[] data, long pageId, String filepath, int offset) {
- this.data = data;
- this.pageId = pageId;
- this.dirty = false;
- this.filepath = filepath;
- this.offset = offset;//在内存中的偏移,指的是以页为单位的偏移
- }
-
- /**
- * 得到的是数据的副本,而非缓冲区的指针。
- * @return clone后的数据
- */
- @Override
- public byte[] getDataBytes() {
- synchronized (this) {
- byte[] tmp = new byte[PageManager.PAGE_SIZE];
- System.arraycopy(this.data, this.offset * PageManager.PAGE_SIZE, tmp, 0, tmp.length);
- return tmp;
- }
- }
-
- /**
- *
- * @param offset 页内偏移值,以字节为单位 ,该过程不加锁
- * @param data 待写入数据
- * @throws PageException 回写数据偏移与大小之和超过规定,则抛出异常
- */
- @Override
- public void patchData(int offset, byte[] data) throws PageException {
- if (offset + data.length > PageManager.PAGE_SIZE) {
- throw new PageException(1);
- }
- synchronized (this) {
- this.dirty = true;
- }
- //直接往缓冲内写入
- System.arraycopy(data, 0, this.data, this.offset * PageManager.PAGE_SIZE + offset, data.length);
- }
-
- /**
- * 还未实现double write
- * @throws FileException
- */
- @Override
- public void flush() throws FileException {
- File file = new File(this.filepath);
- synchronized (this) {
- try {
- RandomAccessFile out = new RandomAccessFile(file, "rw");
- try {
- out.seek((PageManager.FILE_HEAD_SIZE + this.pageId) * (long)PageManager.PAGE_SIZE);
- } catch (Exception e) {
- throw new FileException(4);
- }
- try {
- byte[] data = new byte[PageManager.PAGE_SIZE];
- System.arraycopy(this.data,this.offset*PageManager.PAGE_SIZE,data,0,data.length);
- out.write(data);
- } catch (Exception e) {
- throw new FileException(2);
- }
- out.close();
- } catch (FileException e) {
- throw e;
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- @Override
- public void pin() {
- synchronized (this) {
- pinned++;
- }
- }
-
- @Override
- public void unpin() {
- synchronized (this) {
- pinned--;
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- return this == obj;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- public boolean pinned() {
- return pinned > 0;
- }
-
- public boolean dirty() {
- return dirty;
- }
-
- public Long pageId(){
- return this.pageId;
- }
-
- private final byte[] data;
- private final long pageId;
- boolean dirty;
- int pinned = 0;
- String filepath;
- int offset;
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/RumPageStorage.java b/src/main/java/net/kaaass/rumbase/page/RumPageStorage.java
deleted file mode 100644
index d94dc23..0000000
--- a/src/main/java/net/kaaass/rumbase/page/RumPageStorage.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package net.kaaass.rumbase.page;
-
-import net.kaaass.rumbase.page.exception.BufferException;
-import net.kaaass.rumbase.page.exception.FileException;
-
-import java.io.*;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author 11158
- */
-public class RumPageStorage implements PageStorage {
- public RumPageStorage(String filepath) throws FileException {
- this.filepath = filepath;
- pageMap = new HashMap<>();
- }
-
- @Override
- public Page get(long pageId) {
- File file = new File(filepath);
- //文件不存在时创建新文件
- if (!file.exists()) {
- try {
- file.createNewFile();
- FileOutputStream out = new FileOutputStream(file);
- out.write(new byte[PageManager.PAGE_SIZE * 10]);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //文件会预留5页作为文件头
- try {
- FileInputStream in = new FileInputStream(file);
- byte[] data = new byte[PageManager.PAGE_SIZE];
- try {
- //当文件存储容量不够时追加
- while (in.available() < (pageId + 1 + PageManager.FILE_HEAD_SIZE) * PageManager.PAGE_SIZE) {
- FileWriter fw = new FileWriter(file, true);
- char[] blank = new char[PageManager.PAGE_SIZE * (in.available() / PageManager.PAGE_SIZE)];
- Arrays.fill(blank, (char)0);
- fw.write(blank);
- fw.close();
- }
- in.skip((pageId + PageManager.FILE_HEAD_SIZE) * PageManager.PAGE_SIZE);
- int readNumber = in.read(data);
- if (readNumber < PageManager.PAGE_SIZE) {
- throw new FileException(4);
- }
- } catch (Exception e) {
- throw new FileException(4);
- }
-
- Long tmpId = pageId;
- if (pageMap.containsKey(tmpId)) {
- return pageMap.get(tmpId);
- }
- int offset = -1;
- while (offset < 0) {
- synchronized (RumBuffer.getInstance()) {//并非区间锁,而是将整个内存全部锁住
- try {
- offset = RumBuffer.getInstance().getFreeOffset();
- RumBuffer.getInstance().put(offset, data);
- } catch (BufferException e) {
- //下面的这个换出算法没有考虑到在此过程中其他进程再次pin()的情况
- RumPage p = Replacer.getInstance().victim();
- if (p.dirty()) {
- p.flush();
- }
- RumBuffer.getInstance().free(p.offset);
- this.pageMap.remove(p.pageId());
- }
- }
- }
- RumPage page = new RumPage(RumBuffer.getInstance().buffer(), pageId, this.filepath, offset);
- Replacer.getInstance().insert(page);
- pageMap.put(tmpId, page);
- return page;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- public void flush() {
- Set> entrySet = this.pageMap.entrySet();
- for (Map.Entry entry : entrySet) {
- try {
- entry.getValue().flush();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- private final Map pageMap;
- private final String filepath;
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/exception/BufferException.java b/src/main/java/net/kaaass/rumbase/page/exception/BufferException.java
deleted file mode 100644
index 8d14de2..0000000
--- a/src/main/java/net/kaaass/rumbase/page/exception/BufferException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.kaaass.rumbase.page.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * E9003 缓冲异常
- *
- * E9003-1 内存不足无法换入
- * E9003-2 内存中所有页均被钉住无法换出
- * E9003-3 占用非空内存位置
- *
- * @author XuanLaoYee
- */
-public class BufferException extends RumbaseException {
- public static final Map REASONS = new HashMap() {{
- put(1, "内存不足无法换入");
- put(2, "内存中所有页均被钉住无法换出");
- put(3, "占用非空内存位置");
- }};
-
- /**
- * 文件异常
- *
- * @param subId 子错误号
- */
- public BufferException(int subId) {
- super(9003, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/exception/FileException.java b/src/main/java/net/kaaass/rumbase/page/exception/FileException.java
deleted file mode 100644
index 8358beb..0000000
--- a/src/main/java/net/kaaass/rumbase/page/exception/FileException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.kaaass.rumbase.page.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * E9001 文件异常
- *
- * E9001-1 创建文件失败
- * E9001-2 写入文件失败
- * E9001-3 文件打开失败
- * E9001-4 游标越界
- *
- * @author XuanLaoYee
- */
-public class FileException extends RumbaseException {
- public static final Map REASONS = new HashMap() {{
- put(1, "创建文件失败");
- put(2, "写入文件失败");
- put(3, "文件打开失败");
- put(4, "offset越界");
- }};
-
- /**
- * 文件异常
- *
- * @param subId 子错误号
- */
- public FileException(int subId) {
- super(9001, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/exception/PageException.java b/src/main/java/net/kaaass/rumbase/page/exception/PageException.java
deleted file mode 100644
index 356e5b4..0000000
--- a/src/main/java/net/kaaass/rumbase/page/exception/PageException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.kaaass.rumbase.page.exception;
-
-import net.kaaass.rumbase.exception.RumbaseException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * E9002 文件异常
- *
- * E9002-1 回写数据偏移与大小之和超过规定
- *
- * @author XuanLaoYee
- */
-public class PageException extends RumbaseException {
- public static final Map REASONS = new HashMap() {{
- put(1, "回写数据偏移与大小之和超过规定");
- }};
-
- /**
- * 页操作异常
- *
- * @param subId 主错误号
- */
- public PageException(int subId) {
- super(9002, subId, REASONS.get(subId));
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/mock/MockBuffer.java b/src/main/java/net/kaaass/rumbase/page/mock/MockBuffer.java
deleted file mode 100644
index a536bc3..0000000
--- a/src/main/java/net/kaaass/rumbase/page/mock/MockBuffer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package net.kaaass.rumbase.page.mock;
-
-import net.kaaass.rumbase.page.PageManager;
-import net.kaaass.rumbase.page.exception.BufferException;
-
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- *
- */
-public class MockBuffer {
- private static MockBuffer instance = null;
- private int size = 0;
-
- private MockBuffer() {
- this.lock = new ReentrantLock();
- size = PageManager.BUFFER_SIZE;
- }
-
- public static MockBuffer getInstance() {
- if (instance == null) {
- synchronized (MockBuffer.class) {
- if (instance == null) {
- instance = new MockBuffer();
- }
- }
- }
- return instance;
- }
-
- private final byte[] byteBuffer = new byte[PageManager.BYTE_BUFFER_SIZE];
-
- public void put(int offset, byte[] bytes) throws BufferException {
- if (this.size <= 0) {
- throw new BufferException(1);
- }
- lock.lock();
- try {
- System.arraycopy(bytes, 0, this.byteBuffer, offset, bytes.length);
- this.size--;
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
-
- public byte[] get(int offset) {
- lock.lock();
- try {
- byte[] temp = new byte[PageManager.PAGE_SIZE];
- System.arraycopy(this.byteBuffer, offset, temp, offset, PageManager.PAGE_SIZE);
- return temp;
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- return null;
- }
-
- public void free(int offset) {
- lock.lock();
- try {
- System.arraycopy(this.byteBuffer, offset, new byte[PageManager.PAGE_SIZE], 0, PageManager.PAGE_SIZE);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
-
- private ReentrantLock lock = null;
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/mock/MockPage.java b/src/main/java/net/kaaass/rumbase/page/mock/MockPage.java
deleted file mode 100644
index e96a8c2..0000000
--- a/src/main/java/net/kaaass/rumbase/page/mock/MockPage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.kaaass.rumbase.page.mock;
-
-import net.kaaass.rumbase.page.Page;
-import net.kaaass.rumbase.page.PageManager;
-import net.kaaass.rumbase.page.exception.FileException;
-import net.kaaass.rumbase.page.exception.PageException;
-
-public class MockPage implements Page {
- private byte[] data;
- long pageId;
- boolean dirty;
- int pinned = 0;
- String filepath;
-
- MockPage(byte[] data, long pageId, String filepath) {
- this.data = data;
- this.pageId = pageId;
- this.dirty = false;
- this.filepath = filepath;
- }
-
- @Override
- public byte[] getDataBytes() {
- synchronized (this) {
- return data;
- }
- }
-
- @Override
- public void patchData(int offset, byte[] data) throws PageException {
- if (offset + data.length > PageManager.PAGE_SIZE) {
- throw new PageException(1);
- }
- System.arraycopy(data, 0, this.data, offset, data.length);
- }
-
- @Override
- public void flush() throws FileException {
- }
-
- @Override
- public void pin() {
- synchronized (this) {
- pinned++;
- }
- }
-
- @Override
- public void unpin() {
- synchronized (this) {
- pinned--;
- }
- }
-}
diff --git a/src/main/java/net/kaaass/rumbase/page/mock/MockPageStorage.java b/src/main/java/net/kaaass/rumbase/page/mock/MockPageStorage.java
deleted file mode 100644
index d995199..0000000
--- a/src/main/java/net/kaaass/rumbase/page/mock/MockPageStorage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package net.kaaass.rumbase.page.mock;
-
-import net.kaaass.rumbase.page.Page;
-import net.kaaass.rumbase.page.PageManager;
-import net.kaaass.rumbase.page.PageStorage;
-import net.kaaass.rumbase.page.exception.FileException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author XuanLaoYee
- */
-public class MockPageStorage implements PageStorage {
-
-
- public MockPageStorage(String filepath) throws FileException {
- this.filepath = filepath;
- pageMap = new HashMap<>();
- this.fakeFile = new byte[1024 * 4 * 10000];
- for (int i = 0; i < 10000; i++) {
- for (int j = 0; j < 1024 * 4; j++) {
- this.fakeFile[1024 * 4 * i + j] = (byte) i;
- }
- }
- }
-
- @Override
- public Page get(long pageId) {
- //文件会预留5页作为文件头
- try {
- byte[] data = new byte[PageManager.PAGE_SIZE];
- System.arraycopy(fakeFile, (int) (pageId + PageManager.FILE_HEAD_SIZE) * PageManager.PAGE_SIZE, data, 0, data.length);
- Integer tmpId = (int) pageId;
- if (pageMap.containsKey(tmpId)) {
- return pageMap.get(tmpId);
- }
- Page page = new MockPage(data, pageId, this.filepath);
- pageMap.put(tmpId, page);
- return page;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- public void flush() {
- }
-
- private Map pageMap;
-
- private String filepath;
- private byte[] fakeFile;
-}
diff --git a/src/main/java/net/kaaass/rumbase/parse/ColumnIdentifier.java b/src/main/java/net/kaaass/rumbase/parse/ColumnIdentifier.java
deleted file mode 100644
index 5cc462c..0000000
--- a/src/main/java/net/kaaass/rumbase/parse/ColumnIdentifier.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.kaaass.rumbase.parse;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-/**
- * 操作、标志字段的标识符
- *
- * @author kaaass
- */
-@Data
-@AllArgsConstructor
-public class ColumnIdentifier {
-
- private String tableName;
-
- private String fieldName;
-}
diff --git a/src/main/java/net/kaaass/rumbase/parse/ConditionExpression.java b/src/main/java/net/kaaass/rumbase/parse/ConditionExpression.java
deleted file mode 100644
index 5aa10b7..0000000
--- a/src/main/java/net/kaaass/rumbase/parse/ConditionExpression.java
+++ /dev/null
@@ -1,435 +0,0 @@
-package net.kaaass.rumbase.parse;
-
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.kaaass.rumbase.parse.exception.EvaluationException;
-import net.kaaass.rumbase.parse.parser.jsqlp.ParserUtil;
-import net.sf.jsqlparser.expression.*;
-import net.sf.jsqlparser.expression.operators.arithmetic.*;
-import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
-import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
-import net.sf.jsqlparser.expression.operators.relational.*;
-import net.sf.jsqlparser.schema.Column;
-import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
-
-import java.util.*;
-
-/**
- * 条件表达式操作相关
- *
- * @author kaaass
- */
-@RequiredArgsConstructor
-public class ConditionExpression {
-
- public static double PRECISION = 0.00001;
-
- private final Expression expression;
-
- @NonNull
- private final String defaultTableName;
-
- private Map paramColumn = null;
-
- /**
- * 根据参数列表求值
- *
- * @param paramMap 参数列表,其中参数必须是原生类型的装箱对象,如Integer、String
- */
- public boolean evaluate(Map paramMap) {
- if (expression == null) {
- return true;
- }
- updateParam();
- var parser = new DeParser(paramMap);
- expression.accept(parser);
- var result = parser.getResult();
- if (result instanceof Double) {
- return Math.abs((Double) result) > PRECISION;
- } else if (result instanceof Long) {
- return ((Long) result) != 0;
- } else if (result instanceof Boolean) {
- return (boolean) result;
- } else if (result instanceof String) {
- return !"".equals(result);
- }
- throw new EvaluationException(1);
- }
-
- /**
- * 获得表达式求值需要的参数
- */
- public List getParams() {
- if (expression == null) {
- return List.of();
- }
- updateParam();
- return List.copyOf(paramColumn.values());
- }
-
- private void updateParam() {
- if (paramColumn == null) {
- paramColumn = new HashMap<>();
- expression.accept(new ExpressionVisitorAdapter() {
-
- @Override
- public void visit(Column column) {
- paramColumn.put(column, ParserUtil.mapColumn(column, defaultTableName));
- }
- });
- }
- }
-
- @Override
- public String toString() {
- return "ConditionExpression{" +
- "expression=" + expression +
- ", defaultTableName='" + defaultTableName + '\'' +
- '}';
- }
-
- /**
- * 实现表达式执行的具体访问者
- */
- @RequiredArgsConstructor
- class DeParser extends ExpressionDeParser {
-
- /*
- * 类型:数字暂时都转为Double、Boolean、String
- */
- Stack