use of org.apache.geode.internal.offheap.annotations.Retained in project geode by apache.
the class DummyQRegion method toArray.
@Override
public Object[] toArray() {
if (valueInArray == null) {
valueInArray = new Object[1];
}
Object val = this.entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion());
if (val instanceof StoredObject) {
@Retained @Released StoredObject ohval = (StoredObject) val;
try {
val = ohval.getDeserializedValue(getRegion(), this.entry);
} finally {
ohval.release();
}
} else if (val instanceof CachedDeserializable) {
val = ((CachedDeserializable) val).getDeserializedValue(getRegion(), this.entry);
}
valueInArray[0] = val;
return valueInArray;
}
use of org.apache.geode.internal.offheap.annotations.Retained in project geode by apache.
the class AbstractRegionEntry method fillInValue.
@Override
public boolean fillInValue(LocalRegion region, @Retained(ABSTRACT_REGION_ENTRY_FILL_IN_VALUE) InitialImageOperation.Entry entry, ByteArrayDataInput in, DM mgr) {
// starting default value
entry.setSerialized(false);
@Retained(ABSTRACT_REGION_ENTRY_FILL_IN_VALUE) final Object v;
if (isTombstone()) {
v = Token.TOMBSTONE;
} else {
// OFFHEAP: need to incrc, copy bytes, decrc
v = getValue(region);
if (v == null) {
return false;
}
}
// fix for bug 31059
entry.setLastModified(mgr, getLastModified());
if (v == Token.INVALID) {
entry.setInvalid();
} else if (v == Token.LOCAL_INVALID) {
entry.setLocalInvalid();
} else if (v == Token.TOMBSTONE) {
entry.setTombstone();
} else if (v instanceof CachedDeserializable) {
// don't serialize here if it is not already serialized
CachedDeserializable cd = (CachedDeserializable) v;
if (!cd.isSerialized()) {
entry.value = cd.getDeserializedForReading();
} else {
Object tmp = cd.getValue();
if (tmp instanceof byte[]) {
entry.value = tmp;
} else {
try {
HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
BlobHelper.serializeTo(tmp, hdos);
hdos.trim();
entry.value = hdos;
} catch (IOException e) {
throw new IllegalArgumentException(LocalizedStrings.AbstractRegionEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString(), e);
}
}
entry.setSerialized(true);
}
} else if (v instanceof byte[]) {
entry.value = v;
} else {
Object preparedValue = v;
if (preparedValue != null) {
preparedValue = prepareValueForGII(preparedValue);
if (preparedValue == null) {
return false;
}
}
try {
HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
BlobHelper.serializeTo(preparedValue, hdos);
hdos.trim();
entry.value = hdos;
entry.setSerialized(true);
} catch (IOException e) {
throw new IllegalArgumentException(LocalizedStrings.AbstractRegionEntry_AN_IOEXCEPTION_WAS_THROWN_WHILE_SERIALIZING.toLocalizedString(), e);
}
}
return true;
}
use of org.apache.geode.internal.offheap.annotations.Retained in project geode by apache.
the class AbstractRegionEntry method getValue.
@Override
public Object getValue(RegionEntryContext context) {
ReferenceCountHelper.createReferenceCountOwner();
@Retained Object result = _getValueRetain(context, true);
if (Token.isRemoved(result)) {
ReferenceCountHelper.setReferenceCountOwner(null);
return null;
} else {
result = OffHeapHelper.copyAndReleaseIfNeeded(result);
ReferenceCountHelper.setReferenceCountOwner(null);
setRecentlyUsed();
return result;
}
}
use of org.apache.geode.internal.offheap.annotations.Retained in project geode by apache.
the class AbstractRegionEntry method destroy.
/**
* @throws EntryNotFoundException if expectedOldValue is not null and is not equal to current
* value
*/
@Override
@Released
public boolean destroy(LocalRegion region, EntryEventImpl event, boolean inTokenMode, boolean cacheWrite, @Unretained Object expectedOldValue, boolean forceDestroy, boolean removeRecoveredEntry) throws CacheWriterException, EntryNotFoundException, TimeoutException, RegionClearedException {
// A design decision was made to not retrieve the old value from the disk
// if the entry has been evicted to only have the CacheListener afterDestroy
// method ignore it. We don't want to pay the performance penalty. The
// getValueInVM method does not retrieve the value from disk if it has been
// evicted. Instead, it uses the NotAvailable token.
//
// If the region is a WAN queue region, the old value is actually used by the
// afterDestroy callback on a secondary. It is not needed on a primary.
// Since the destroy that sets WAN_QUEUE_TOKEN always originates on the primary
// we only pay attention to WAN_QUEUE_TOKEN if the event is originRemote.
//
// We also read old value from disk or buffer
// in the case where there is a non-null expectedOldValue
// see PartitionedRegion#remove(Object key, Object value)
ReferenceCountHelper.skipRefCountTracking();
@Retained @Released Object curValue = _getValueRetain(region, true);
ReferenceCountHelper.unskipRefCountTracking();
boolean proceed;
try {
if (curValue == null) {
curValue = Token.NOT_AVAILABLE;
}
if (curValue == Token.NOT_AVAILABLE) {
// the state of the transmitting cache's entry & should be used here
if (event.getCallbackArgument() != null && event.getCallbackArgument().equals(RegionQueue.WAN_QUEUE_TOKEN) && event.isOriginRemote()) {
// check originRemote for bug 40508
// curValue = getValue(region); can cause deadlock if GII is occurring
curValue = getValueOnDiskOrBuffer(region);
} else {
FilterProfile fp = region.getFilterProfile();
if (fp != null && (fp.getCqCount() > 0 || expectedOldValue != null)) {
// curValue = getValue(region); can cause deadlock will fault in the value
// and will confuse LRU.
curValue = getValueOnDiskOrBuffer(region);
}
}
}
if (expectedOldValue != null) {
if (!checkExpectedOldValue(expectedOldValue, curValue, region)) {
throw new EntryNotFoundException(LocalizedStrings.AbstractRegionEntry_THE_CURRENT_VALUE_WAS_NOT_EQUAL_TO_EXPECTED_VALUE.toLocalizedString());
}
}
if (inTokenMode && event.hasOldValue()) {
proceed = true;
} else {
proceed = event.setOldValue(curValue, curValue instanceof GatewaySenderEventImpl) || removeRecoveredEntry || forceDestroy || region.getConcurrencyChecksEnabled() || (event.getOperation() == Operation.REMOVE && (curValue == null || curValue == Token.LOCAL_INVALID || curValue == Token.INVALID));
}
} finally {
OffHeapHelper.releaseWithNoTracking(curValue);
}
if (proceed) {
// after the entry not found exception above.
if (!removeRecoveredEntry) {
region.generateAndSetVersionTag(event, this);
}
if (cacheWrite) {
region.cacheWriteBeforeDestroy(event, expectedOldValue);
if (event.getRegion().getServerProxy() != null) {
// server will return a version tag
// update version information (may throw ConcurrentCacheModificationException)
VersionStamp stamp = getVersionStamp();
if (stamp != null) {
stamp.processVersionTag(event);
}
}
}
region.recordEvent(event);
// RegionEntry (the old value) is invalid
if (!region.isProxy() && !isInvalid()) {
IndexManager indexManager = region.getIndexManager();
if (indexManager != null) {
try {
if (isValueNull()) {
@Released Object value = getValueOffHeapOrDiskWithoutFaultIn(region);
try {
Object preparedValue = prepareValueForCache(region, value, false);
_setValue(preparedValue);
releaseOffHeapRefIfRegionBeingClosedOrDestroyed(region, preparedValue);
} finally {
OffHeapHelper.release(value);
}
}
indexManager.updateIndexes(this, IndexManager.REMOVE_ENTRY, IndexProtocol.OTHER_OP);
} catch (QueryException e) {
throw new IndexMaintenanceException(e);
}
}
}
boolean removeEntry = false;
VersionTag v = event.getVersionTag();
if (region.concurrencyChecksEnabled && !removeRecoveredEntry && !event.isFromRILocalDestroy()) {
// Destroy will write a tombstone instead
if (v == null || !v.hasValidVersion()) {
// localDestroy and eviction and ops received with no version tag
// should create a tombstone using the existing version stamp, as should
// (bug #45245) responses from servers that do not have valid version information
VersionStamp stamp = this.getVersionStamp();
if (stamp != null) {
// proxy has no stamps
v = stamp.asVersionTag();
event.setVersionTag(v);
}
}
removeEntry = v == null || !v.hasValidVersion();
} else {
removeEntry = true;
}
if (removeEntry) {
boolean isThisTombstone = isTombstone();
if (inTokenMode && !event.getOperation().isEviction()) {
setValue(region, Token.DESTROYED);
} else {
removePhase1(region, false);
}
if (isThisTombstone) {
region.unscheduleTombstone(this);
}
} else {
makeTombstone(region, v);
}
return true;
} else {
return false;
}
}
use of org.apache.geode.internal.offheap.annotations.Retained in project geode by apache.
the class AbstractRegionEntry method prepareValueForCache.
@Override
@Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE)
public Object prepareValueForCache(RegionEntryContext r, @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE) Object val, EntryEventImpl event, boolean isEntryUpdate) {
if (r != null && r.getOffHeap() && okToStoreOffHeap(val, this)) {
if (val instanceof StoredObject) {
// Check to see if val has the same compression settings as this region.
// The recursive calls in this section are safe because
// we only do it after copy the off-heap value to the heap.
// This is needed to fix bug 52057.
StoredObject soVal = (StoredObject) val;
assert !soVal.isCompressed();
if (r.getCompressor() != null) {
// val is uncompressed and we need a compressed value.
// So copy the off-heap value to the heap in a form that can be compressed.
byte[] valAsBytes = soVal.getValueAsHeapByteArray();
Object heapValue;
if (soVal.isSerialized()) {
heapValue = CachedDeserializableFactory.create(valAsBytes);
} else {
heapValue = valAsBytes;
}
return prepareValueForCache(r, heapValue, event, isEntryUpdate);
}
if (soVal.hasRefCount()) {
// if the reused guy has a refcount then need to inc it
if (!soVal.retain()) {
throw new IllegalStateException("Could not use an off heap value because it was freed");
}
}
// else it is has no refCount so just return it as prepared.
} else {
byte[] data;
boolean isSerialized = !(val instanceof byte[]);
if (isSerialized) {
if (event != null && event.getCachedSerializedNewValue() != null) {
data = event.getCachedSerializedNewValue();
} else if (val instanceof CachedDeserializable) {
data = ((CachedDeserializable) val).getSerializedValue();
} else if (val instanceof PdxInstance) {
try {
data = ((ConvertableToBytes) val).toBytes();
} catch (IOException e) {
throw new PdxSerializationException("Could not convert " + val + " to bytes", e);
}
} else {
data = EntryEventImpl.serialize(val);
}
} else {
data = (byte[]) val;
}
byte[] compressedData = compressBytes(r, data);
// TODO: array comparison is broken
boolean isCompressed = compressedData != data;
ReferenceCountHelper.setReferenceCountOwner(this);
// fix for bug 47875
MemoryAllocator ma = MemoryAllocatorImpl.getAllocator();
val = ma.allocateAndInitialize(compressedData, isSerialized, isCompressed, data);
ReferenceCountHelper.setReferenceCountOwner(null);
}
return val;
}
@Unretained Object nv = val;
if (nv instanceof StoredObject) {
// This off heap value is being put into a on heap region.
byte[] data = ((StoredObject) nv).getSerializedValue();
nv = CachedDeserializableFactory.create(data);
}
if (nv instanceof PdxInstanceImpl) {
// So get the serialized bytes and use a CachedDeserializable.
try {
byte[] data = ((ConvertableToBytes) nv).toBytes();
byte[] compressedData = compressBytes(r, data);
// TODO: array comparison is broken
if (data == compressedData) {
nv = CachedDeserializableFactory.create(data);
} else {
nv = compressedData;
}
} catch (IOException e) {
throw new PdxSerializationException("Could not convert " + nv + " to bytes", e);
}
} else {
nv = compress(r, nv, event);
}
return nv;
}
Aggregations