blob: 3a31e9085365bca5ede4124b5625cb1f07da55fd [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* more patents listed at http://www.pivotal.io/patents.
*=========================================================================
*/
package com.gemstone.gemfire.internal.cache;
import com.gemstone.gemfire.cache.EntryEvent;
import com.gemstone.gemfire.cache.EntryNotFoundException;
import com.gemstone.gemfire.distributed.internal.DM;
import com.gemstone.gemfire.internal.ByteArrayDataInput;
import com.gemstone.gemfire.internal.cache.versions.VersionTag;
import com.gemstone.gemfire.internal.offheap.annotations.Retained;
/**
* Abstract implementation class of RegionEntry interface.
* This is adds Disk support behavior
*
* @since 3.5.1
*
* @author Darrel Schneider
*
*/
public abstract class AbstractOplogDiskRegionEntry
extends AbstractDiskRegionEntry
{
protected AbstractOplogDiskRegionEntry(RegionEntryContext context, Object value) {
super(context, value);
}
abstract void setDiskId(RegionEntry oldRe);
@Override
public final void removePhase1(LocalRegion r, boolean isClear) throws RegionClearedException
{
synchronized (this) {
Helper.removeFromDisk(this, r, isClear);
_removePhase1();
}
}
@Override
public void removePhase2() {
Object syncObj = getDiskId();
if (syncObj == null) {
syncObj = this;
}
synchronized (syncObj) {
super.removePhase2();
}
}
@Override
public final boolean fillInValue(LocalRegion r, InitialImageOperation.Entry entry, ByteArrayDataInput in, DM mgr) {
return Helper.fillInValue(this, entry, r.getDiskRegion(), mgr, in, r);
}
@Override
public final boolean isOverflowedToDisk(LocalRegion r, DistributedRegion.DiskPosition dp) {
return Helper.isOverflowedToDisk(this, r.getDiskRegion(), dp, r);
}
@Override
public final Object getValue(RegionEntryContext context) {
return Helper.faultInValue(this, (LocalRegion) context); // OFFHEAP returned to callers
}
@Override
@Retained
public final Object getValueRetain(RegionEntryContext context) {
return Helper.faultInValueRetain(this, (LocalRegion) context);
}
@Override
public final Object getValueInVMOrDiskWithoutFaultIn(LocalRegion owner) {
return Helper.getValueInVMOrDiskWithoutFaultIn(this, owner);
}
@Retained
@Override
public Object getValueOffHeapOrDiskWithoutFaultIn(LocalRegion owner) {
return Helper.getValueOffHeapOrDiskWithoutFaultIn(this, owner);
}
@Override
public final Object getValueOnDisk(LocalRegion r)
throws EntryNotFoundException
{
return Helper.getValueOnDisk(this, r.getDiskRegion());
}
@Override
public final Object getSerializedValueOnDisk(LocalRegion r)
throws EntryNotFoundException
{
return Helper.getSerializedValueOnDisk(this, r.getDiskRegion());
}
@Override
public final Object getValueOnDiskOrBuffer(LocalRegion r)
throws EntryNotFoundException
{
// @todo darrel if value is Token.REMOVED || Token.DESTROYED throw
// EntryNotFoundException
return Helper.getValueOnDiskOrBuffer(this, r.getDiskRegion(), r);
}
public DiskEntry getPrev() {
return getDiskId().getPrev();
}
public DiskEntry getNext() {
return getDiskId().getNext();
}
public void setPrev(DiskEntry v) {
getDiskId().setPrev(v);
}
public void setNext(DiskEntry v) {
getDiskId().setNext(v);
}
/*
* If detected a conflict event, persist region needs to persist both the
* golden copy and conflict tag
*/
@Override
public void persistConflictingTag(LocalRegion region, VersionTag tag) {
// only persist region needs to persist conflict tag
Helper.updateVersionOnly(this, region, tag);
setRecentlyUsed();
}
/**
* Process a version tag. This overrides AbtractRegionEntry so
* we can check to see if the old value was recovered from disk.
* If so, we don't check for conflicts.
*/
@Override
public void processVersionTag(EntryEvent cacheEvent) {
DiskId did = getDiskId();
boolean checkConflicts = true;
if(did != null) {
LocalRegion lr = (LocalRegion)cacheEvent.getRegion();
if (lr != null && lr.getDiskRegion().isReadyForRecovery()) {
synchronized(did) {
checkConflicts = !EntryBits.isRecoveredFromDisk(did.getUserBits());
}
}
}
processVersionTag(cacheEvent, checkConflicts);
}
/**
* Returns true if the DiskEntry value is equal to {@link Token#DESTROYED}, {@link Token#REMOVED_PHASE1}, or {@link Token#REMOVED_PHASE2}.
*/
@Override
public boolean isRemovedFromDisk() {
return Token.isRemovedFromDisk(getValueAsToken());
}
// Do not add any instance variables to this class.
// Instead add them to the DISK section of LeafRegionEntry.cpp.
}