You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2016/03/05 01:51:04 UTC

[04/38] incubator-geode git commit: collapsed OffHeapCacheDeserializable into ObjectChunk

collapsed OffHeapCacheDeserializable into ObjectChunk


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/af6a01d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/af6a01d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/af6a01d7

Branch: refs/heads/feature/GEODE-982
Commit: af6a01d758c39436b6c0b3324fced6beb7c1b3ca
Parents: dfeea95
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Thu Feb 25 11:34:29 2016 -0800
Committer: Darrel Schneider <ds...@pivotal.io>
Committed: Thu Feb 25 11:34:29 2016 -0800

----------------------------------------------------------------------
 .../internal/cache/AbstractRegionEntry.java     |  20 ++-
 .../gemfire/internal/offheap/ObjectChunk.java   | 103 +++++++++++++-
 .../offheap/OffHeapCachedDeserializable.java    | 142 -------------------
 3 files changed, 108 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/af6a01d7/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
index 558ea37..c2d6a4c 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegionEntry.java
@@ -63,9 +63,7 @@ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
 import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.ObjectChunkWithHeapForm;
-import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.MemoryAllocator;
-import com.gemstone.gemfire.internal.offheap.OffHeapCachedDeserializable;
 import com.gemstone.gemfire.internal.offheap.OffHeapHelper;
 import com.gemstone.gemfire.internal.offheap.ReferenceCountHelper;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
@@ -989,10 +987,10 @@ public abstract class AbstractRegionEntry implements RegionEntry,
       return checkPdxEquals((PdxInstance)v1, v2);
     } else if (v2 instanceof PdxInstance) {
       return checkPdxEquals((PdxInstance)v2, v1);
-    } else if (v1 instanceof OffHeapCachedDeserializable) {
-      return checkOffHeapEquals((OffHeapCachedDeserializable)v1, v2);
-    } else if (v2 instanceof OffHeapCachedDeserializable) {
-      return checkOffHeapEquals((OffHeapCachedDeserializable)v2, v1);
+    } else if (v1 instanceof ObjectChunk) {
+      return checkOffHeapEquals((ObjectChunk)v1, v2);
+    } else if (v2 instanceof ObjectChunk) {
+      return checkOffHeapEquals((ObjectChunk)v2, v1);
     } else if (v1 instanceof CachedDeserializable) {
       return checkCDEquals((CachedDeserializable)v1, v2, isCompressedOffHeap);
     } else if (v2 instanceof CachedDeserializable) {
@@ -1001,20 +999,20 @@ public abstract class AbstractRegionEntry implements RegionEntry,
       return basicEquals(v1, v2);
     }
   }
-  private static boolean checkOffHeapEquals(@Unretained OffHeapCachedDeserializable cd, @Unretained Object obj) {
+  private static boolean checkOffHeapEquals(@Unretained ObjectChunk cd, @Unretained Object obj) {
     if (cd.isSerializedPdxInstance()) {
       PdxInstance pi = InternalDataSerializer.readPdxInstance(cd.getSerializedValue(), GemFireCacheImpl.getForPdx("Could not check value equality"));
       return checkPdxEquals(pi, obj);
     }
-    if (obj instanceof OffHeapCachedDeserializable) {
-      return cd.checkDataEquals((OffHeapCachedDeserializable)obj);
+    if (obj instanceof ObjectChunk) {
+      return cd.checkDataEquals((ObjectChunk)obj);
     } else {
       byte[] serializedObj;
       if (obj instanceof CachedDeserializable) {
         if (!cd.isSerialized()) {
           if (obj instanceof StoredObject && !((StoredObject) obj).isSerialized()) {
             // both are byte[]
-            // obj must be DataAsAddress since it was not OffHeapCachedDeserializable
+            // obj must be DataAsAddress since it was not ObjectChunk
             // so its byte[] will be small.
             byte[] objBytes = (byte[]) ((StoredObject) obj).getDeserializedForReading();
             return cd.checkDataEquals(objBytes);
@@ -1574,7 +1572,7 @@ public abstract class AbstractRegionEntry implements RegionEntry,
 
   protected StringBuilder appendFieldsToString(final StringBuilder sb) {
     sb.append("key=").append(getKey()).append("; rawValue=")
-        .append(_getValue()); // OFFHEAP _getValue ok: the current toString on OffHeapCachedDeserializable is safe to use without incing refcount.
+        .append(_getValue()); // OFFHEAP _getValue ok: the current toString on ObjectChunk is safe to use without incing refcount.
     VersionStamp stamp = getVersionStamp();
     if (stamp != null) {
       sb.append("; version=").append(stamp.asVersionTag()+";member="+stamp.getMemberID());

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/af6a01d7/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
index 29e6956..840d8e5 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/ObjectChunk.java
@@ -27,6 +27,8 @@ import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.internal.DSCODE;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
+import com.gemstone.gemfire.internal.cache.EntryBits;
 import com.gemstone.gemfire.internal.cache.EntryEventImpl;
 import com.gemstone.gemfire.internal.cache.RegionEntry;
 import com.gemstone.gemfire.internal.cache.RegionEntryContext;
@@ -41,7 +43,7 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
    * to it in the cache. Instead the memoryAddress is stored in a primitive field in
    * the cache and if used it will then, if needed, create an instance of this class.
    */
-  public class ObjectChunk extends OffHeapCachedDeserializable implements Comparable<ObjectChunk>, MemoryBlock {
+  public class ObjectChunk extends AbstractStoredObject implements MemoryChunkWithRefCount, Comparable<ObjectChunk>, MemoryBlock {
     /**
      * The unsafe memory address of the first byte of this chunk
      */
@@ -128,6 +130,102 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       this.memoryAddress = chunk.memoryAddress;
     }
     
+    @Override
+    public void fillSerializedValue(BytesAndBitsForCompactor wrapper, byte userBits) {
+      if (isSerialized()) {
+        userBits = EntryBits.setSerialized(userBits, true);
+      }
+      wrapper.setChunkData((ObjectChunk) this, userBits);
+    }
+    
+    String getShortClassName() {
+      String cname = getClass().getName();
+      return cname.substring(getClass().getPackage().getName().length()+1);
+    }
+
+    public boolean checkDataEquals(@Unretained ObjectChunk other) {
+      if (this == other) {
+        return true;
+      }
+      if (isSerialized() != other.isSerialized()) {
+        return false;
+      }
+      int mySize = getValueSizeInBytes();
+      if (mySize != other.getValueSizeInBytes()) {
+        return false;
+      }
+      // We want to be able to do this operation without copying any of the data into the heap.
+      // Hopefully the jvm is smart enough to use our stack for this short lived array.
+      final byte[] dataCache1 = new byte[1024];
+      final byte[] dataCache2 = new byte[dataCache1.length];
+      // TODO OFFHEAP: no need to copy to heap. Just get the address of each and compare each byte.
+      int i;
+      // inc it twice since we are reading two different off-heap objects
+      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+      for (i=0; i < mySize-(dataCache1.length-1); i+=dataCache1.length) {
+        this.readBytes(i, dataCache1);
+        other.readBytes(i, dataCache2);
+        for (int j=0; j < dataCache1.length; j++) {
+          if (dataCache1[j] != dataCache2[j]) {
+            return false;
+          }
+        }
+      }
+      int bytesToRead = mySize-i;
+      if (bytesToRead > 0) {
+        // need to do one more read which will be less than dataCache.length
+        this.readBytes(i, dataCache1, 0, bytesToRead);
+        other.readBytes(i, dataCache2, 0, bytesToRead);
+        for (int j=0; j < bytesToRead; j++) {
+          if (dataCache1[j] != dataCache2[j]) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+    
+    public boolean isSerializedPdxInstance() {
+      byte dsCode = this.readByte(0);
+      return dsCode == DSCODE.PDX || dsCode == DSCODE.PDX_ENUM || dsCode == DSCODE.PDX_INLINE_ENUM;
+    }
+    
+    public boolean checkDataEquals(byte[] serializedObj) {
+      // caller was responsible for checking isSerialized
+      int mySize = getValueSizeInBytes();
+      if (mySize != serializedObj.length) {
+        return false;
+      }
+      // We want to be able to do this operation without copying any of the data into the heap.
+      // Hopefully the jvm is smart enough to use our stack for this short lived array.
+      // TODO OFFHEAP: compare as ByteBuffers?
+      final byte[] dataCache = new byte[1024];
+      int idx=0;
+      int i;
+      SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
+      for (i=0; i < mySize-(dataCache.length-1); i+=dataCache.length) {
+        this.readBytes(i, dataCache);
+        for (int j=0; j < dataCache.length; j++) {
+          if (dataCache[j] != serializedObj[idx++]) {
+            return false;
+          }
+        }
+      }
+      int bytesToRead = mySize-i;
+      if (bytesToRead > 0) {
+        // need to do one more read which will be less than dataCache.length
+        this.readBytes(i, dataCache, 0, bytesToRead);
+        for (int j=0; j < bytesToRead; j++) {
+          if (dataCache[j] != serializedObj[idx++]) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    
     /**
      * Throw an exception if this chunk is not allocated
      */
@@ -402,9 +500,6 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
       return (int)(value ^ (value >>> 32));
     }
 
-    // OffHeapCachedDeserializable methods 
-    
-    @Override
     public void setSerializedValue(byte[] value) {
       writeBytes(0, value);
     }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/af6a01d7/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
deleted file mode 100644
index bd380e2..0000000
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapCachedDeserializable.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 com.gemstone.gemfire.internal.offheap;
-
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.internal.DSCODE;
-import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor;
-import com.gemstone.gemfire.internal.cache.EntryBits;
-import com.gemstone.gemfire.internal.cache.RegionEntry;
-import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
-
-/**
- * This abstract class is intended to be used by {@link MemoryChunk} implementations that also want
- * to be a CachedDeserializable.
- * 
- * @author darrel
- * @since 9.0
- */
-public abstract class OffHeapCachedDeserializable extends AbstractStoredObject implements MemoryChunkWithRefCount {
-  public abstract void setSerializedValue(byte[] value);
-  @Override
-  public abstract byte[] getSerializedValue();
-  @Override
-  public abstract int getSizeInBytes();
-  @Override
-  public abstract int getValueSizeInBytes();
-  @Override
-  public abstract Object getDeserializedValue(Region r, RegionEntry re);
-
-  @Override
-  public void fillSerializedValue(BytesAndBitsForCompactor wrapper, byte userBits) {
-    if (isSerialized()) {
-      userBits = EntryBits.setSerialized(userBits, true);
-    }
-    wrapper.setChunkData((ObjectChunk) this, userBits);
-  }
-  
-  String getShortClassName() {
-    String cname = getClass().getName();
-    return cname.substring(getClass().getPackage().getName().length()+1);
-  }
-
-  @Override
-  public String toString() {
-    return getShortClassName()+"@"+this.hashCode();
-  }
-  public boolean checkDataEquals(@Unretained OffHeapCachedDeserializable other) {
-    if (this == other) {
-      return true;
-    }
-    if (isSerialized() != other.isSerialized()) {
-      return false;
-    }
-    int mySize = getValueSizeInBytes();
-    if (mySize != other.getValueSizeInBytes()) {
-      return false;
-    }
-    // We want to be able to do this operation without copying any of the data into the heap.
-    // Hopefully the jvm is smart enough to use our stack for this short lived array.
-    final byte[] dataCache1 = new byte[1024];
-    final byte[] dataCache2 = new byte[dataCache1.length];
-    // TODO OFFHEAP: no need to copy to heap. Just get the address of each and compare each byte.
-    int i;
-    // inc it twice since we are reading two different off-heap objects
-    SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
-    SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
-    for (i=0; i < mySize-(dataCache1.length-1); i+=dataCache1.length) {
-      this.readBytes(i, dataCache1);
-      other.readBytes(i, dataCache2);
-      for (int j=0; j < dataCache1.length; j++) {
-        if (dataCache1[j] != dataCache2[j]) {
-          return false;
-        }
-      }
-    }
-    int bytesToRead = mySize-i;
-    if (bytesToRead > 0) {
-      // need to do one more read which will be less than dataCache.length
-      this.readBytes(i, dataCache1, 0, bytesToRead);
-      other.readBytes(i, dataCache2, 0, bytesToRead);
-      for (int j=0; j < bytesToRead; j++) {
-        if (dataCache1[j] != dataCache2[j]) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-  
-  public boolean isSerializedPdxInstance() {
-    byte dsCode = this.readByte(0);
-    return dsCode == DSCODE.PDX || dsCode == DSCODE.PDX_ENUM || dsCode == DSCODE.PDX_INLINE_ENUM;
-  }
-  
-  public boolean checkDataEquals(byte[] serializedObj) {
-    // caller was responsible for checking isSerialized
-    int mySize = getValueSizeInBytes();
-    if (mySize != serializedObj.length) {
-      return false;
-    }
-    // We want to be able to do this operation without copying any of the data into the heap.
-    // Hopefully the jvm is smart enough to use our stack for this short lived array.
-    // TODO OFFHEAP: compare as ByteBuffers?
-    final byte[] dataCache = new byte[1024];
-    int idx=0;
-    int i;
-    SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads();
-    for (i=0; i < mySize-(dataCache.length-1); i+=dataCache.length) {
-      this.readBytes(i, dataCache);
-      for (int j=0; j < dataCache.length; j++) {
-        if (dataCache[j] != serializedObj[idx++]) {
-          return false;
-        }
-      }
-    }
-    int bytesToRead = mySize-i;
-    if (bytesToRead > 0) {
-      // need to do one more read which will be less than dataCache.length
-      this.readBytes(i, dataCache, 0, bytesToRead);
-      for (int j=0; j < bytesToRead; j++) {
-        if (dataCache[j] != serializedObj[idx++]) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-}