package edu.cmu.graphchi.datablocks; import java.util.ArrayList; /** * Copyright [2012] [Aapo Kyrola, Guy Blelloch, Carlos Guestrin / Carnegie Mellon University] * * Licensed 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. */ /** * Manages large chunks of data which are accessed using ChiPointers. * Used internally by GraphChi. * @author akyrola */ public class DataBlockManager { private ArrayList<byte[]> blocks = new ArrayList<byte[]>(32678); public DataBlockManager() { } public int allocateBlock(int numBytes) { byte[] dataBlock = new byte[numBytes]; synchronized(blocks) { int blockId = blocks.size(); blocks.add(blockId, dataBlock); return blockId; } } public byte[] getRawBlock(int blockId) { byte[] bb = blocks.get(blockId); /* Note, not synchronized! */ if (bb == null) { throw new IllegalStateException("Null-reference!"); } return bb; } /** * Called by the engine to clear the registry. All blocks must be null * prior to calling! */ public void reset() { for(int i=0; i<blocks.size(); i++) { if (blocks.get(i) != null) { throw new RuntimeException("Tried to reset block manager, but it was non-empty at index: " + i); } } blocks.clear(); } public boolean empty() { for(int i=0; i<blocks.size(); i++) { if (blocks.get(i) != null) { return false; } } return true; } public void release(int blockId) { blocks.set(blockId, null); } public <T> T dereference(ChiPointer ptr, BytesToValueConverter<T> conv) { byte[] arr = new byte[conv.sizeOf()]; if (ptr == null) { throw new IllegalStateException("Tried to dereference a null pointer!"); } System.arraycopy(getRawBlock(ptr.blockId), ptr.offset, arr, 0, arr.length); return conv.getValue(arr); } public <T> void writeValue(ChiPointer ptr, BytesToValueConverter<T> conv, T value) { byte[] arr = new byte[conv.sizeOf()]; conv.setValue(arr, value); System.arraycopy(arr, 0, getRawBlock(ptr.blockId), ptr.offset, arr.length); } public <T> void writeValue(ChiPointer ptr, byte[] data) { System.arraycopy(data, 0, getRawBlock(ptr.blockId), ptr.offset, data.length); } }