You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by es...@apache.org on 2018/06/08 00:21:11 UTC

[geode] branch feature/GEODE-5302 updated: GEODE-5302: set totalLiveCount to 0 after successfuly compacted the oplog.

This is an automated email from the ASF dual-hosted git repository.

eshu11 pushed a commit to branch feature/GEODE-5302
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/feature/GEODE-5302 by this push:
     new aa75aca  GEODE-5302: set totalLiveCount to 0 after successfuly compacted the oplog.
aa75aca is described below

commit aa75aca398d1f3e823e5711aa034fe25f33b6ebf
Author: eshu <es...@pivotal.io>
AuthorDate: Thu Jun 7 17:19:22 2018 -0700

    GEODE-5302: set totalLiveCount to 0 after successfuly compacted the oplog.
---
 .../org/apache/geode/internal/cache/Oplog.java     | 32 ++++----
 .../org/apache/geode/internal/cache/OplogTest.java | 86 ++++++++++++++++++++++
 2 files changed, 105 insertions(+), 13 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java b/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java
index 2ff97d5..b1fdcd1 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/Oplog.java
@@ -216,16 +216,16 @@ public class Oplog implements CompactableOplog, Flushable {
    * Written to CRF, and DRF.
    */
   private static final byte OPLOG_EOF_ID = 0;
-  private static final byte END_OF_RECORD_ID = 21;
 
+  private static final byte END_OF_RECORD_ID = 21;
   /**
    * Written to CRF and DRF. Followed by 16 bytes which is the leastSigBits and mostSigBits of a
    * UUID for the disk store we belong to. 1: EndOfRecord Is written once at the beginning of every
    * oplog file.
    */
   private static final byte OPLOG_DISK_STORE_ID = 62;
-  static final int OPLOG_DISK_STORE_REC_SIZE = 1 + 16 + 1;
 
+  static final int OPLOG_DISK_STORE_REC_SIZE = 1 + 16 + 1;
   /**
    * Written to CRF. Followed by 8 bytes which is the BASE_ID to use for any NEW_ENTRY records. 1:
    * EndOfRecord Only needs to be written once per oplog and must preceed any OPLOG_NEW_ENTRY_0ID
@@ -413,6 +413,7 @@ public class Oplog implements CompactableOplog, Flushable {
    * @since GemFire prPersistSprint1
    */
   private static final byte OPLOG_DEL_ENTRY_1ID = 81;
+
   /**
    * Written to DRF. The OplogEntryId is relative to the previous del_entry OplogEntryId. The signed
    * difference is encoded in 2 bytes. Byte Format: 2: OplogEntryId 1: EndOfRecord
@@ -420,7 +421,6 @@ public class Oplog implements CompactableOplog, Flushable {
    * @since GemFire prPersistSprint1
    */
   private static final byte OPLOG_DEL_ENTRY_2ID = 82;
-
   /**
    * Written to DRF. The OplogEntryId is relative to the previous del_entry OplogEntryId. The signed
    * difference is encoded in 3 bytes. Byte Format: 3: OplogEntryId 1: EndOfRecord
@@ -5854,14 +5854,14 @@ public class Oplog implements CompactableOplog, Flushable {
 
   private static final ThreadLocal isCompactorThread = new ThreadLocal();
 
-  private boolean calledByCompactorThread() {
+  boolean calledByCompactorThread() {
     if (!this.compacting)
       return false;
     Object v = isCompactorThread.get();
     return v != null && v == Boolean.TRUE;
   }
 
-  private void handleNoLiveValues() {
+  void handleNoLiveValues() {
     if (!this.doneAppending)
       return;
     if (hasNoLiveValues()) {
@@ -6062,14 +6062,7 @@ public class Oplog implements CompactableOplog, Flushable {
           }
         }
 
-        if (!compactFailed) {
-          // Need to still remove the oplog even if it had nothing to compact.
-          handleNoLiveValues();
-
-          // We can't assert hasNoLiveValues() because a race condition exists
-          // in which our liveEntries list is empty but the liveCount has not
-          // yet been decremented.
-        }
+        cleanupAfterCompaction(compactFailed);
         return totalCount;
       } finally {
         unlockCompactor();
@@ -6081,6 +6074,19 @@ public class Oplog implements CompactableOplog, Flushable {
     }
   }
 
+  void cleanupAfterCompaction(boolean compactFailed) {
+    if (!compactFailed) {
+      // all data has been copied forward to new oplog so no live entries remain
+      getTotalLiveCount().set(0);
+      // Need to still remove the oplog even if it had nothing to compact.
+      handleNoLiveValues();
+    }
+  }
+
+  AtomicLong getTotalLiveCount() {
+    return totalLiveCount;
+  }
+
   public static boolean isCRFFile(String filename) {
     return filename.endsWith(Oplog.CRF_FILE_EXT);
   }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/OplogTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/OplogTest.java
new file mode 100644
index 0000000..69ce89a
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/OplogTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class OplogTest {
+  private final DiskStoreImpl.OplogCompactor compactor = mock(DiskStoreImpl.OplogCompactor.class);
+  private final PersistentOplogSet parent = mock(PersistentOplogSet.class);
+  private final long oplogId = 1;
+  private Oplog oplog;
+
+  @Before
+  public void setup() {
+    when(parent.getParent()).thenReturn(mock(DiskStoreImpl.class));
+    oplog = spy(new Oplog(oplogId, parent));
+    doReturn(true).when(oplog).needsCompaction();
+    doReturn(true).when(oplog).calledByCompactorThread();
+  }
+
+  @Test
+  public void noCompactIfDoesNotNeedCompaction() {
+    doReturn(false).when(oplog).needsCompaction();
+    assertThat(oplog.compact(compactor)).isEqualTo(0);
+  }
+
+  @Test
+  public void noCompactIfNotKeepCompactorRunning() {
+    when(compactor.keepCompactorRunning()).thenReturn(false);
+    assertThat(oplog.compact(compactor)).isEqualTo(0);
+  }
+
+  @Test
+  public void handlesNoLiveValuesIfNoLiveValueInOplog() {
+    when(compactor.keepCompactorRunning()).thenReturn(true);
+
+    doReturn(true).when(oplog).hasNoLiveValues();
+    assertThat(oplog.compact(compactor)).isEqualTo(0);
+    verify(oplog, times(1)).handleNoLiveValues();
+  }
+
+  @Test
+  public void invockeCleanupAfterCompaction() {
+    when(compactor.keepCompactorRunning()).thenReturn(true);
+    doReturn(mock(DiskStoreStats.class)).when(oplog).getStats();
+    doReturn(false).when(oplog).hasNoLiveValues();
+    oplog.compact(compactor);
+    verify(oplog, times(1)).cleanupAfterCompaction(eq(false));
+  }
+
+  @Test
+  public void handlesNoLiveValuesIfCompactSuccessful() {
+    oplog.getTotalLiveCount().set(5);
+    oplog.cleanupAfterCompaction(false);
+    verify(oplog, times(1)).handleNoLiveValues();
+    assertThat(oplog.getTotalLiveCount().get()).isEqualTo(0);
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
eshu11@apache.org.