Repository: incubator-geode Updated Branches: refs/heads/feature/GEODE-1785 [created] 3b439d33c
added generateRegionEntryClasses.sh and LeafRegionEntry.cpp Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/3b439d33 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/3b439d33 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/3b439d33 Branch: refs/heads/feature/GEODE-1785 Commit: 3b439d33c028a06e6a31ef7dda6d3643a0de4f62 Parents: 7973d57 Author: Darrel Schneider <dschnei...@pivotal.io> Authored: Wed Nov 9 14:34:33 2016 -0800 Committer: Darrel Schneider <dschnei...@pivotal.io> Committed: Wed Nov 9 14:34:33 2016 -0800 ---------------------------------------------------------------------- dev-tools/generateRegionEntryClasses.sh | 44 + .../geode/internal/cache/LeafRegionEntry.cpp | 866 +++++++++++++++++++ 2 files changed, 910 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3b439d33/dev-tools/generateRegionEntryClasses.sh ---------------------------------------------------------------------- diff --git a/dev-tools/generateRegionEntryClasses.sh b/dev-tools/generateRegionEntryClasses.sh new file mode 100755 index 0000000..b208a9a --- /dev/null +++ b/dev-tools/generateRegionEntryClasses.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# This script should only be run from the top level build directory (i.e. the one that contains build.xml). +# It reads LeafRegionEntry.cpp, preprocesses it and generates all the leaf classes that subclass AbstractRegionEntry. +# It executes cpp. It has been tested with gnu's cpp on linux and the mac. + +SRCDIR=geode-core/src/main/java/org/apache/geode/internal/cache +SRCFILE=$SRCDIR/LeafRegionEntry.cpp + +for VERTYPE in VM Versioned +do + for RETYPE in Thin Stats ThinLRU StatsLRU ThinDisk StatsDisk ThinDiskLRU StatsDiskLRU + do + for KEY_INFO in 'ObjectKey KEY_OBJECT' 'IntKey KEY_INT' 'LongKey KEY_LONG' 'UUIDKey KEY_UUID' 'StringKey1 KEY_STRING1' 'StringKey2 KEY_STRING2' + do + for MEMTYPE in Heap OffHeap + do + declare -a KEY_ARRAY=($KEY_INFO) + KEY_CLASS=${KEY_ARRAY[0]} + KEY_TYPE=${KEY_ARRAY[1]} + BASE=${VERTYPE}${RETYPE}RegionEntry${MEMTYPE} + OUT=${BASE}${KEY_CLASS} + WP_ARGS=-Wp,-C,-P,-D${KEY_TYPE},-DPARENT_CLASS=$BASE,-DLEAF_CLASS=$OUT + if [ "$VERTYPE" = "Versioned" ]; then + WP_ARGS=${WP_ARGS},-DVERSIONED + fi + if [[ "$RETYPE" = *Stats* ]]; then + WP_ARGS=${WP_ARGS},-DSTATS + fi + if [[ "$RETYPE" = *Disk* ]]; then + WP_ARGS=${WP_ARGS},-DDISK + fi + if [[ "$RETYPE" = *LRU* ]]; then + WP_ARGS=${WP_ARGS},-DLRU + fi + if [[ "$MEMTYPE" = "OffHeap" ]]; then + WP_ARGS=${WP_ARGS},-DOFFHEAP + fi + echo generating $SRCDIR/$OUT.java + cpp -E $WP_ARGS $SRCFILE >$SRCDIR/$OUT.java + #echo VERTYPE=$VERTYPE RETYPE=$RETYPE $KEY_INFO KEY_CLASS=$KEY_CLASS KEY_TYPE=$KEY_TYPE args=$WP_ARGS + done + done + done +done http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3b439d33/geode-core/src/main/java/org/apache/geode/internal/cache/LeafRegionEntry.cpp ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LeafRegionEntry.cpp b/geode-core/src/main/java/org/apache/geode/internal/cache/LeafRegionEntry.cpp new file mode 100644 index 0000000..9eaf6b1 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LeafRegionEntry.cpp @@ -0,0 +1,866 @@ +/* + * 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; +// DO NOT modify this class. It was generated from LeafRegionEntry.cpp +#if defined(KEY_OBJECT) +#define KEY_TYPE Object +#elif defined(KEY_INT) +#define KEY_TYPE int +#elif defined(KEY_LONG) +#define KEY_TYPE long +#elif defined(KEY_UUID) +#define KEY_TYPE UUID +#elif defined(KEY_STRING1) || defined(KEY_STRING2) +#define KEY_TYPE String +#else +#error the KEY_TYPE macro must be defined +#endif + +#ifdef KEY_UUID +import java.util.UUID; +#endif +#if defined(STATS) || defined(LRU) +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +#endif +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +#if defined(VERSIONED) +import org.apache.geode.cache.EntryEvent; +#endif +#if defined(DISK) || defined(LRU) +import org.apache.geode.internal.cache.lru.EnableLRU; +#endif +#ifdef DISK +import org.apache.geode.internal.cache.persistence.DiskRecoveryStore; +#endif +#ifdef STATS +import org.apache.geode.internal.InternalStatisticsDisabledException; +#endif +#ifdef LRU +import org.apache.geode.internal.cache.lru.LRUClockNode; +import org.apache.geode.internal.cache.lru.NewLRUClockHand; +#endif +#ifdef VERSIONED +import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.internal.cache.versions.VersionSource; +import org.apache.geode.internal.cache.versions.VersionStamp; +import org.apache.geode.internal.cache.versions.VersionTag; +#endif +#ifdef OFFHEAP +import org.apache.geode.internal.offheap.OffHeapRegionEntryHelper; +import org.apache.geode.internal.offheap.annotations.Released; +import org.apache.geode.internal.offheap.annotations.Retained; +import org.apache.geode.internal.offheap.annotations.Unretained; +#endif +import org.apache.geode.internal.util.concurrent.CustomEntryConcurrentHashMap.HashEntry; + +// macros whose definition changes this class: +// disk: DISK +// lru: LRU +// stats: STATS +// versioned: VERSIONED +// offheap: OFFHEAP +// One of the following key macros must be defined: +// key object: KEY_OBJECT +// key int: KEY_INT +// key long: KEY_LONG +// key uuid: KEY_UUID +// key string1: KEY_STRING1 +// key string2: KEY_STRING2 + +/** + * Do not modify this class. It was generated. + * Instead modify LeafRegionEntry.cpp and then run + * bin/generateRegionEntryClasses.sh from the directory + * that contains your build.xml. + */ +public class LEAF_CLASS extends PARENT_CLASS { + public LEAF_CLASS (RegionEntryContext context, KEY_TYPE key, +#ifdef OFFHEAP + @Retained +#endif + Object value +#if defined(KEY_STRING1) || defined(KEY_STRING2) + , boolean byteEncode +#endif + ) { + super(context, +#ifdef DISK + (value instanceof RecoveredEntry ? null : value) +#else + value +#endif + ); + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp +#ifdef DISK + initialize(context, value); +#endif +#if defined(KEY_OBJECT) + this.key = key; +#elif defined(KEY_INT) + this.key = key; +#elif defined(KEY_LONG) + this.key = key; +#elif defined(KEY_UUID) + this.keyMostSigBits = key.getMostSignificantBits(); + this.keyLeastSigBits = key.getLeastSignificantBits(); +#elif defined(KEY_STRING1) + // caller has already confirmed that key.length <= MAX_INLINE_STRING_KEY + long tmpBits1 = 0L; + if (byteEncode) { + for (int i=key.length()-1; i >= 0; i--) { + // Note: we know each byte is <= 0x7f so the "& 0xff" is not needed. But I added it in to keep findbugs happy. + tmpBits1 |= (byte)key.charAt(i) & 0xff; + tmpBits1 <<= 8; + } + tmpBits1 |= 1<<6; + } else { + for (int i=key.length()-1; i >= 0; i--) { + tmpBits1 |= key.charAt(i); + tmpBits1 <<= 16; + } + } + tmpBits1 |= key.length(); + this.bits1 = tmpBits1; +#elif defined(KEY_STRING2) + // caller has already confirmed that key.length <= MAX_INLINE_STRING_KEY + long tmpBits1 = 0L; + long tmpBits2 = 0L; + if (byteEncode) { + for (int i=key.length()-1; i >= 0; i--) { + // Note: we know each byte is <= 0x7f so the "& 0xff" is not needed. But I added it in to keep findbugs happy. + if (i < 7) { + tmpBits1 |= (byte)key.charAt(i) & 0xff; + tmpBits1 <<= 8; + } else { + tmpBits2 <<= 8; + tmpBits2 |= (byte)key.charAt(i) & 0xff; + } + } + tmpBits1 |= 1<<6; + } else { + for (int i=key.length()-1; i >= 0; i--) { + if (i < 3) { + tmpBits1 |= key.charAt(i); + tmpBits1 <<= 16; + } else { + tmpBits2 <<= 16; + tmpBits2 |= key.charAt(i); + } + } + } + tmpBits1 |= key.length(); + this.bits1 = tmpBits1; + this.bits2 = tmpBits2; +#endif + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // common code + protected int hash; + private HashEntry<Object, Object> next; + @SuppressWarnings("unused") + private volatile long lastModified; + private static final AtomicLongFieldUpdater<LEAF_CLASS> lastModifiedUpdater + = AtomicLongFieldUpdater.newUpdater(LEAF_CLASS.class, "lastModified"); +#ifdef OFFHEAP + /** + * All access done using ohAddrUpdater so it is used even though the compiler can not tell it is. + */ + @SuppressWarnings("unused") + @Retained @Released private volatile long ohAddress; + /** + * I needed to add this because I wanted clear to call setValue which normally can only be called while the re is synced. + * But if I sync in that code it causes a lock ordering deadlock with the disk regions because they also get a rw lock in clear. + * Some hardware platforms do not support CAS on a long. If gemfire is run on one of those the AtomicLongFieldUpdater does a sync + * on the re and we will once again be deadlocked. + * I don't know if we support any of the hardware platforms that do not have a 64bit CAS. If we do then we can expect deadlocks + * on disk regions. + */ + private final static AtomicLongFieldUpdater<LEAF_CLASS> ohAddrUpdater = AtomicLongFieldUpdater.newUpdater(LEAF_CLASS.class, "ohAddress"); + + @Override + public Token getValueAsToken() { + return OffHeapRegionEntryHelper.getValueAsToken(this); + } + + @Override + protected Object getValueField() { + return OffHeapRegionEntryHelper._getValue(this); + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + @Override +#ifdef OFFHEAP + @Unretained + protected void setValueField(@Unretained Object v) { +#else + protected void setValueField(Object v) { +#endif + OffHeapRegionEntryHelper.setValue(this, v); + } + @Override +#ifdef OFFHEAP + @Retained +#endif + public Object _getValueRetain(RegionEntryContext context, boolean decompress) { + return OffHeapRegionEntryHelper._getValueRetain(this, decompress, context); + } + + @Override + public long getAddress() { + return ohAddrUpdater.get(this); + } + + @Override + public boolean setAddress(long expectedAddr, long newAddr) { + return ohAddrUpdater.compareAndSet(this, expectedAddr, newAddr); + } + + @Override +#ifdef OFFHEAP + @Released +#endif + public void release() { + OffHeapRegionEntryHelper.releaseEntry(this); + } + + @Override + public void returnToPool() { + // Deadcoded for now; never was working +// if (this instanceof VMThinRegionEntryLongKey) { +// factory.returnToPool((VMThinRegionEntryLongKey)this); +// } + } +#else + private volatile Object value; + @Override + protected final Object getValueField() { + return this.value; + } + @Override + protected void setValueField(Object v) { + this.value = v; + } +#endif + protected long getlastModifiedField() { + return lastModifiedUpdater.get(this); + } + protected boolean compareAndSetLastModifiedField(long expectedValue, long newValue) { + return lastModifiedUpdater.compareAndSet(this, expectedValue, newValue); + } + /** + * @see HashEntry#getEntryHash() + */ + public final int getEntryHash() { + return this.hash; + } + protected void setEntryHash(int v) { + this.hash = v; + } + /** + * @see HashEntry#getNextEntry() + */ + public final HashEntry<Object, Object> getNextEntry() { + return this.next; + } + /** + * @see HashEntry#setNextEntry + */ + public final void setNextEntry(final HashEntry<Object, Object> n) { + this.next = n; + } +#ifdef DISK + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // disk code +#ifdef LRU + protected void initialize(RegionEntryContext drs, Object value) { + boolean isBackup; + if (drs instanceof LocalRegion) { + isBackup = ((LocalRegion)drs).getDiskRegion().isBackup(); + } else if (drs instanceof PlaceHolderDiskRegion) { + isBackup = true; + } else { + throw new IllegalArgumentException("expected a LocalRegion or PlaceHolderDiskRegion"); + } + // Delay the initialization of DiskID if overflow only + if (isBackup) { + diskInitialize(drs, value); + } + } + @Override + public final synchronized int updateAsyncEntrySize(EnableLRU capacityController) { + int oldSize = getEntrySize(); + int newSize = capacityController.entrySize( getKeyForSizing(), null); + setEntrySize(newSize); + int delta = newSize - oldSize; + return delta; + } +#else + protected void initialize(RegionEntryContext context, Object value) { + diskInitialize(context, value); + } + @Override + public int updateAsyncEntrySize(EnableLRU capacityController) { + throw new IllegalStateException("should never be called"); + } +#endif + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + private void diskInitialize(RegionEntryContext context, Object value) { + DiskRecoveryStore drs = (DiskRecoveryStore)context; + DiskStoreImpl ds = drs.getDiskStore(); + long maxOplogSize = ds.getMaxOplogSize(); + //get appropriate instance of DiskId implementation based on maxOplogSize + this.id = DiskId.createDiskId(maxOplogSize, true/* is persistence */, ds.needsLinkedList()); + Helper.initialize(this, drs, value); + } + + /** + * DiskId + * + * @since 5.1 + */ + protected DiskId id;//= new DiskId(); + public DiskId getDiskId() { + return this.id; + } + @Override + void setDiskId(RegionEntry old) { + this.id = ((AbstractDiskRegionEntry)old).getDiskId(); + } +// // inlining DiskId +// // always have these fields +// /** +// * id consists of +// * most significant +// * 1 byte = users bits +// * 2-8 bytes = oplog id +// * least significant. +// * +// * The highest bit in the oplog id part is set to 1 if the oplog id +// * is negative. +// * @todo this field could be an int for an overflow only region +// */ +// private long id; +// /** +// * Length of the bytes on disk. +// * This is always set. If the value is invalid then it will be set to 0. +// * The most significant bit is used by overflow to mark it as needing to be written. +// */ +// protected int valueLength = 0; +// // have intOffset or longOffset +// // intOffset +// /** +// * The position in the oplog (the oplog offset) where this entry's value is +// * stored +// */ +// private volatile int offsetInOplog; +// // longOffset +// /** +// * The position in the oplog (the oplog offset) where this entry's value is +// * stored +// */ +// private volatile long offsetInOplog; +// // have overflowOnly or persistence +// // overflowOnly +// // no fields +// // persistent +// /** unique entry identifier * */ +// private long keyId; +#endif + +#ifdef LRU + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // lru code + @Override + public void setDelayedDiskId(LocalRegion r) { +#ifdef DISK + DiskStoreImpl ds = r.getDiskStore(); + long maxOplogSize = ds.getMaxOplogSize(); + this.id = DiskId.createDiskId(maxOplogSize, false /* over flow only */, ds.needsLinkedList()); +#else + // nothing needed for LRUs with no disk +#endif + } + public final synchronized int updateEntrySize(EnableLRU capacityController) { + return updateEntrySize(capacityController, _getValue()); // OFHEAP: _getValue ok w/o incing refcount because we are synced and only getting the size + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + public final synchronized int updateEntrySize(EnableLRU capacityController, + Object value) { + int oldSize = getEntrySize(); + int newSize = capacityController.entrySize( getKeyForSizing(), value); + setEntrySize(newSize); + int delta = newSize - oldSize; + // if ( debug ) log( "updateEntrySize key=" + getKey() + // + (_getValue() == Token.INVALID ? " invalid" : + // (_getValue() == Token.LOCAL_INVALID ? "local_invalid" : + // (_getValue()==null ? " evicted" : " valid"))) + // + " oldSize=" + oldSize + // + " newSize=" + this.size ); + return delta; + } + public final boolean testRecentlyUsed() { + return areAnyBitsSet(RECENTLY_USED); + } + @Override + public final void setRecentlyUsed() { + setBits(RECENTLY_USED); + } + public final void unsetRecentlyUsed() { + clearBits(~RECENTLY_USED); + } + public final boolean testEvicted() { + return areAnyBitsSet(EVICTED); + } + public final void setEvicted() { + setBits(EVICTED); + } + public final void unsetEvicted() { + clearBits(~EVICTED); + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + private LRUClockNode nextLRU; + private LRUClockNode prevLRU; + private int size; + public final void setNextLRUNode( LRUClockNode next ) { + this.nextLRU = next; + } + public final LRUClockNode nextLRUNode() { + return this.nextLRU; + } + public final void setPrevLRUNode( LRUClockNode prev ) { + this.prevLRU = prev; + } + public final LRUClockNode prevLRUNode() { + return this.prevLRU; + } + public final int getEntrySize() { + return this.size; + } + protected final void setEntrySize(int size) { + this.size = size; + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + +//@Override +//public StringBuilder appendFieldsToString(final StringBuilder sb) { +// StringBuilder result = super.appendFieldsToString(sb); +// result.append("; prev=").append(this.prevLRU==null?"null":"not null"); +// result.append("; next=").append(this.nextLRU==null?"null":"not null"); +// return result; +//} + + @Override + public Object getKeyForSizing() { +#ifdef KEY_OBJECT + // default implementation. + return getKey(); +#else + // inline keys always report null for sizing since the size comes from the entry size + return null; +#endif + } +#endif + +#ifdef STATS + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // stats code + @Override + public final void updateStatsForGet(boolean hit, long time) + { + setLastAccessed(time); + if (hit) { + incrementHitCount(); + } else { + incrementMissCount(); + } + } + @Override + protected final void setLastModified(long lastModified) { + _setLastModified(lastModified); + if (!DISABLE_ACCESS_TIME_UPDATE_ON_PUT) { + setLastAccessed(lastModified); + } + } + private volatile long lastAccessed; + private volatile int hitCount; + private volatile int missCount; + + private static final AtomicIntegerFieldUpdater<LEAF_CLASS> hitCountUpdater + = AtomicIntegerFieldUpdater.newUpdater(LEAF_CLASS.class, "hitCount"); + private static final AtomicIntegerFieldUpdater<LEAF_CLASS> missCountUpdater + = AtomicIntegerFieldUpdater.newUpdater(LEAF_CLASS.class, "missCount"); + + @Override + public final long getLastAccessed() throws InternalStatisticsDisabledException { + return this.lastAccessed; + } + private void setLastAccessed(long lastAccessed) { + this.lastAccessed = lastAccessed; + } + @Override + public final long getHitCount() throws InternalStatisticsDisabledException { + return this.hitCount & 0xFFFFFFFFL; + } + @Override + public final long getMissCount() throws InternalStatisticsDisabledException { + return this.missCount & 0xFFFFFFFFL; + } + private void incrementHitCount() { + hitCountUpdater.incrementAndGet(this); + } + private void incrementMissCount() { + missCountUpdater.incrementAndGet(this); + } + @Override + public final void resetCounts() throws InternalStatisticsDisabledException { + hitCountUpdater.set(this,0); + missCountUpdater.set(this,0); + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + @Override + public final void txDidDestroy(long currTime) { + setLastModified(currTime); + setLastAccessed(currTime); + this.hitCount = 0; + this.missCount = 0; + } + @Override + public boolean hasStats() { + return true; + } +#endif + +#ifdef VERSIONED + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // versioned code + private VersionSource memberID; + private short entryVersionLowBytes; + private short regionVersionHighBytes; + private int regionVersionLowBytes; + private byte entryVersionHighByte; + private byte distributedSystemId; + + public int getEntryVersion() { + return ((entryVersionHighByte << 16) & 0xFF0000) | (entryVersionLowBytes & 0xFFFF); + } + + public long getRegionVersion() { + return (((long)regionVersionHighBytes) << 32) | (regionVersionLowBytes & 0x00000000FFFFFFFFL); + } + + + public long getVersionTimeStamp() { + return getLastModified(); + } + + public void setVersionTimeStamp(long time) { + setLastModified(time); + } + + public VersionSource getMemberID() { + return this.memberID; + } + public int getDistributedSystemId() { + return this.distributedSystemId; + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + public void setVersions(VersionTag tag) { + this.memberID = tag.getMemberID(); + int eVersion = tag.getEntryVersion(); + this.entryVersionLowBytes = (short)(eVersion & 0xffff); + this.entryVersionHighByte = (byte)((eVersion & 0xff0000) >> 16); + this.regionVersionHighBytes = tag.getRegionVersionHighBytes(); + this.regionVersionLowBytes = tag.getRegionVersionLowBytes(); + if (!(tag.isGatewayTag()) && this.distributedSystemId == tag.getDistributedSystemId()) { + if (getVersionTimeStamp() <= tag.getVersionTimeStamp()) { + setVersionTimeStamp(tag.getVersionTimeStamp()); + } else { + tag.setVersionTimeStamp(getVersionTimeStamp()); + } + } else { + setVersionTimeStamp(tag.getVersionTimeStamp()); + } + this.distributedSystemId = (byte)(tag.getDistributedSystemId() & 0xff); + } + + public void setMemberID(VersionSource memberID) { + this.memberID = memberID; + } + + @Override + public VersionStamp getVersionStamp() { + return this; + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + public VersionTag asVersionTag() { + VersionTag tag = VersionTag.create(memberID); + tag.setEntryVersion(getEntryVersion()); + tag.setRegionVersion(this.regionVersionHighBytes, this.regionVersionLowBytes); + tag.setVersionTimeStamp(getVersionTimeStamp()); + tag.setDistributedSystemId(this.distributedSystemId); + return tag; + } + + public void processVersionTag(LocalRegion r, VersionTag tag, + boolean isTombstoneFromGII, boolean hasDelta, + VersionSource thisVM, InternalDistributedMember sender, boolean checkForConflicts) { + basicProcessVersionTag(r, tag, isTombstoneFromGII, hasDelta, thisVM, sender, checkForConflicts); + } + + @Override + public void processVersionTag(EntryEvent cacheEvent) { + // this keeps Eclipse happy. without it the sender chain becomes confused + // while browsing this code + super.processVersionTag(cacheEvent); + } + + /** get rvv internal high byte. Used by region entries for transferring to storage */ + public short getRegionVersionHighBytes() { + return this.regionVersionHighBytes; + } + + /** get rvv internal low bytes. Used by region entries for transferring to storage */ + public int getRegionVersionLowBytes() { + return this.regionVersionLowBytes; + } +#endif + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + // key code +#ifdef KEY_OBJECT + private final Object key; + @Override + public final Object getKey() { + return this.key; + } + +#elif defined(KEY_INT) + private final int key; + @Override + public final Object getKey() { + return this.key; + } + @Override + public boolean isKeyEqual(Object k) { + if (k instanceof Integer) { + return ((Integer) k).intValue() == this.key; + } + return false; + } + +#elif defined(KEY_LONG) + private final long key; + @Override + public final Object getKey() { + return this.key; + } + @Override + public boolean isKeyEqual(Object k) { + if (k instanceof Long) { + return ((Long) k).longValue() == this.key; + } + return false; + } + +#elif defined(KEY_UUID) + private final long keyMostSigBits; + private final long keyLeastSigBits; + @Override + public final Object getKey() { + return new UUID(this.keyMostSigBits, this.keyLeastSigBits); + } + @Override + public boolean isKeyEqual(Object k) { + if (k instanceof UUID) { + UUID uuid = (UUID)k; + return uuid.getLeastSignificantBits() == this.keyLeastSigBits && uuid.getMostSignificantBits() == this.keyMostSigBits; + } + return false; + } + +#elif defined(KEY_STRING1) + private final long bits1; + private int getKeyLength() { + return (int) (this.bits1 & 0x003fL); + } + private int getEncoding() { + // 0 means encoded as char + // 1 means encoded as bytes that are all <= 0x7f; + return (int) (this.bits1 >> 6) & 0x03; + } + @Override + public final Object getKey() { + int keylen = getKeyLength(); + char[] chars = new char[keylen]; + long tmpBits1 = this.bits1; + if (getEncoding() == 1) { + for (int i=0; i < keylen; i++) { + tmpBits1 >>= 8; + chars[i] = (char) (tmpBits1 & 0x00ff); + } + } else { + for (int i=0; i < keylen; i++) { + tmpBits1 >>= 16; + chars[i] = (char) (tmpBits1 & 0x00FFff); + } + } + return new String(chars); + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + @Override + public boolean isKeyEqual(Object k) { + if (k instanceof String) { + String str = (String)k; + int keylen = getKeyLength(); + if (str.length() == keylen) { + long tmpBits1 = this.bits1; + if (getEncoding() == 1) { + for (int i=0; i < keylen; i++) { + tmpBits1 >>= 8; + char c = (char) (tmpBits1 & 0x00ff); + if (str.charAt(i) != c) { + return false; + } + } + } else { + for (int i=0; i < keylen; i++) { + tmpBits1 >>= 16; + char c = (char) (tmpBits1 & 0x00FFff); + if (str.charAt(i) != c) { + return false; + } + } + } + return true; + } + } + return false; + } + +#elif defined(KEY_STRING2) + // strlen is encoded in lowest 6 bits (max strlen is 63) + // character encoding info is in bits 7 and 8 + // The other bits are used to encoded character data. + private final long bits1; + // bits2 encodes character data + private final long bits2; + private int getKeyLength() { + return (int) (this.bits1 & 0x003fL); + } + private int getEncoding() { + // 0 means encoded as char + // 1 means encoded as bytes that are all <= 0x7f; + return (int) (this.bits1 >> 6) & 0x03; + } + @Override + public final Object getKey() { + int keylen = getKeyLength(); + char[] chars = new char[keylen]; + long tmpBits1 = this.bits1; + long tmpBits2 = this.bits2; + if (getEncoding() == 1) { + for (int i=0; i < keylen; i++) { + if (i < 7) { + tmpBits1 >>= 8; + chars[i] = (char) (tmpBits1 & 0x00ff); + } else { + chars[i] = (char) (tmpBits2 & 0x00ff); + tmpBits2 >>= 8; + } + } + } else { + for (int i=0; i < keylen; i++) { + if (i < 3) { + tmpBits1 >>= 16; + chars[i] = (char) (tmpBits1 & 0x00FFff); + } else { + chars[i] = (char) (tmpBits2 & 0x00FFff); + tmpBits2 >>= 16; + } + } + } + return new String(chars); + } + + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp + + @Override + public boolean isKeyEqual(Object k) { + if (k instanceof String) { + String str = (String)k; + int keylen = getKeyLength(); + if (str.length() == keylen) { + long tmpBits1 = this.bits1; + long tmpBits2 = this.bits2; + if (getEncoding() == 1) { + for (int i=0; i < keylen; i++) { + char c; + if (i < 7) { + tmpBits1 >>= 8; + c = (char) (tmpBits1 & 0x00ff); + } else { + c = (char) (tmpBits2 & 0x00ff); + tmpBits2 >>= 8; + } + if (str.charAt(i) != c) { + return false; + } + } + } else { + for (int i=0; i < keylen; i++) { + char c; + if (i < 3) { + tmpBits1 >>= 16; + c = (char) (tmpBits1 & 0x00FFff); + } else { + c = (char) (tmpBits2 & 0x00FFff); + tmpBits2 >>= 16; + } + if (str.charAt(i) != c) { + return false; + } + } + } + return true; + } + } + return false; + } +#endif + // DO NOT modify this class. It was generated from LeafRegionEntry.cpp +}