You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by sa...@apache.org on 2016/02/27 02:06:05 UTC

incubator-geode git commit: GEODE-996: OffheapStats - fragmentation percentage calculation has to be revisited.

Repository: incubator-geode
Updated Branches:
  refs/heads/feature/GEODE-996 [created] f15010cf6


GEODE-996: OffheapStats - fragmentation percentage calculation has to be revisited.


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

Branch: refs/heads/feature/GEODE-996
Commit: f15010cf6996e7d82c27ee9573e708182d061a80
Parents: 4fed7d8
Author: Sai Boorlagadda <sb...@pivotal.io>
Authored: Fri Feb 26 13:46:32 2016 -0800
Committer: Sai Boorlagadda <sb...@pivotal.io>
Committed: Fri Feb 26 17:05:38 2016 -0800

----------------------------------------------------------------------
 .../internal/offheap/FreeListManager.java       | 38 ++++++++------
 .../internal/offheap/OffHeapStorage.java        |  2 +-
 .../internal/offheap/FreeListManagerTest.java   | 53 ++++++++++++++++++++
 3 files changed, 78 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f15010cf/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
index a716f14..5d5d688 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/FreeListManager.java
@@ -437,7 +437,7 @@ public class FreeListManager {
 
         this.ma.getStats().setLargestFragment(largestFragment);
         this.ma.getStats().setFragments(tmp.size());        
-        updateFragmentation(largestFragment);
+        this.ma.getStats().setFragmentation(getFragmentation());
 
         return result;
       } // sync
@@ -473,21 +473,31 @@ public class FreeListManager {
     }
   }
   
-  private void updateFragmentation(long largestFragment) {      
-    long freeSize = getFreeMemory();
-
-    // Calculate free space fragmentation only if there is free space available.
-    if(freeSize > 0) {
-      long numerator = freeSize - largestFragment;
-
-      double percentage = (double) numerator / (double) freeSize;
-      percentage *= 100d;
+  protected int getNoOfFragments() {
+    return this.fragmentList.size();
+  }
+  
+  protected int getFragmentation() {
 
-      int wholePercentage = (int) Math.rint(percentage);
-      this.ma.getStats().setFragmentation(wholePercentage);
+    int availableFragments = getNoOfFragments();
+    
+    if(availableFragments < 2) {
+      //case when there are no fragments or only one fragment
+      //then freeMemory is either be 0 or as 1 fragment, so freeMemory is not fragmented.
+      return 0;
     } else {
-      // No free space? Then we have no free space fragmentation.
-      this.ma.getStats().setFragmentation(0);
+      long freeMemory = getFreeMemory();
+      long totalMemory = getTotalMemory();
+      if (freeMemory == totalMemory) {
+        //case when freeMemory is entirely totalMemory then freeMemory is not fragmented
+        return 0;
+      } else {
+        //case when freeMemory is fragmented
+        //then compare the no. of available fragments with max no. of possible fragments
+        long maxPossibleFragments = freeMemory / ObjectChunk.MIN_CHUNK_SIZE;
+        double fragmentation = (availableFragments / maxPossibleFragments) * 100.0;
+        return (int) fragmentation;
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f15010cf/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
index bb5cdeb..3156067 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
@@ -71,7 +71,7 @@ public class OffHeapStorage implements OffHeapMemoryStats {
     final String usedMemoryDesc = "The amount of off-heap memory, in bytes, that is being used to store data.";
     final String compactionsDesc = "The total number of times off-heap memory has been compacted.";
     final String compactionTimeDesc = "The total time spent compacting off-heap memory.";
-    final String fragmentationDesc = "The percentage of off-heap memory fragmentation.  Updated every time a compaction is performed.";
+    final String fragmentationDesc = "The percentage of off-heap free memory that is fragmented.  Updated every time a compaction is performed.";
     final String fragmentsDesc = "The number of fragments of free off-heap memory. Updated every time a compaction is done.";
     final String freeMemoryDesc = "The amount of off-heap memory, in bytes, that is not being used.";
     final String largestFragmentDesc = "The largest fragment of memory found by the last compaction of off heap memory. Updated every time a compaction is done.";

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f15010cf/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
index 64032cc..c32b5ee 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
@@ -739,6 +739,59 @@ public class FreeListManagerTest {
     LogWriter lw = mock(LogWriter.class);
     this.freeListManager.logOffHeapState(lw, 1024);
   }
+  
+  @Test
+  public void fragmentationShouldBeZeroIfNumberOfFragmentsIsZero() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    
+    FreeListManager spy = spy(this.freeListManager);
+    
+    when(spy.getNoOfFragments()).thenReturn(0);
+    
+    assertThat(spy.getFragmentation()).isZero();
+  }
+  
+  @Test
+  public void fragmentationShouldBeZeroIfNumberOfFragmentsIsOne() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    
+    FreeListManager spy = spy(this.freeListManager);
+    
+    when(spy.getNoOfFragments()).thenReturn(1);
+    
+    assertThat(spy.getFragmentation()).isZero();
+  }
+  
+  @Test
+  public void fragmentationShouldBeZeroIfTotalMemoryIsFree() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    
+    FreeListManager spy = spy(this.freeListManager);
+    
+    when(spy.getNoOfFragments()).thenReturn(2);
+    when(spy.getFreeMemory()).thenReturn(Long.MAX_VALUE);
+    when(spy.getTotalMemory()).thenReturn(Long.MAX_VALUE);
+    
+    assertThat(spy.getFragmentation()).isZero();
+  }
+  
+  @Test
+  public void fragmentationShouldBe100IfAllFreeMemoryIsFragmentedAsMinChunks() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    
+    FreeListManager spy = spy(this.freeListManager);
+    
+    when(spy.getNoOfFragments()).thenReturn(2);
+    when(spy.getFreeMemory()).thenReturn((long)ObjectChunk.MIN_CHUNK_SIZE * 2);
+    when(spy.getTotalMemory()).thenReturn(Long.MAX_VALUE);
+    
+    assertThat(spy.getFragmentation()).isEqualTo(100);
+  }
+  
   /**
    * Just like Fragment except that the first time allocate is called
    * it returns false indicating that the allocate failed.