Skip to content

Commit

Permalink
Merge pull request #4006 from andreitokar/issue-3909
Browse files Browse the repository at this point in the history
Housekeeping refinement
  • Loading branch information
andreitokar committed Mar 24, 2024
2 parents 8f5c541 + b3c20eb commit e69ff62
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
7 changes: 4 additions & 3 deletions h2/src/main/org/h2/mvstore/FileStore.java
Expand Up @@ -423,7 +423,7 @@ public final void setAutoCommitDelay(int millis) {
stopBackgroundThread(millis >= 0);
// start the background thread if needed
if (millis > 0 && mvStore.isOpen()) {
int sleep = Math.max(1, millis / 10);
int sleep = Math.max(10, millis / 3);
BackgroundWriterThread t = new BackgroundWriterThread(this, sleep, toString());
if (backgroundWriterThread.compareAndSet(null, t)) {
t.start();
Expand Down Expand Up @@ -622,7 +622,7 @@ protected final boolean hasPersistentData() {
}

protected final boolean isIdle() {
return autoCompactLastFileOpCount == getWriteCount() + getReadCount();
return autoCompactLastFileOpCount >= getWriteCount() + getReadCount();
}

protected final void setLastChunk(C last) {
Expand Down Expand Up @@ -1835,7 +1835,8 @@ void writeInBackground() {
mvStore.tryCommit();
}
doHousekeeping(mvStore);
autoCompactLastFileOpCount = getWriteCount() + getReadCount();
// less than 10 I/O operations will still count as "idle"
autoCompactLastFileOpCount = getWriteCount() + getReadCount() + 10;
}
} catch (InterruptedException ignore) {
} catch (Throwable e) {
Expand Down
6 changes: 2 additions & 4 deletions h2/src/main/org/h2/mvstore/FreeSpaceBitSet.java
Expand Up @@ -145,10 +145,8 @@ private int allocate(int blocks, int reservedLow, int reservedHigh, boolean allo
int freeBlocks = end - start;
if (end < 0 || freeBlocks >= blocks) {
if ((reservedHigh < 0 || start < reservedHigh) && start + blocks > reservedLow) { // overlap detected
if (reservedHigh < 0) {
start = getAfterLastBlock();
end = -1;
} else {
if (reservedHigh >= 0) {
freeBlocksTotal += freeBlocks;
i = reservedHigh;
continue;
}
Expand Down
34 changes: 21 additions & 13 deletions h2/src/main/org/h2/mvstore/RandomAccessStore.java
Expand Up @@ -703,45 +703,53 @@ private void shrinkIfPossible(int minPercent) {
@Override
protected void doHousekeeping(MVStore mvStore) throws InterruptedException {
boolean idle = isIdle();
int rewritableChunksFillRate = getRewritableChunksFillRate();
if (idle && stopIdleHousekeeping) {
return;
}
int autoCommitMemory = mvStore.getAutoCommitMemory();
int fillRate = getFillRate();
if (isFragmented() && fillRate < getAutoCompactFillRate()) {
int fileFillRate = getFillRate();
long chunksTotalSize = size() * fileFillRate / 100;
if (isFragmented() && fileFillRate < getAutoCompactFillRate()) {
mvStore.tryExecuteUnderStoreLock(() -> {
int moveSize = 2 * autoCommitMemory;
if (isIdle()) {
if (idle) {
moveSize *= 4;
}
compactMoveChunks(101, moveSize, mvStore);
return true;
});
}

int chunksFillRate = getRewritableChunksFillRate();
int adjustedChunksFillRate = 100 - (100 - chunksFillRate) / 2;
int fillRateToCompare = isIdle() ? chunksFillRate : adjustedChunksFillRate;
if (fillRateToCompare < getTargetFillRate()) {
int chunksFillRate = getChunksFillRate();
int adjustedUpFillRate = 50 + rewritableChunksFillRate / 2;
int fillRateToCompare = idle ? rewritableChunksFillRate : adjustedUpFillRate;
if (fillRateToCompare < getTargetFillRate(idle)) {
int targetFillRate = idle ? adjustedUpFillRate : rewritableChunksFillRate;
mvStore.tryExecuteUnderStoreLock(() -> {
int writeLimit = autoCommitMemory;
if (!isIdle()) {
if (!idle) {
writeLimit /= 4;
}
if (rewriteChunks(writeLimit, isIdle() ? adjustedChunksFillRate : chunksFillRate)) {
if (rewriteChunks(writeLimit, targetFillRate)) {
dropUnusedChunks();
}
return true;
});
}
stopIdleHousekeeping = idle && getFillRate() <= fillRate && getRewritableChunksFillRate() <= chunksFillRate;
stopIdleHousekeeping = false;
if (idle) {
int currentChunksFillRate = getChunksFillRate();
long currentTotalChunksSize = size() * getFillRate() / 100;
stopIdleHousekeeping = currentTotalChunksSize > chunksTotalSize || currentTotalChunksSize == chunksTotalSize && currentChunksFillRate <= chunksFillRate;
}
}

private int getTargetFillRate() {
private int getTargetFillRate(boolean idle) {
int targetRate = getAutoCompactFillRate();
// use a lower fill rate if there were any file operations since the last time
if (!isIdle()) {
targetRate /= 2;
if (!idle) {
targetRate = targetRate * targetRate / 100;
}
return targetRate;
}
Expand Down

0 comments on commit e69ff62

Please sign in to comment.