|
@@ -29,7 +29,7 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
|
|
|
|
|
|
private static final ReleasableBytesReference EMPTY = new ReleasableBytesReference(BytesArray.EMPTY, RefCounted.ALWAYS_REFERENCED);
|
|
|
|
|
|
- private final BytesReference delegate;
|
|
|
+ private BytesReference delegate;
|
|
|
private final RefCounted refCounted;
|
|
|
|
|
|
public static ReleasableBytesReference empty() {
|
|
@@ -63,20 +63,29 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
|
|
|
|
|
|
@Override
|
|
|
public boolean decRef() {
|
|
|
- return refCounted.decRef();
|
|
|
+ boolean res = refCounted.decRef();
|
|
|
+ if (res) {
|
|
|
+ delegate = null;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean hasReferences() {
|
|
|
- return refCounted.hasReferences();
|
|
|
+ boolean hasRef = refCounted.hasReferences();
|
|
|
+ // delegate is nulled out when the ref-count reaches zero but only via a plain store, and also we could be racing with a concurrent
|
|
|
+ // decRef so need to check #refCounted again in case we run into a non-null delegate but saw a reference before
|
|
|
+ assert delegate != null || refCounted.hasReferences() == false;
|
|
|
+ return hasRef;
|
|
|
}
|
|
|
|
|
|
public ReleasableBytesReference retain() {
|
|
|
- refCounted.incRef();
|
|
|
+ refCounted.mustIncRef();
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
public ReleasableBytesReference retainedSlice(int from, int length) {
|
|
|
+ assert hasReferences();
|
|
|
if (from == 0 && length() == length) {
|
|
|
return retain();
|
|
|
}
|
|
@@ -128,6 +137,7 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
|
|
|
|
|
|
@Override
|
|
|
public int length() {
|
|
|
+ assert hasReferences();
|
|
|
return delegate.length();
|
|
|
}
|
|
|
|
|
@@ -139,6 +149,7 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
|
|
|
|
|
|
@Override
|
|
|
public long ramBytesUsed() {
|
|
|
+ assert hasReferences();
|
|
|
return delegate.ramBytesUsed();
|
|
|
}
|
|
|
|
|
@@ -213,6 +224,7 @@ public final class ReleasableBytesReference implements RefCounted, Releasable, B
|
|
|
|
|
|
@Override
|
|
|
public boolean isFragment() {
|
|
|
+ assert hasReferences();
|
|
|
return delegate.isFragment();
|
|
|
}
|
|
|
|