/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.github.geophile.erdo.map.diskmap;
import com.github.geophile.erdo.map.Factory;
import java.nio.ByteBuffer;
class TimestampSection extends DiskPageSectionFixedLengthRecords
{
// DiskPageSection interface
@Override
public void close()
{
timestamps.close();
// Timestamp section metadata
timestampBase = timestamps.min();
metadataAppendULong(timestampBase);
metadataAppendUByte(timestamps.deltaBytes());
metadataClose();
recordSize(timestamps.deltaBytes());
// Write the deltas (relative to the min timestamp)
append(timestamps);
super.close();
}
// TimestampSection interface
public void append(long timestamp)
{
timestamps.append(timestamp);
}
public void removeLast()
{
timestamps.removeLast();
}
public long timestamp(int position)
{
return timestamps.at(position);
}
// Size within a disk page. If not closed (which is expected usage), then figure it out from the header
// size (available from super.size(), known now), and timestamps.
public int size()
{
int size = super.size();
if (state != State.CLOSED) {
size += timestamps.size() * timestamps.deltaBytes();
}
return size;
}
public static TimestampSection forRead(ByteBuffer pageBuffer)
{
return new TimestampSection(pageBuffer);
}
public static TimestampSection forWrite(ByteBuffer buffer, Factory factory)
{
return new TimestampSection(buffer, factory);
}
// For use by this class
private TimestampSection(ByteBuffer pageBuffer)
{
super(pageBuffer);
timestampBase = metadataULong(0);
int deltaSize = metadataUByte(TIMESTAMP_BASE_SIZE);
timestamps = new CompressibleLongArray(timestampBase, count, deltaSize);
timestamps.readFrom(pageBuffer);
pageBuffer.position(dataPosition + count * timestamps.deltaBytes());
}
private TimestampSection(ByteBuffer buffer, Factory factory)
{
super(TIMESTAMP_SECTION_METADATA_SIZE, buffer);
int pageSize = factory.configuration().diskPageSizeBytes();
// pageSize / 8 is big enough to accomodate 8-byte records. If that's not enough,
// CompressibleLongArray grows.
timestamps = new CompressibleLongArray(pageSize / 8);
}
// Class state
// 8 bytes for timestampBase. 1 byte for delta size.
private static final int TIMESTAMP_BASE_SIZE = 8;
private static final int TIMESTAMP_DELTA_BYTES_SIZE = 1;
private static final int TIMESTAMP_SECTION_METADATA_SIZE = TIMESTAMP_BASE_SIZE + TIMESTAMP_DELTA_BYTES_SIZE;
// Object state
private long timestampBase;
private CompressibleLongArray timestamps;
}