/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.tdb.base.recordbuffer;
import java.nio.ByteBuffer;
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.tdb.base.block.Block ;
import org.apache.jena.tdb.base.buffer.RecordBuffer ;
import org.apache.jena.tdb.base.page.PageBase ;
import org.apache.jena.tdb.base.record.RecordFactory ;
import org.apache.jena.tdb.sys.SystemTDB ;
/** The on-disk form of a block of a single RecordBuffer
* (i.e. this is not part of a BTree/BPlusTree branch node).
* This must be compatible with B+Tree records nodes and hashbuckets.
*/
public abstract class RecordBufferPageBase extends PageBase //implements Page
{
// Field offsets
final public static int COUNT = 0 ;
// Length due to this class - subclasses may use more overhead.
final private static int FIELD_LENGTH = SystemTDB.SizeOfInt ;
protected final int headerLength ;
// Interface: "Page" - id, byteBuffer, count
protected RecordBuffer recBuff ;
private final RecordFactory factory ;
//private int offset ; // Bytes of overhead.
public static int calcRecordSize(RecordFactory factory, int blkSize, int headerOffset)
{
// Length = X*recordLength + HEADER
int x = blkSize-totalOffset(headerOffset) ;
return x / factory.recordLength() ;
}
public static int calcBlockSize(RecordFactory factory, int maxRec, int headerOffset)
{
return totalOffset(headerOffset) + factory.recordLength()*maxRec ;
}
private static int totalOffset(int headerOffset)
{
return FIELD_LENGTH+headerOffset ;
}
protected RecordBufferPageBase(Block block, int offset,
RecordFactory factory, int count)
{ // This code knows the alignment of the records in the ByteBuffer.
super(block) ;
this.headerLength = FIELD_LENGTH+offset ; // NB +4 for the count field
this.factory = factory ;
reset(block, count) ;
}
protected void reset(Block block, int count)
{
ByteBuffer bb = block.getByteBuffer() ;
bb.clear() ;
bb.position(headerLength) ;
bb = bb.slice();
this.recBuff = new RecordBuffer(bb, factory, count) ;
}
public final RecordBuffer getRecordBuffer()
{
return recBuff ;
}
public final int getCount()
{
return recBuff.size() ;
}
public final int getMaxSize()
{
return recBuff.maxSize() ;
}
public void setCount(int count)
{ recBuff.setSize(count) ; }
@Override
public String toString()
{ return String.format("RecordBufferPageBase[id=%d]: %s", getBackingBlock().getId(), recBuff) ; }
@Override
public void output(IndentedWriter out)
{ out.print(toString()) ; }
}