public static <T extends Closeable> ReferenceCountingResourceHolder<T> fromCloseable(final T object) { return new ReferenceCountingResourceHolder<>(object, object); }
/** * Decrements the reference count by 1. If it reaches to 0, then closes {@link #closer}. */ @Override public void close() { if (closed.compareAndSet(false, true)) { decrement(); } else { log.warn(new ISE("Already closed"), "Already closed"); } }
public GroupByQueryResource(List<ReferenceCountingResourceHolder<ByteBuffer>> mergeBufferHolders) { this.mergeBufferHolders = mergeBufferHolders; this.mergeBuffers = new ArrayDeque<>(mergeBufferHolders.size()); mergeBufferHolders.forEach(holder -> mergeBuffers.add(holder.get())); }
private void createDanglingReleaser(AtomicBoolean released) { try (ReferenceCountingResourceHolder<Closeable> handler = makeReleasingHandler(released)) { handler.increment(); // Releaser not close, the object leaked } }
@Override public void run() { for (ReferenceCountingResourceHolder<Integer> holder : r2) { if (holder != null) { holder.close(); } } } });
@Test(timeout = 60_000L) public void testResourceHandlerClearedByJVM() throws InterruptedException { long initialLeakedResources = ReferenceCountingResourceHolder.leakedResources(); final AtomicBoolean released = new AtomicBoolean(false); makeReleasingHandler(released); // Don't store the handler in a variable and don't close it, the object leaked verifyCleanerRun(released, initialLeakedResources); }
private ReferenceCountingResourceHolder<Closeable> makeReleasingHandler(final AtomicBoolean released) { return ReferenceCountingResourceHolder .fromCloseable((Closeable) new Closeable() { @Override public void close() { released.set(true); } }); }
@Override public Void call() { try ( CloseableIterator<Entry<KeyType>> mergedIterator = CloseableIterators.mergeSorted( iterators, keyObjComparator ); // This variable is used to close releaser automatically. @SuppressWarnings("unused") final Releaser releaser = combineBufferHolder.increment() ) { while (mergedIterator.hasNext()) { final Entry<KeyType> next = mergedIterator.next(); settableColumnSelectorFactory.set(next.values); grouper.aggregate(next.key); // grouper always returns ok or throws an exception settableColumnSelectorFactory.set(null); } } catch (IOException e) { throw Throwables.propagate(e); } grouper.finish(); return null; } }
@Override public void run() { for (ReferenceCountingResourceHolder<Integer> holder : r1) { if (holder != null) { holder.close(); } } } });
@Test(timeout = 60_000L) public void testResourceHandlerWithReleaserClearedByJVM() throws InterruptedException { long initialLeakedResources = ReferenceCountingResourceHolder.leakedResources(); final AtomicBoolean released = new AtomicBoolean(false); // createDanglingReleaser() need to be a separate method because otherwise JVM preserves a ref to Holder on stack // and Cleaner is not called createDanglingReleaser(released); verifyCleanerRun(released, initialLeakedResources); }
@Override public ByteBuffer get() { taken = true; return super.get(); } }
@Nullable private ReferenceCountingResourceHolder<T> wrapObject(T theObject) { return theObject == null ? null : new ReferenceCountingResourceHolder<>( theObject, () -> offer(theObject) ); }
@Override public Void call() { try ( CloseableIterator<Entry<KeyType>> mergedIterator = CloseableIterators.mergeSorted( iterators, keyObjComparator ); // This variable is used to close releaser automatically. @SuppressWarnings("unused") final Releaser releaser = combineBufferHolder.increment() ) { while (mergedIterator.hasNext()) { final Entry<KeyType> next = mergedIterator.next(); settableColumnSelectorFactory.set(next.values); grouper.aggregate(next.key); // grouper always returns ok or throws an exception settableColumnSelectorFactory.set(null); } } catch (IOException e) { throw Throwables.propagate(e); } grouper.finish(); return null; } }
/** * Decrements the reference count by 1. If it reaches to 0, then closes {@link #closer}. */ @Override public void close() { if (closed.compareAndSet(false, true)) { decrement(); } else { log.warn(new ISE("Already closed"), "Already closed"); } }
@Test(timeout = 60_000L) public void testTake() { final ReferenceCountingResourceHolder<Integer> holder = pool.take(100); assertNotNull(holder); assertEquals(9, pool.getPoolSize()); holder.close(); assertEquals(10, pool.getPoolSize()); }
final ByteBuffer combineBuffer = combineBufferHolder.get(); final int minimumRequiredBufferCapacity = StreamingMergeSortedGrouper.requiredBufferCapacity( combineKeySerdeFactory.factorizeWithDictionary(mergedDictionary),
public static <T extends Closeable> ReferenceCountingResourceHolder<T> fromCloseable(final T object) { return new ReferenceCountingResourceHolder<>(object, object); }
public GroupByQueryResource(List<ReferenceCountingResourceHolder<ByteBuffer>> mergeBufferHolders) { this.mergeBufferHolders = mergeBufferHolders; this.mergeBuffers = new ArrayDeque<>(mergeBufferHolders.size()); mergeBufferHolders.forEach(holder -> mergeBuffers.add(holder.get())); }
@Nullable private ReferenceCountingResourceHolder<T> wrapObject(T theObject) { return theObject == null ? null : new ReferenceCountingResourceHolder<>( theObject, () -> offer(theObject) ); }