/** * get the address from a memory chunk holder. * * @param mchunk * specify the memory chunk holder * * @return an address that could be used to retrieve its memory chunk */ @Override public long getChunkAddress(MemChunkHolder<VolatileMemAllocator> mchunk) { return mchunk.get(); }
@Override public void restoreDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy, DurableType[] gField, long phandler, boolean autoReclaim, ReclaimContext rctx) throws RestoreDurableEntityError { initializeDurableEntity(allocator, factoryProxy, gField, autoReclaim, rctx); if (0L == phandler) { throw new RestoreDurableEntityError("Input handler is null on restoreDurableEntity."); } chunkAddr = allocator.retrieveChunk(phandler, autoReclaim, reclaimcontext); long chunkHandler = unsafe.getLong(chunkAddr.get()); holder = allocator.retrieveChunk(chunkHandler, autoReclaim, reclaimcontext); if (null == holder || null == chunkAddr) { throw new RestoreDurableEntityError("Retrieve Entity Failure!"); } setCapacityHint(holder.getSize() / MAX_OBJECT_SIZE); mapSize = recomputeMapSize(); initializeAfterRestore(); }
/** * get the address from a memory chunk holder. * * @param mchunk * specify the memory chunk holder * * @return an address that could be used to retrieve its memory chunk */ @Override public long getChunkAddress(MemChunkHolder<NonVolatileMemAllocator> mchunk) { return mchunk.get(); }
@Override public void destroy() throws RetrieveDurableEntityError { long startAddr = holder.get(); long endAddr = startAddr + MAX_OBJECT_SIZE * arraySize; int index = 0; while (startAddr < endAddr) { if (null != get(index)) { genericField[index] = null; } index++; startAddr += MAX_OBJECT_SIZE; } holder.destroy(); }
/** * Return a value to which key is mapped * * @param key * the key whose value is to be retrieved * * @return previous value with key else return null */ @Override public V get(K key) { int hash = hash(key.hashCode()); long bucketIndex = getBucketIndex(hash); long bucketAddr = holder.get() + MAX_OBJECT_SIZE * bucketIndex; return getEntry(key, bucketAddr); }
/** * Remove a mapping for a specified key * * @param key * the key whose value is to be removed * * @return previous value with key else return null */ @Override public V remove(K key) { int hash = hash(key.hashCode()); long bucketIndex = getBucketIndex(hash); long bucketAddr = holder.get() + MAX_OBJECT_SIZE * bucketIndex; return removeEntry(key, bucketAddr); }
@Override public void restoreDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy, DurableType[] gType, long phandler, boolean autoReclaim, ReclaimContext rctx) throws RestoreDurableEntityError { initializeDurableEntity(allocator, factoryProxy, gType, autoReclaim, rctx); if (0L == phandler) { throw new RestoreDurableEntityError("Input handler is null on restoreDurableEntity."); } holder = allocator.retrieveChunk(phandler, autoReclaim); long rootHandler = unsafe.getLong(holder.get()); root = TreeNodeFactory.restore(allocator, factoryProxy, genericType, rootHandler, autoReclaim, reclaimcontext); initializeAfterRestore(); }
@Override public void createDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy, DurableType[] gField, boolean autoReclaim, ReclaimContext rctx) throws OutOfHybridMemory { initializeDurableEntity(allocator, factoryProxy, gField, autoReclaim, rctx); this.holder = allocator.createChunk(MAX_OBJECT_SIZE * totalCapacity, autoReclaim, reclaimcontext); this.chunkAddr = allocator.createChunk(MAX_OBJECT_SIZE, autoReclaim, reclaimcontext); unsafe.putLong(chunkAddr.get(), allocator.getChunkHandler(holder)); if (null == this.holder || null == this.chunkAddr) { throw new OutOfHybridMemory("Create Durable Entity Error!"); } initializeAfterCreate(); }
/** * Recomputes the size of the map during restore without persistence * * @return size of the map */ protected long recomputeMapSize() { long size = 0; long bucketAddr = holder.get(); long maxbucketAddr = bucketAddr + MAX_OBJECT_SIZE * totalCapacity; while (bucketAddr < maxbucketAddr) { long handler = unsafe.getAddress(bucketAddr); if (0L != handler) { SinglyLinkedNode<MapEntry<K, V>> head = SinglyLinkedNodeFactory.restore(allocator, listefproxies, listgftypes, handler, false, reclaimcontext); while (null != head) { size++; head = head.getNext(); } } bucketAddr += MAX_OBJECT_SIZE; } return size; }
/** * Add a new key-value pair to map * * @param key * the key to be set * * @param value * the value to be set * * @return previous value with key else return null */ @Override public V put(K key, V value) throws OutOfHybridMemory { int hash = hash(key.hashCode()); long bucketIndex = getBucketIndex(hash); long bucketAddr = holder.get() + MAX_OBJECT_SIZE * bucketIndex; V retVal = addEntry(key, value, bucketAddr); if (autoResize && (mapSize >= threshold)) { resize(2 * totalCapacity); } return retVal; }
long bucketAddr = prevHolder.get(); long maxbucketAddr = bucketAddr + MAX_OBJECT_SIZE * totalCapacity; holder = allocator.createChunk(MAX_OBJECT_SIZE * newCapacity, autoReclaim); unsafe.putLong(chunkAddr.get(), allocator.getChunkHandler(holder)); while (bucketAddr < maxbucketAddr) { long handler = unsafe.getAddress(bucketAddr);
/** * Transfers a map item from old map to the new map * * @param elem * the item in the old map */ protected void transfer(SinglyLinkedNode<MapEntry<K, V>> elem) { int hash = hash(elem.getItem().getKey().hashCode()); long bucketIndex = getBucketIndex(hash); long bucketAddr = holder.get() + MAX_OBJECT_SIZE * bucketIndex; long handler = unsafe.getAddress(bucketAddr); if (0L != handler) { SinglyLinkedNode<MapEntry<K, V>> head = SinglyLinkedNodeFactory.restore(allocator, listefproxies, listgftypes, handler, false, reclaimcontext); elem.setNext(head, false); } else { elem.setNext(null, false); } unsafe.putLong(bucketAddr, elem.getHandler()); }
/** * get item from the given index of array * * @return item from the given index of array */ public E get(int index) { if (index >= arraySize) { throw new RetrieveDurableEntityError("Index greater than array size."); } if (null == genericField[index]) { EntityFactoryProxy proxy = null; DurableType gftype = null; if (null != factoryProxy) { proxy = factoryProxy[0]; } if (null != genericType) { gftype = genericType[0]; } else { throw new RetrieveDurableEntityError("No Generic Field Type Info."); } genericField[index] = new GenericField<A, E>(proxy, gftype, factoryProxy, genericType, allocator, unsafe, autoReclaim, reclaimcontext, holder.get() + index * MAX_OBJECT_SIZE); } if (null != genericField[index]) { return ((GenericField<A, E>)genericField[index]).get(); } else { throw new RetrieveDurableEntityError("GenericField is null!"); } }
protected void replace(TreeNode<E> first, TreeNode<E> second) { if (null == first.getParent()) { root = second; unsafe.putLong(holder.get(), root.getHandler()); } else if (first.equals(first.getParent().getLeft())) { first.getParent().setLeft(second, false); } else { first.getParent().setRight(second, false); } if (second != null) { second.setParent(first.getParent(), false); } }
unsafe, autoReclaim, reclaimcontext, holder.get() + index * MAX_OBJECT_SIZE);
@Override public void destroy() throws RetrieveDurableEntityError { long bucketAddr = holder.get(); long maxbucketAddr = bucketAddr + MAX_OBJECT_SIZE * totalCapacity; SinglyLinkedNode<MapEntry<K, V>> head, prev; while (bucketAddr < maxbucketAddr) { long handler = unsafe.getAddress(bucketAddr); if (0L != handler) { head = SinglyLinkedNodeFactory.restore(allocator, listefproxies, listgftypes, handler, false, reclaimcontext); prev = head; while (null != head) { head = head.getNext(); prev.destroy(); //TODO: Destroy head in a cascading way prev = head; } } bucketAddr += MAX_OBJECT_SIZE; } holder.destroy(); chunkAddr.destroy(); }
protected void rotateRight(TreeNode<E> currentNode) { if (currentNode.getParent() != null) { if (currentNode.equals(currentNode.getParent().getLeft())) { currentNode.getParent().setLeft(currentNode.getLeft(), false); } else { currentNode.getParent().setRight(currentNode.getLeft(), false); } currentNode.getLeft().setParent(currentNode.getParent(), false); currentNode.setParent(currentNode.getLeft(), false); if (currentNode.getLeft().getRight() != null) { currentNode.getLeft().getRight().setParent(currentNode, false); } currentNode.setLeft(currentNode.getLeft().getRight(), false); currentNode.getParent().setRight(currentNode, false); } else { TreeNode<E> left = root.getLeft(); root.setLeft(root.getLeft().getRight(), false); if (left.getRight() != null) { left.getRight().setParent(root, false); } root.setParent(left, false); left.setRight(root, false); left.setParent(null, false); root = left; unsafe.putLong(holder.get(), root.getHandler()); } }
protected void rotateLeft(TreeNode<E> currentNode) { if (currentNode.getParent() != null) { if (currentNode.equals(currentNode.getParent().getLeft())) { currentNode.getParent().setLeft(currentNode.getRight(), false); } else { currentNode.getParent().setRight(currentNode.getRight(), false); } currentNode.getRight().setParent(currentNode.getParent(), false); currentNode.setParent(currentNode.getRight(), false); if (currentNode.getRight().getLeft() != null) { currentNode.getRight().getLeft().setParent(currentNode, false); } currentNode.setRight(currentNode.getRight().getLeft(), false); currentNode.getParent().setLeft(currentNode, false); } else { TreeNode<E> right = root.getRight(); root.setRight(right.getLeft(), false); if (right.getLeft() != null) { right.getLeft().setParent(root, false); } root.setParent(right, false); right.setLeft(root, false); right.setParent(null, false); root = right; unsafe.putLong(holder.get(), root.getHandler()); } }