@Override void getBlock(URI uri, long tick) { Buff duplicate = null; synchronized (this) { if (Debug.THREADS) ThreadAssert.resume(this, false); int index = Tick.indexOf(_ticks, tick); if (index >= 0) { Buff buff = _buffs[index]; if (buff != null) { duplicate = buff.duplicate(); if (Debug.THREADS) ThreadAssert.exchangeGive(duplicate, duplicate); } } if (Debug.THREADS) ThreadAssert.suspend(this); } if (duplicate != null) { Buff[] duplicates = new Buff[] {duplicate}; if (Debug.THREADS) { ThreadAssert.exchangeTake(duplicate); ThreadAssert.exchangeGive(duplicates, duplicate); } uri.onBlock(this, tick, duplicates, null, true, null, false, null); if (Debug.THREADS) ThreadAssert.exchangeTake(duplicates); duplicate.recycle(); } }
@Override void onBlock(URI uri, long tick, Buff[] buffs, long[] removals, boolean requested) { int capacity = 0; if (Debug.THREADS) ThreadAssert.exchangeTake(buffs); for (int i = 0; i < buffs.length; i++) capacity += buffs[i].remaining(); Buff buff = Buff.createCustom(capacity, false); if (Stats.ENABLED) Stats.Instance.MemoryBlocksCreated.incrementAndGet(); for (int i = 0; i < buffs.length; i++) { buff.putImmutably(buffs[i]); if (Debug.THREADS) ThreadAssert.exchangeGive(buffs, buffs[i]); } if (Debug.ENABLED) Debug.assertion(buff.remaining() == 0); buff.position(0); buff.mark(); List<Buff> recycle = null; if (Debug.THREADS) ThreadAssert.exchangeGive(buff, buff); synchronized (this) { if (Debug.THREADS) { ThreadAssert.resume(this, false); ThreadAssert.exchangeTake(buff); } int index = Tick.indexOf(_ticks, tick); if (index < 0) { index = add(tick); _buffs[index] = buff; if (Stats.ENABLED) Stats.Instance.MemoryBlocksLive.incrementAndGet(); } else { if (Debug.ENABLED) Debug.assertion(_buffs[index] != null); recycle = new List<Buff>(); recycle.add(buff); } for (int i = 0; removals != null && i < removals.length; i++) { if (!Tick.isNull(removals[i])) { index = Tick.remove(_ticks, removals[i]); if (index >= 0) { if (recycle == null) recycle = new List<Buff>(); recycle.add(_buffs[index]); _buffs[index] = null; if (Stats.ENABLED) Stats.Instance.MemoryBlocksLive.decrementAndGet(); } } } if (Debug.THREADS) { for (int i = 0; recycle != null && i < recycle.size(); i++) ThreadAssert.exchangeGive(recycle, recycle.get(i)); ThreadAssert.suspend(this); } } if (!location().isCache()) { uri.onAck(this, tick); if (Stats.ENABLED) Stats.Instance.AckCreated.incrementAndGet(); } if (recycle != null) { if (Debug.THREADS) ThreadAssert.exchangeTake(recycle); for (int i = 0; i < recycle.size(); i++) recycle.get(i).recycle(); } }