/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.github.geophile.erdo.segmentfilemanager.pagememorymanager; import java.nio.ByteBuffer; import java.util.ArrayDeque; import java.util.Queue; import java.util.logging.Level; import java.util.logging.Logger; /* * A Slab provides the memory from which pages are allocated. Initially, the entire slab is unused. Initial allocations * are done from the beginning. Later, page buffers are returned and kept in a list. When a page buffer is requested, * a returned page buffer is used if available. */ class Slab { public synchronized ByteBuffer takePageBuffer() { ByteBuffer buffer = available.isEmpty() ? takeNew() : takeUsed(); if (buffer != null) { assert buffer.position() == 0; assert buffer.remaining() == pageSize; } return buffer; } public void returnPageBuffer(ByteBuffer pageBuffer) { available.add(pageBuffer); } public Slab(int slabId, int slabSize, int pageSize) { this.slabId = slabId; this.pageSize = pageSize; long start = System.currentTimeMillis(); this.slab = ByteBuffer.allocate(slabSize); long stop = System.currentTimeMillis(); LOG.log(Level.INFO, "Allocated slab {0} of size {1} in {2} msec", new Object[]{slabId, slabSize, stop - start}); } public int slabId() { return slabId; } public byte[] byteArray() { return slab.array(); } public void clear() { available.clear(); slab.clear(); } private ByteBuffer takeNew() { ByteBuffer pageBuffer = null; if (slab.remaining() >= pageSize) { pageBuffer = slab.slice(); pageBuffer.limit(pageSize); slab.position(slab.position() + pageSize); } return pageBuffer; } private ByteBuffer takeUsed() { ByteBuffer buffer = available.remove(); buffer.position(0); return buffer; } private static final Logger LOG = Logger.getLogger(Slab.class.getName()); private final int slabId; private final int pageSize; private final ByteBuffer slab; private Queue<ByteBuffer> available = new ArrayDeque<>(); }