public synchronized long getAllocatedSize() { long sum = 0; for (PowerOfTwoAllocator a : sliceAllocators) { sum += a.occupied(); } return sum; }
public long getAllocatedSizeUnSync() { long sum = 0; for (PowerOfTwoAllocator a : sliceAllocators) { sum += a.occupied(); } return sum; }
private Page allocateAsThief(final int size, boolean victim, OffHeapStorageArea owner) { Page free = allocateFromFree(size, victim, owner); if (free != null) { return free; } // do thieving here... PowerOfTwoAllocator victimAllocator = null; PowerOfTwoAllocator sliceAllocator = null; List<Page> targets = Collections.emptyList(); Collection<AllocatedRegion> tempHolds = new ArrayList<AllocatedRegion>(); Map<OffHeapStorageArea, Collection<Page>> releases = new IdentityHashMap<OffHeapStorageArea, Collection<Page>>(); synchronized (this) { for (int i = 0; i < victimAllocators.size(); i++) { int address = victimAllocators.get(i).find(size, victim ? CEILING : FLOOR); if (address >= 0) { victimAllocator = victimAllocators.get(i); sliceAllocator = sliceAllocators.get(i); targets = findVictimPages(i, address, size); // need to claim everything that falls within the range of our allocation int claimAddress = address; for (Page p : targets) { victimAllocator.claim(p.address(), p.size()); int claimSize = p.address() - claimAddress; if (claimSize > 0) { tempHolds.add(new AllocatedRegion(claimAddress, claimSize)); sliceAllocator.claim(claimAddress, claimSize); victimAllocator.claim(claimAddress, claimSize); } claimAddress = p.address() + p.size(); } int claimSize = (address + size) - claimAddress; if (claimSize > 0) { tempHolds.add(new AllocatedRegion(claimAddress, claimSize)); sliceAllocator.claim(claimAddress, claimSize); victimAllocator.claim(claimAddress, claimSize); } break; } } for (Page p : targets) { OffHeapStorageArea a = p.binding(); Collection<Page> c = releases.get(a); if (c == null) { c = new LinkedList<Page>(); c.add(p); releases.put(a, c); } else { c.add(p); } } } /* * Drop the page source synchronization here to prevent deadlock against * map/cache threads. */ Collection<Page> results = new LinkedList<Page>(); for (Entry<OffHeapStorageArea, Collection<Page>> e : releases.entrySet()) { OffHeapStorageArea a = e.getKey(); Collection<Page> p = e.getValue(); results.addAll(a.release(p)); } List<Page> failedReleases = new ArrayList<Page>(); synchronized (this) { for (AllocatedRegion r : tempHolds) { sliceAllocator.free(r.address, r.size); victimAllocator.free(r.address, r.size); } if (results.size() == targets.size()) { for (Page p : targets) { victimAllocator.free(p.address(), p.size()); free(p); } return allocateFromFree(size, victim, owner); } else { for (Page p : targets) { if (results.contains(p)) { victimAllocator.free(p.address(), p.size()); free(p); } else { failedReleases.add(p); } } } } try { return allocateAsThief(size, victim, owner); } finally { synchronized (this) { for (Page p : failedReleases) { // this is just an ugly way of doing an identity equals based contains if (victims.get(p.index()).floor(p) == p) { victimAllocator.free(p.address(), p.size()); } } } } }