diff --git a/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/data/BufferedLinearRegionFile.java b/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/data/BufferedLinearRegionFile.java index 485c782..505ee59 100644 --- a/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/data/BufferedLinearRegionFile.java +++ b/shiroha-server/src/main/java/io/nanachiyo0721/shiroha/data/BufferedLinearRegionFile.java @@ -269,13 +269,13 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R public void syncIfNeeded() throws IOException { try { - this.syncToMasterFile(); + this.syncToMasterFile(false, false); } finally { BEING_SYNCED_HANDLE.setVolatile(this, false); // mark as not being synced } } - private void syncToMasterFile() throws IOException { + private void syncToMasterFile(boolean forceSync, boolean forceCompact) throws IOException { // serialized against close: the swap channel cannot go away under a running sync synchronized (this.syncLock) { // skip if closed already @@ -285,12 +285,12 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R // fast skip when there is nothing to sync; writers flip the flag back // via markAsToSync() which triggers the next round - if (!SYNCED_HANDLE.compareAndSet(this, false, true)) { + if (!SYNCED_HANDLE.compareAndSet(this, false, true) && !forceSync) { return; } try { - this.masterFileParser.sync(this.masterFilePath); + this.masterFileParser.sync(this.masterFilePath, forceCompact); } catch (Throwable e) { // set back SYNCED_HANDLE.setVolatile(this, false); @@ -403,7 +403,7 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R } if (initiallySyncRequired) { - this.syncToMasterFile(); + this.syncToMasterFile(false, false); } } @@ -427,7 +427,7 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R // concurrent flusher sync is still running when we tear down below. // if this throws we deliberately stay open: the flusher can retry the sync // later, and the not-yet-synced swap data is not dropped on the floor - this.syncToMasterFile(); + this.syncToMasterFile(true, true); IOException failure = null; @@ -974,13 +974,13 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R } // must be called under syncLock (see syncToMasterFile) - public void sync(@NotNull Path mainFile) throws IOException { + public void sync(@NotNull Path mainFile, boolean forceCompact) throws IOException { this.masterFileLock.writeLock().lock(); try { // full rewrite on the first sync after open, and afterwards whenever the // appended garbage passed the auto-compact threshold: writes a tmp file, // then atomically replaces the master file with it - if (this.appendChannel == null || this.shouldCompactMasterFile()) { + if (this.appendChannel == null || this.shouldCompactMasterFile() || forceCompact) { this.rewriteFully(mainFile); } else { // WAL-style otherwise: only append the dirty buckets @@ -1589,7 +1589,7 @@ public class BufferedLinearRegionFile implements io.nanachiyo0721.shiroha.data.R // old parsed, remove the original file, and we will recreate it as we sync if (oldParsed) { // immediately do sync operation - BufferedLinearRegionFile.this.syncToMasterFile(); + BufferedLinearRegionFile.this.syncToMasterFile(true, true); return; }