/* * 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() {} }