ByteBuffer release(ByteBuffer buffer) { if (buffer != null) { allocator.release(buffer); } return null; }
/** * See docs on CodecFactory#createDirectCodecFactory which is how this class is * exposed publicly and is just a pass-through factory method for this constructor * to hide the rest of this class from public access. */ DirectCodecFactory(Configuration config, ByteBufferAllocator allocator, int pageSize) { super(config, pageSize); Preconditions.checkNotNull(allocator, "allocator"); Preconditions.checkState(allocator.isDirect(), "A %s requires a direct buffer allocator be provided.", getClass().getSimpleName()); this.allocator = allocator; }
/** * See docs on CodecFactory#createDirectCodecFactory which is how this class is * exposed publicly and is just a pass-through factory method for this constructor * to hide the rest of this class from public access. */ DirectCodecFactory(Configuration config, ByteBufferAllocator allocator, int pageSize) { super(config, pageSize); Preconditions.checkNotNull(allocator, "allocator"); Preconditions.checkState(allocator.isDirect(), "A %s requires a direct buffer allocator be provided.", getClass().getSimpleName()); this.allocator = allocator; }
ByteBuffer release(ByteBuffer buffer) { if (buffer != null) { allocator.release(buffer); } return null; }
/** * When re-using an instance with reset, it will adjust slab size based on previous data size. * The intent is to reuse the same instance for the same type of data (for example, the same column). * The assumption is that the size in the buffer will be consistent. */ public void reset() { // readjust slab size. // 7 = 2^3 - 1 so that doubling the initial size 3 times will get to the same size this.initialSlabSize = max(bytesUsed / 7, initialSlabSize); LOG.debug("initial slab of size {}", initialSlabSize); for (ByteBuffer slab : slabs) { allocator.release(slab); } this.slabs.clear(); this.bytesAllocated = 0; this.bytesUsed = 0; this.currentSlab = EMPTY_SLAB; this.currentSlabIndex = 0; }
/** * the new slab is guaranteed to be at least minimumSize * @param minimumSize the size of the data we want to copy in the new slab */ private void addSlab(int minimumSize) { int nextSlabSize; if (bytesUsed == 0) { nextSlabSize = initialSlabSize; } else if (bytesUsed > maxCapacityHint / 5) { // to avoid an overhead of up to twice the needed size, we get linear when approaching target page size nextSlabSize = maxCapacityHint / 5; } else { // double the size every time nextSlabSize = bytesUsed; } if (nextSlabSize < minimumSize) { LOG.debug("slab size {} too small for value of size {}. Bumping up slab size", nextSlabSize, minimumSize); nextSlabSize = minimumSize; } LOG.debug("used {} slabs, adding new slab of size {}", slabs.size(), nextSlabSize); this.currentSlab = allocator.allocate(nextSlabSize); this.slabs.add(currentSlab); this.bytesAllocated += nextSlabSize; this.currentSlabIndex = 0; }
/** * When re-using an instance with reset, it will adjust slab size based on previous data size. * The intent is to reuse the same instance for the same type of data (for example, the same column). * The assumption is that the size in the buffer will be consistent. */ public void reset() { // readjust slab size. // 7 = 2^3 - 1 so that doubling the initial size 3 times will get to the same size this.initialSlabSize = max(bytesUsed / 7, initialSlabSize); LOG.debug("initial slab of size {}", initialSlabSize); for (ByteBuffer slab : slabs) { allocator.release(slab); } this.slabs.clear(); this.bytesAllocated = 0; this.bytesUsed = 0; this.currentSlab = EMPTY_SLAB; this.currentSlabIndex = 0; }
/** * the new slab is guaranteed to be at least minimumSize * @param minimumSize the size of the data we want to copy in the new slab */ private void addSlab(int minimumSize) { int nextSlabSize; if (bytesUsed == 0) { nextSlabSize = initialSlabSize; } else if (bytesUsed > maxCapacityHint / 5) { // to avoid an overhead of up to twice the needed size, we get linear when approaching target page size nextSlabSize = maxCapacityHint / 5; } else { // double the size every time nextSlabSize = bytesUsed; } if (nextSlabSize < minimumSize) { LOG.debug("slab size {} too small for value of size {}. Bumping up slab size", nextSlabSize, minimumSize); nextSlabSize = minimumSize; } LOG.debug("used {} slabs, adding new slab of size {}", slabs.size(), nextSlabSize); this.currentSlab = allocator.allocate(nextSlabSize); this.slabs.add(currentSlab); this.bytesAllocated += nextSlabSize; this.currentSlabIndex = 0; }
@Override public void close() { for (ByteBuffer slab : slabs) { allocator.release(slab); } try { super.close(); }catch(IOException e){ throw new OutputStreamCloseException(e); } } }
/** * @param f file to read the blocks from * @return the ByteBuffer blocks * @throws IOException if there is an error while reading from the stream */ List<ByteBuffer> readBlocks(SeekableInputStream f, long offset, int length) throws IOException { f.seek(offset); int fullAllocations = length / options.getMaxAllocationSize(); int lastAllocationSize = length % options.getMaxAllocationSize(); int numAllocations = fullAllocations + (lastAllocationSize > 0 ? 1 : 0); List<ByteBuffer> buffers = new ArrayList<>(numAllocations); for (int i = 0; i < fullAllocations; i++) { buffers.add(options.getAllocator().allocate(options.getMaxAllocationSize())); } if (lastAllocationSize > 0) { buffers.add(options.getAllocator().allocate(lastAllocationSize)); } for (ByteBuffer buffer : buffers) { f.readFully(buffer); buffer.flip(); } return buffers; }
@Override public void close() { for (ByteBuffer slab : slabs) { allocator.release(slab); } try { super.close(); }catch(IOException e){ throw new OutputStreamCloseException(e); } } }