blob: 04e68c1552a927b5d8f2a5efab65731c933cd705 [file] [log] [blame]
/*
* 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.file;
import java.nio.ByteBuffer ;
import org.apache.jena.tdb.base.block.Block ;
import static org.apache.jena.tdb.sys.SystemTDB.SizeOfInt ;
/**
* FileAccess interface backed by a byte array.
*/
public class BlockAccessByteArray implements BlockAccess
{
private ByteBuffer bytes ;
private long length ; // Bytes in use: 0 to length-1
private long alloc ; // Bytes allocated
private final String label ;
public BlockAccessByteArray(String label)
{
bytes = ByteBuffer.allocate(1024) ;
length = 0 ;
alloc = 0 ;
this.label = label ;
}
@Override
public String getLabel () { return label ; }
@Override
public Block allocate(int size)
{
long addr = alloc ;
ByteBuffer bb = ByteBuffer.allocate(size) ;
alloc += (size + SizeOfInt) ;
return new Block((int)addr, bb) ;
}
@Override
public Block read(long id)
{
// Variable length blocks.
if ( id < 0 || id >= length || id >= bytes.capacity() )
throw new FileException("Bad id (read): "+id) ;
bytes.position((int)id) ;
int len = bytes.getInt() ;
ByteBuffer bb = ByteBuffer.allocate(len) ;
// Copy out the bytes - copy for safety.
bytes.get(bb.array(), 0, len) ;
return new Block(id, bb) ;
}
@Override
public void write(Block block)
{
// Variable length blocks.
long loc = block.getId() ;
if ( loc < 0 || loc > length ) // Can be equal => append.
throw new FileException("Bad id (write): "+loc+" ("+alloc+","+length+")") ;
ByteBuffer bb = block.getByteBuffer() ;
int len = bb.capacity() ;
if ( loc == length )
{
if ( bytes.capacity()-length < len )
{
int cap2 = bytes.capacity()+1024 ;
while(bytes.capacity()-length < len)
cap2 += 1024 ;
ByteBuffer bytes2 = ByteBuffer.allocate(cap2) ;
bytes2.position(0) ;
bytes2.put(bytes) ;
}
length += len +SizeOfInt ;
}
bytes.position((int)loc) ;
bytes.putInt(len) ;
bytes.put(bb.array(), 0, bb.capacity()) ;
}
@Override
public void overwrite(Block block)
{
write(block) ;
}
@Override
public boolean isEmpty()
{
return length == 0 ;
}
@Override
public boolean valid(long id)
{
return ( id >= 0 && id < length ) ;
}
@Override
public void sync()
{}
@Override
public void close()
{}
}