org.h2.pagestore.PageStreamData Maven / Gradle / Ivy
/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.pagestore;
import org.h2.engine.Session;
import org.h2.store.Data;
/**
* A data page of a stream. The format is:
*
* - page type: byte (0)
* - checksum: short (1-2)
* - the trunk page id: int (3-6)
* - log key: int (7-10)
* - data (11-)
*
*/
public class PageStreamData extends Page {
private static final int DATA_START = 11;
private final PageStore store;
private int trunk;
private int logKey;
private Data data;
private int remaining;
private PageStreamData(PageStore store, int pageId, int trunk, int logKey) {
setPos(pageId);
this.store = store;
this.trunk = trunk;
this.logKey = logKey;
}
/**
* Read a stream data page.
*
* @param store the page store
* @param data the data
* @param pageId the page id
* @return the page
*/
static PageStreamData read(PageStore store, Data data, int pageId) {
PageStreamData p = new PageStreamData(store, pageId, 0, 0);
p.data = data;
p.read();
return p;
}
/**
* Create a new stream trunk page.
*
* @param store the page store
* @param pageId the page id
* @param trunk the trunk page
* @param logKey the log key
* @return the page
*/
static PageStreamData create(PageStore store, int pageId, int trunk,
int logKey) {
return new PageStreamData(store, pageId, trunk, logKey);
}
/**
* Read the page from the disk.
*/
private void read() {
data.reset();
data.readByte();
data.readShortInt();
trunk = data.readInt();
logKey = data.readInt();
}
/**
* Write the header data.
*/
void initWrite() {
data = store.createData();
data.writeByte((byte) Page.TYPE_STREAM_DATA);
data.writeShortInt(0);
data.writeInt(trunk);
data.writeInt(logKey);
remaining = store.getPageSize() - data.length();
}
/**
* Write the data to the buffer.
*
* @param buff the source data
* @param offset the offset in the source buffer
* @param len the number of bytes to write
* @return the number of bytes written
*/
int write(byte[] buff, int offset, int len) {
int max = Math.min(remaining, len);
data.write(buff, offset, max);
remaining -= max;
return max;
}
@Override
public void write() {
store.writePage(getPos(), data);
}
/**
* Get the number of bytes that fit in a page.
*
* @param pageSize the page size
* @return the number of bytes
*/
static int getCapacity(int pageSize) {
return pageSize - DATA_START;
}
/**
* Read the next bytes from the buffer.
*
* @param startPos the position in the data page
* @param buff the target buffer
* @param off the offset in the target buffer
* @param len the number of bytes to read
*/
void read(int startPos, byte[] buff, int off, int len) {
System.arraycopy(data.getBytes(), startPos, buff, off, len);
}
/**
* Get the number of remaining data bytes of this page.
*
* @return the remaining byte count
*/
int getRemaining() {
return remaining;
}
/**
* Get the estimated memory size.
*
* @return number of double words (4 bytes)
*/
@Override
public int getMemory() {
return store.getPageSize() >> 2;
}
@Override
public void moveTo(Session session, int newPos) {
// not required
}
int getLogKey() {
return logKey;
}
@Override
public String toString() {
return "[" + getPos() + "] stream data key:" + logKey +
" pos:" + data.length() + " remaining:" + remaining;
}
@Override
public boolean canRemove() {
return true;
}
public static int getReadStart() {
return DATA_START;
}
@Override
public boolean canMove() {
return false;
}
}