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