/** * @param cnt Number of stripes. * @param mem Unsafe memory. */ GridUnsafeLru(short cnt, GridUnsafeMemory mem) { assert cnt > 0; assert mem != null; lrus = new LruStripe[cnt]; this.cnt = cnt; this.mem = mem; for (short i = 0; i < cnt; i++) lrus[i] = new LruStripe(i, mem); addIdx = new AtomicInteger(); rmvIdx = new AtomicInteger(cnt / 2); maxIdxCnt = cnt - 1; }
/** * Releases memory allocated for this queue. */ void destruct() { if (released.compareAndSet(false, true)) { for (int i = 0; i < cnt; i++) lrus[i].destruct(); } }
/** * Unlinks and releases queue node. * * @param qAddr Queue node address. */ private void unlink(long qAddr) { assert head != 0 && tail != 0; long prev = 0; long next = next(qAddr); if (head == qAddr) head = next; else { prev = previous(qAddr); assert prev != 0 : "Invalid previous link for stripe: " + order; next(prev, next); } if (next != 0) previous(next, prev); else { assert qAddr == tail; tail = prev; } mem.releaseSystem(qAddr, NODE); size--; assert head != 0 || (tail == 0 && size == 0); }
/** * Polls oldest entry from the queue. * * @return Queue node address. */ long prePoll() { lock.lock(); try { long n = head; while (n != 0) { if (!polling(n)) { // Mark as polling, but do not remove. // Node will be removed by explicitly calling remove. polling(n, true); break; } n = next(n); } return n; } finally { lock.unlock(); } }
/** * Removes queue node from queue. * * @param qAddr Address of queue node. */ void remove(long qAddr) { lock.lock(); try { // Don't remove polling entries (poll operation will remove them). if (!polling(qAddr)) unlink(qAddr); else // Update entry address in node to 0. entry(qAddr, 0); } finally { lock.unlock(); } }
/** * @param cnt Number of stripes. * @param mem Unsafe memory. */ GridUnsafeLru(short cnt, GridUnsafeMemory mem) { assert cnt > 0; assert mem != null; lrus = new LruStripe[cnt]; this.cnt = cnt; this.mem = mem; for (short i = 0; i < cnt; i++) lrus[i] = new LruStripe(i, mem); addIdx = new AtomicInteger(); rmvIdx = new AtomicInteger(cnt / 2); maxIdxCnt = cnt - 1; }
/** * Adds entry address to LRU queue. * * @param part Entry Entry partition. * @param addr Entry address. * @param hash Entry hash code. * @return Queue node address. * @throws GridOffHeapOutOfMemoryException If failed. */ long offer(int part, long addr, int hash) throws GridOffHeapOutOfMemoryException { return lrus[incrementAndGet(addIdx, maxIdxCnt)].offer(part, addr, hash); }
/** * Releases memory allocated for this queue. */ void destruct() { if (released.compareAndSet(false, true)) { for (int i = 0; i < cnt; i++) lrus[i].destruct(); } }
/** * Releases memory allocated for this queue stripe. */ void destruct() { lock.lock(); try { for (long n = head, prev = 0; n != 0; prev = n, n = next(n)) mem.releaseSystem(prev, NODE); } finally { lock.unlock(); } }
/** * @return Total memory consumed by all stripes. */ long memorySize() { long sum = 0; for (int i = 0; i < lrus.length; i++) sum += lrus[i].memorySize(); return sum; }
/** * Reads order of LRU stripe for queue node. * * @param qAddr Queue node address. * @return Order of LRU stripe. */ short order(long qAddr) { return LruStripe.order(qAddr, mem); }
/** * Polls oldest entry from the queue. * * @return Queue node address. */ long prePoll() { lock.lock(); try { long n = head; while (n != 0) { if (!polling(n)) { // Mark as polling, but do not remove. // Node will be removed by explicitly calling remove. polling(n, true); break; } n = next(n); } return n; } finally { lock.unlock(); } }
/** * Unlinks and releases queue node. * * @param qAddr Queue node address. */ private void unlink(long qAddr) { assert head != 0 && tail != 0; long prev = 0; long next = next(qAddr); if (head == qAddr) head = next; else { prev = previous(qAddr); assert prev != 0 : "Invalid previous link for stripe: " + order; next(prev, next); } if (next != 0) previous(next, prev); else { assert qAddr == tail; tail = prev; } mem.releaseSystem(qAddr, NODE); size--; assert head != 0 || (tail == 0 && size == 0); }