int chunkSize = fileHeader.getWorkSize() - ph.getDataLength();
final int chunkLen = chunk.size();
if (chunkLen < chunkSize) {chunkSize = chunkLen;}
// fill last page
if (isTransactional && transaction != null) {
final Loggable loggable =
new OverflowAppendLoggable(fileId, transaction, page.getPageNum(), chunk, 0, chunkSize);
writeToLog(loggable, page);
}
chunk.copyTo(0, page.getData(), ph.getDataLength(), chunkSize);
if(page != firstPage)
{ph.setDataLength(ph.getDataLength() + chunkSize);}
page.setDirty(true);
// write the remaining chunks to new pages
int remaining = chunkLen - chunkSize;
int current = chunkSize;
chunkSize = fileHeader.getWorkSize();
if (remaining > 0) {
// walk through chain of pages
while (remaining > 0) {
if (remaining < chunkSize) {chunkSize = remaining;}
// add a new page to the chain
nextPage = createDataPage();
if (isTransactional && transaction != null) {
Loggable loggable = new OverflowCreatePageLoggable(transaction, fileId, nextPage.getPageNum(),
page.getPageNum());
writeToLog(loggable, nextPage);
loggable = new OverflowAppendLoggable(fileId, transaction, nextPage.getPageNum(),
chunk, current, chunkSize);
writeToLog(loggable, page);
}
nextPage.setData(new byte[fileHeader.getWorkSize()]);
page.getPageHeader().setNextInChain(nextPage.getPageNum());
page.setDirty(true);
dataCache.add(page);
page = nextPage;
// copy next chunk of data to the page
chunk.copyTo(current, page.getData(), 0, chunkSize);
page.setDirty(true);
if (page != firstPage)
{page.getPageHeader().setDataLength(chunkSize);}
remaining = remaining - chunkSize;
current += chunkSize;
}
}
ph = firstPage.getPageHeader();
if (isTransactional && transaction != null) {
final Loggable loggable = new OverflowModifiedLoggable(fileId, transaction, firstPage.getPageNum(),
ph.getDataLength() + chunkLen, ph.getDataLength(), page == firstPage ? 0 : page.getPageNum());
writeToLog(loggable, page);
}
if (page != firstPage) {
// add link to last page