blob: 80b591819355652deb75def45ace0945430f7eae [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.cache;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.nio.ByteBuffer;
import org.apache.geode.annotations.Immutable;
import org.apache.geode.internal.DSCODE;
import org.apache.geode.internal.DataSerializableFixedID;
import org.apache.geode.internal.Version;
/**
* Internal tokens used as region values. These tokens are never seen from the public API.
*
* <p>
* These classes are Serializable and implement readResolve to support canonicalization in the face
* of copysharing.
*/
@Immutable
public abstract class Token {
@Immutable
public static final Invalid INVALID = new Invalid();
@Immutable
public static final LocalInvalid LOCAL_INVALID = new LocalInvalid();
// DESTROYED token, used during getInitialImage only
// and only for identity comparisons
@Immutable
public static final Destroyed DESTROYED = new Destroyed();
/**
* Tombstone is used to hold onto destroyed entries in regions supporting entry versioning.
* DESTROYED and REMOVED_PHASE2 tokens transition to TOMBSTONE during GII and normal entry
* removal.
*/
@Immutable
public static final Tombstone TOMBSTONE = new Tombstone();
/**
* Used when a RegionEntry is removed from a RegionMap. In phase 1 of removal, the destroy()
* operation is applied to the entry under synchronization. The lock is then released while
* distribution is done. During this period, the entry may be modified, preventing the entry from
* being removed from its map.
*/
@Immutable
public static final Removed REMOVED_PHASE1 = new Removed();
/**
* Used when a RegionEntry is removed from a RegionMap. In phase 2 of removal, callbacks for the
* entry are invoked under synchronization and the entry is then removed from the map. If an entry
* is seen in this state, you should wait in a loop for the entry to be removed from the map.
*/
@Immutable
public static final Removed2 REMOVED_PHASE2 = new Removed2();
/**
* Used to designate end of stream in StreamingOperation
*/
@Immutable
public static final EndOfStream END_OF_STREAM = new EndOfStream();
/**
* Indicates that a decision was made to not provide some information that is normally available.
*/
@Immutable
public static final NotAvailable NOT_AVAILABLE = new NotAvailable();
// !!! NOTICE !!!
// If you add a new Token to this class then add
// support in OffHeapRegionEntryHelper to encode that
// token as an address.
// See OffHeapRegionEntryHelper.objectToAddress.
/**
* A token used to represent a value that is not a token.
*/
@Immutable
public static final NotAToken NOT_A_TOKEN = new NotAToken();
/**
* Returns true if o is INVALID, LOCAL_INVALID, DESTROYED, or REMOVED.
*/
public static boolean isInvalidOrRemoved(Object o) {
return isInvalid(o) || isRemoved(o);
}
public static boolean isInvalid(Object o) {
return o == INVALID || o == LOCAL_INVALID;
}
public static boolean isRemoved(Object o) {
return o == DESTROYED || o == REMOVED_PHASE1 || o == REMOVED_PHASE2 || o == TOMBSTONE;
}
public static boolean isRemovedFromDisk(Object o) {
return o == DESTROYED || o == REMOVED_PHASE1 || o == REMOVED_PHASE2;
}
public static boolean isDestroyed(Object o) {
return o == DESTROYED;
}
public static boolean isToken(Object o) {
return o instanceof Token;
}
/**
* Singleton token indicating an Invalid Entry.
*/
public static class Invalid extends Token implements DataSerializableFixedID, Serializable {
private static final long serialVersionUID = -4133205114649525169L;
protected Invalid() {}
@Override
public String toString() {
return "INVALID";
}
private Object readResolve() throws ObjectStreamException {
return INVALID;
}
@Override
public int getDSFID() {
return TOKEN_INVALID;
}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
public boolean isSerializedValue(byte[] value) {
ByteBuffer buf = ByteBuffer.wrap(value);
return buf.capacity() == 3 && buf.get() == DSCODE.DS_FIXED_ID_SHORT.toByte()
&& buf.getShort() == getDSFID();
}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
public static class LocalInvalid extends Invalid {
private static final long serialVersionUID = 4110159168041217249L;
protected LocalInvalid() {}
@Override
public String toString() {
return "LOCAL_INVALID";
}
private Object readResolve() throws ObjectStreamException {
return LOCAL_INVALID;
}
@Override
public int getDSFID() {
return TOKEN_LOCAL_INVALID;
}
}
public static class Destroyed extends Token implements DataSerializableFixedID, Serializable {
private static final long serialVersionUID = -1922513819482668368L;
protected Destroyed() {}
@Override
public String toString() {
return "DESTROYED";
}
private Object readResolve() throws ObjectStreamException {
return DESTROYED;
}
@Override
public int getDSFID() {
return TOKEN_DESTROYED;
}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
public static class Tombstone extends Token implements DataSerializableFixedID, Serializable {
static final long serialVersionUID = -6388232623019450170L;
protected Tombstone() {}
@Override
public String toString() {
return "TOMBSTONE";
}
private Object readResolve() throws ObjectStreamException {
return TOMBSTONE;
}
@Override
public int getDSFID() {
return TOKEN_TOMBSTONE;
}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
public static class Removed extends Token implements DataSerializableFixedID, Serializable {
private static final long serialVersionUID = -1999836887955504653L;
protected Removed() {}
@Override
public String toString() {
return "REMOVED_PHASE1";
}
private Object readResolve() throws ObjectStreamException {
return REMOVED_PHASE1;
}
@Override
public int getDSFID() {
return TOKEN_REMOVED;
}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
public static class Removed2 extends Token implements DataSerializableFixedID, Serializable {
private static final long serialVersionUID = 5122235867167804597L;
protected Removed2() {}
@Override
public String toString() {
return "REMOVED_PHASE2";
}
private Object readResolve() throws ObjectStreamException {
return REMOVED_PHASE2;
}
@Override
public int getDSFID() {
return TOKEN_REMOVED2;
}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
public static class NotAvailable extends Token {
protected NotAvailable() {}
@Override
public String toString() {
return "NOT_AVAILABLE";
}
// to fix bug 50200 no longer serializable
}
public static class NotAToken extends Token {
protected NotAToken() {}
@Override
public String toString() {
return "NOT_A_TOKEN";
}
// to fix bug 50200 no longer serializable
}
/** Token used in StreamingOperation, StreamingPartitionOperation */
public static class EndOfStream extends Token implements DataSerializableFixedID {
public EndOfStream() {}
@Override
public String toString() {
return "EndOfStream";
}
private Object readResolve() throws ObjectStreamException {
return END_OF_STREAM;
}
@Override
public int getDSFID() {
return END_OF_STREAM_TOKEN;
}
@Override
public void fromData(DataInput in) throws IOException, ClassNotFoundException {}
@Override
public void toData(DataOutput out) throws IOException {}
@Override
public Version[] getSerializationVersions() {
return null;
}
}
}