private SizeBucket newBucket(int size) { long offset = sizeMap.getLong(newBucketOffset); SizeBucket bucket = new SizeBucket(offset); bucket.count(0); bucket.size(size); bucket.prev(0); bucket.next(0); sizeMap.putLong(newBucketOffset, offset + bucketSize); return bucket; }
public void free(long position, int size) { SizeBucket bucket = findSizeBucket(size); if (bucket == null) { // create a new bucket with that size and put it as the first element of // bucket list for that size bucket = newBucket(size); sizeMap.putLong(sizeIndex(size), bucket.position); } else if (bucket.count() == bucket.max()) { SizeBucket newb = newBucket(size); newb.prev(bucket.position); newb.next(bucket.nextOffset()); bucket.next(newb.position); bucket = newb; } bucket.put(position); }
private void freeBucket(SizeBucket bucket) { // First, we need to unlink from the list. if (bucket.prevOffset() != 0) bucket.prev().next(bucket.nextOffset()); else sizeMap.putLong(sizeIndex(bucket.size()), bucket.nextOffset()); if (bucket.nextOffset() != 0) bucket.next().prev(bucket.prevOffset()); // Next, if this is not the last bucket block in the file, we want to swap // the last into it so as to reclaim that space long lastBucketPosition = sizeMap.getLong(newBucketOffset) - bucketSize; if (lastBucketPosition != bucket.position) { byte[] data = new byte[bucketSize]; try { read(lastBucketPosition, bucketSize).get(data); write(bucket.position, bucketSize).put(data); } catch (Throwable t) { throw new HGException(t); } } sizeMap.putLong(newBucketOffset, lastBucketPosition); }