LOG.debug("splitting " + rec.page.getPageNum() + ": new: " + nextSplitPage.getPageNum() + "; next: " + rec.page.getPageHeader().getNextDataPage());
    private RecordPos splitDataPage(DocumentImpl doc, RecordPos rec) {        if(currentDocument != null)            currentDocument.incSplitCount();        // check if a split is really required        boolean requireSplit = false;        for (int pos = rec.offset; pos < rec.page.len;) {            short currentId = ByteConversion.byteToShort(rec.page.data, pos);            if(!ItemId.isLink(currentId)) {                requireSplit = true;                break;            }            pos += 10;        }        if(!requireSplit) {//            LOG.debug("page " + rec.page.getPageNum() + ": no split required");            rec.offset = rec.page.len;            return rec;        }        NodeIndexListener idx = doc.getIndexListener();        int oldDataLen = rec.page.getPageHeader().getDataLength();        byte[] oldData = rec.page.data;        long oldPageNum = rec.page.getPageNum();        rec.page.data = new byte[fileHeader.getWorkSize()];        System.arraycopy(oldData, 0, rec.page.data, 0, rec.offset);        rec.page.len = rec.offset;        rec.page.setDirty(true);        DOMPage firstSplitPage = new DOMPage();        DOMPage nextSplitPage = firstSplitPage;        nextSplitPage.getPageHeader().setNextTID((short)(rec.page.getPageHeader().getNextTID() - 1));        short tid, currentId, currentLen;        long backLink;        short splitRecordCount = 0;//        LOG.debug("splitting " + rec.page.getPageNum() + ": new: "//                + nextSplitPage.getPageNum() + "; next: " + //                rec.page.getPageHeader().getNextDataPage());        for (int pos = rec.offset; pos < oldDataLen; splitRecordCount++) {            // read the current id            currentId = ByteConversion.byteToShort(oldData, pos);            tid = ItemId.getId(currentId);            pos += 2;            if(ItemId.isLink(currentId)) {                /* This is already a link, so we just copy it */                ByteConversion.shortToByte(currentId,                        rec.page.data, rec.page.len);                rec.page.len += 2;                System.arraycopy(oldData, pos, rec.page.data, rec.page.len, 8);                rec.page.len += 8;                pos += 8;                continue;            }            // read data length            currentLen = ByteConversion.byteToShort(oldData, pos);            pos += 2;                        if(nextSplitPage.len + currentLen + 12 > fileHeader.getWorkSize()) {                // not enough room in the split page: append a new page                DOMPage newPage = new DOMPage();                newPage.getPageHeader().setNextTID((short)(rec.page.getPageHeader().getNextTID() - 1));                newPage.getPageHeader().setPrevDataPage(nextSplitPage.getPageNum());                LOG.debug("creating new split page: " + newPage.getPageNum());                nextSplitPage.getPageHeader().setNextDataPage(newPage.getPageNum());                nextSplitPage.getPageHeader().setDataLength(nextSplitPage.len);                nextSplitPage.getPageHeader().setRecordCount(splitRecordCount);                nextSplitPage.setDirty(true);                dataCache.add(nextSplitPage);                dataCache.add(newPage);                nextSplitPage = newPage;                splitRecordCount = 0;            }            /* if the record has already been relocated, read the original storage             * address and update the link there.             */            if(ItemId.isRelocated(currentId)) {                backLink = ByteConversion.byteToLong(oldData, pos);                pos += 8;                RecordPos origRec = findRecord(backLink, false);                long forwardLink = StorageAddress.createPointer((int) nextSplitPage                        .getPageNum(), tid);                ByteConversion.longToByte(forwardLink, origRec.page.data, origRec.offset);                origRec.page.setDirty(true);                dataCache.add(origRec.page);            } else                backLink = StorageAddress.createPointer(                        (int) rec.page.getPageNum(), tid);            // set the relocated flag and save the item id            ByteConversion.shortToByte(ItemId.setIsRelocated(currentId),                    nextSplitPage.data, nextSplitPage.len);            nextSplitPage.len += 2;            //	save length field            ByteConversion.shortToByte(currentLen, nextSplitPage.data,                    nextSplitPage.len);            nextSplitPage.len += 2;            // save link to the original page            ByteConversion.longToByte(backLink, nextSplitPage.data,                    nextSplitPage.len);            nextSplitPage.len += 8;            // now save the data if this is not an overflow record            if (currentLen != OVERFLOW) {                try {                    System.arraycopy(oldData, pos, nextSplitPage.data,                            nextSplitPage.len, currentLen);                } catch (ArrayIndexOutOfBoundsException e) {                    LOG.error("pos = " + pos + "; len = " + nextSplitPage.len + "; currentLen = " + currentLen +                            "; tid = " + currentId + "; page = " + rec.page.getPageNum());                    throw e;                }                nextSplitPage.len += currentLen;                pos += currentLen;            }            // report the split to the index listener            if(idx != null) {	            idx.nodeChanged(StorageAddress.createPointer((int) oldPageNum, tid), StorageAddress.createPointer(	                    (int) nextSplitPage.getPageNum(), tid));            }            // save a link pointer in the original page if the record has not been            // relocated before.            if(!ItemId.isRelocated(currentId)) {                if(rec.page.len + 10 > fileHeader.getWorkSize()) {                    // the link doesn't fit into the old page. Append a new page                    DOMPage newPage = new DOMPage();                    newPage.getPageHeader().setNextTID((short)(rec.page.getPageHeader().getNextTID() - 1));                    newPage.getPageHeader().setPrevDataPage(rec.page.getPageNum());                    newPage.getPageHeader().setNextDataPage(rec.page.getPageHeader().getNextDataPage());//                    LOG.debug("creating new page after split: " + newPage.getPageNum());                    rec.page.getPageHeader().setNextDataPage(newPage.getPageNum());                    rec.page.getPageHeader().setDataLength(rec.page.len);                    rec.page.getPageHeader().setRecordCount(countRecordsInPage(rec.page));                    rec.page.setDirty(true);                    dataCache.add(rec.page);                    dataCache.add(newPage);                    rec.page = newPage;                    rec.page.len = 0;                }                ByteConversion.shortToByte(ItemId.setIsLink(currentId),                    rec.page.data, rec.page.len);                rec.page.len += 2;                long forwardLink = StorageAddress.createPointer((int) nextSplitPage                    .getPageNum(), tid);                ByteConversion.longToByte(forwardLink, rec.page.data, rec.page.len);                rec.page.len += 8;            }        }        if(nextSplitPage.len == 0) {            LOG.warn("page " + nextSplitPage.getPageNum() + " is empty. Remove it");            // if nothing has been copied to the last split page,            // remove it            dataCache.remove(nextSplitPage);            if(nextSplitPage == firstSplitPage)                firstSplitPage = null;            try {                unlinkPages(nextSplitPage.page);            } catch (IOException e) {                LOG.warn("Failed to remove empty split page: " + e.getMessage(), e);            }            nextSplitPage = null;        } else {	        nextSplitPage.getPageHeader().setDataLength(nextSplitPage.len);	        nextSplitPage.getPageHeader().setNextDataPage(	                rec.page.getPageHeader().getNextDataPage());	        nextSplitPage.getPageHeader().setRecordCount(splitRecordCount);	        nextSplitPage.setDirty(true);	        dataCache.add(nextSplitPage);	        firstSplitPage.getPageHeader().setPrevDataPage(rec.page.getPageNum());	        if(nextSplitPage != firstSplitPage) {	            firstSplitPage.setDirty(true);	            dataCache.add(firstSplitPage);	        }        }        long next = rec.page.getPageHeader().getNextDataPage();        if(-1 < next) {            DOMPage nextPage = getCurrentPage(next);            nextPage.getPageHeader().setPrevDataPage(nextSplitPage.getPageNum());            nextPage.setDirty(true);            dataCache.add(nextPage);        }        if(firstSplitPage != null) {            rec.page.getPageHeader().setNextDataPage(firstSplitPage.getPageNum());        }        rec.page.getPageHeader().setDataLength(rec.page.len);        rec.page.getPageHeader().setRecordCount(countRecordsInPage(rec.page));        rec.offset = rec.page.len;        return rec;    }