Skip to content

Commit 27a133f

Browse files
committed
Sync with main
Signed-off-by: Artem Ananev <[email protected]>
2 parents a02d19d + 1e9b28d commit 27a133f

File tree

11 files changed

+283
-165
lines changed

11 files changed

+283
-165
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
# SPDX-License-Identifier: Apache-2.0
12
version: 2
23
updates:
4+
- package-ecosystem: "gradle"
5+
directory: "/" # for 'plugins { }' in 'settings.gradle.kts'
6+
schedule:
7+
interval: "daily"
8+
open-pull-requests-limit: 10
39
- package-ecosystem: "gradle"
410
directory: "/hiero-dependency-versions"
511
schedule:

hiero-dependency-versions/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ val junit5 = "5.10.3!!" // no updates beyond 5.10.3 until #17125 is resolved
2828
val log4j = "2.24.3"
2929
val mockito = "5.17.0"
3030
val pbj = "0.11.6" // ATTENTION: keep in sync with plugin version in 'hapi/hapi/build.gradle.kts'
31-
val protobuf = "4.30.2"
31+
val protobuf = "4.31.0"
3232
val testContainers = "1.21.0"
3333
val tuweni = "2.4.2"
3434
val webcompare = "2.1.8"
@@ -50,7 +50,7 @@ dependencies.constraints {
5050
because("com.fasterxml.jackson.dataformat.yaml")
5151
}
5252
api("com.github.ben-manes.caffeine:caffeine:3.2.0") { because("com.github.benmanes.caffeine") }
53-
api("com.github.docker-java:docker-java-api:3.5.0") { because("com.github.dockerjava.api") }
53+
api("com.github.docker-java:docker-java-api:3.5.1") { because("com.github.dockerjava.api") }
5454
api("com.github.spotbugs:spotbugs-annotations:4.9.3") {
5555
because("com.github.spotbugs.annotations")
5656
}
@@ -111,7 +111,7 @@ dependencies.constraints {
111111
because("org.hyperledger.besu.nativelib.secp256k1")
112112
}
113113
api("org.jetbrains:annotations:26.0.2") { because("org.jetbrains.annotations") }
114-
api("org.json:json:20250107") { because("org.json") }
114+
api("org.json:json:20250517") { because("org.json") }
115115
api("org.junit.jupiter:junit-jupiter-api:$junit5") { because("org.junit.jupiter.api") }
116116
api("org.junit.jupiter:junit-jupiter-engine:$junit5") { because("org.junit.jupiter.engine") }
117117
api("org.junit-pioneer:junit-pioneer:2.3.0") { because("org.junitpioneer") }

platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/MerkleDbCompactionCoordinator.java

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@
1313
import edu.umd.cs.findbugs.annotations.NonNull;
1414
import java.io.IOException;
1515
import java.nio.channels.ClosedByInterruptException;
16+
import java.util.HashMap;
1617
import java.util.Map;
1718
import java.util.concurrent.Callable;
18-
import java.util.concurrent.ConcurrentHashMap;
1919
import java.util.concurrent.ExecutorService;
20-
import java.util.concurrent.Future;
2120
import java.util.concurrent.LinkedBlockingQueue;
2221
import java.util.concurrent.ThreadPoolExecutor;
2322
import java.util.concurrent.TimeUnit;
24-
import java.util.concurrent.atomic.AtomicBoolean;
25-
import java.util.concurrent.atomic.AtomicInteger;
2623
import org.apache.logging.log4j.LogManager;
2724
import org.apache.logging.log4j.Logger;
2825

@@ -75,21 +72,15 @@ static synchronized ExecutorService getCompactionExecutor(final @NonNull MerkleD
7572
return compactionExecutor;
7673
}
7774

78-
private final AtomicBoolean compactionEnabled = new AtomicBoolean();
75+
// Synchronized on this
76+
private boolean compactionEnabled = false;
7977

80-
// A map of compactor futures by task names
81-
final Map<String, Future<Boolean>> futuresByName = new ConcurrentHashMap<>(16);
82-
83-
// A map of compactors by task names
84-
final Map<String, DataFileCompactor> compactorsByName = new ConcurrentHashMap<>(16);
78+
// A map of compactors by task names. Synchronized on this
79+
final Map<String, DataFileCompactor> compactorsByName = new HashMap<>(16);
8580

8681
@NonNull
8782
private final MerkleDbConfig merkleDbConfig;
8883

89-
// Number of compaction tasks currently running. Checked during shutdown to make sure all
90-
// tasks are stopped
91-
private final AtomicInteger tasksRunning = new AtomicInteger(0);
92-
9384
/**
9485
* Creates a new instance of {@link MerkleDbCompactionCoordinator}.
9586
* @param tableName the name of the table
@@ -104,8 +95,8 @@ public MerkleDbCompactionCoordinator(@NonNull String tableName, @NonNull MerkleD
10495
/**
10596
* Enables background compaction.
10697
*/
107-
void enableBackgroundCompaction() {
108-
compactionEnabled.set(true);
98+
synchronized void enableBackgroundCompaction() {
99+
compactionEnabled = true;
109100
}
110101

111102
/**
@@ -114,7 +105,7 @@ void enableBackgroundCompaction() {
114105
* critical for snapshots (e.g. update an index), it will be stopped until {@link
115106
* #resumeCompaction()}} is called.
116107
*/
117-
public void pauseCompaction() throws IOException {
108+
synchronized void pauseCompaction() throws IOException {
118109
for (final DataFileCompactor compactor : compactorsByName.values()) {
119110
compactor.pauseCompaction();
120111
}
@@ -123,7 +114,7 @@ public void pauseCompaction() throws IOException {
123114
/**
124115
* Resumes previously stopped data file collection compaction.
125116
*/
126-
public void resumeCompaction() throws IOException {
117+
synchronized void resumeCompaction() throws IOException {
127118
for (final DataFileCompactor compactor : compactorsByName.values()) {
128119
compactor.resumeCompaction();
129120
}
@@ -133,26 +124,24 @@ public void resumeCompaction() throws IOException {
133124
* Stops all compactions in progress and disables background compaction. All subsequent calls to
134125
* compacting methods will be ignored until {@link #enableBackgroundCompaction()} is called.
135126
*/
136-
void stopAndDisableBackgroundCompaction() {
137-
compactionEnabled.set(false);
127+
synchronized void stopAndDisableBackgroundCompaction() {
128+
// Make sure no new compaction tasks are scheduled
129+
compactionEnabled = false;
138130
// Interrupt all running compaction tasks, if any
139-
for (final Future<Boolean> futureEntry : futuresByName.values()) {
140-
futureEntry.cancel(true);
131+
for (final DataFileCompactor compactor : compactorsByName.values()) {
132+
compactor.interruptCompaction();
141133
}
142-
futuresByName.clear();
143-
compactorsByName.clear();
144134
// Wait till all the tasks are stopped
145-
final long now = System.currentTimeMillis();
146135
try {
147-
while ((tasksRunning.get() != 0) && (System.currentTimeMillis() - now < SHUTDOWN_TIMEOUT_MILLIS)) {
148-
Thread.sleep(1);
136+
while (!compactorsByName.isEmpty()) {
137+
wait(SHUTDOWN_TIMEOUT_MILLIS);
149138
}
150139
} catch (final InterruptedException e) {
151140
logger.warn(MERKLE_DB.getMarker(), "Interrupted while waiting for compaction tasks to complete", e);
152141
}
153142
// If some tasks are still running, there is nothing else to than to log it
154-
if (tasksRunning.get() != 0) {
155-
logger.error(MERKLE_DB.getMarker(), "Failed to stop all compactions tasks");
143+
if (!compactorsByName.isEmpty()) {
144+
logger.warn(MERKLE_DB.getMarker(), "Timed out waiting to stop all compactions tasks");
156145
}
157146
}
158147

@@ -163,19 +152,18 @@ void stopAndDisableBackgroundCompaction() {
163152
* @param key Compaction task name
164153
* @param compactor Compactor to run
165154
*/
166-
public void compactIfNotRunningYet(final String key, final DataFileCompactor compactor) {
167-
if (!compactionEnabled.get()) {
155+
public synchronized void compactIfNotRunningYet(final String key, final DataFileCompactor compactor) {
156+
if (!compactionEnabled) {
168157
return;
169158
}
170159
if (isCompactionRunning(key)) {
171160
logger.info(MERKLE_DB.getMarker(), "Compaction for {} is already in progress", key);
172161
return;
173162
}
174-
assert !compactorsByName.containsKey(key);
175163
compactorsByName.put(key, compactor);
176164
final ExecutorService executor = getCompactionExecutor(merkleDbConfig);
177165
final CompactionTask task = new CompactionTask(key, compactor);
178-
futuresByName.put(key, executor.submit(task));
166+
executor.submit(task);
179167
}
180168

181169
/**
@@ -184,13 +172,12 @@ public void compactIfNotRunningYet(final String key, final DataFileCompactor com
184172
* @param key Compactor name
185173
* @return {@code true} if compaction with this name is currently running, {@code false} otherwise
186174
*/
187-
public boolean isCompactionRunning(final String key) {
188-
final Future<?> future = futuresByName.get(key);
189-
return (future != null) && !future.isDone();
175+
synchronized boolean isCompactionRunning(final String key) {
176+
return compactorsByName.containsKey(key);
190177
}
191178

192-
boolean isCompactionEnabled() {
193-
return compactionEnabled.get();
179+
synchronized boolean isCompactionEnabled() {
180+
return compactionEnabled;
194181
}
195182

196183
/**
@@ -211,7 +198,6 @@ public CompactionTask(@NonNull String id, @NonNull DataFileCompactor compactor)
211198

212199
@Override
213200
public Boolean call() {
214-
tasksRunning.incrementAndGet();
215201
try {
216202
return compactor.compact();
217203
} catch (final InterruptedException | ClosedByInterruptException e) {
@@ -221,9 +207,10 @@ public Boolean call() {
221207
// will stop all future merges from happening
222208
logger.error(EXCEPTION.getMarker(), "[{}] Compaction failed", id, e);
223209
} finally {
224-
compactorsByName.remove(id);
225-
futuresByName.remove(id);
226-
tasksRunning.decrementAndGet();
210+
synchronized (MerkleDbCompactionCoordinator.this) {
211+
compactorsByName.remove(id);
212+
MerkleDbCompactionCoordinator.this.notifyAll();
213+
}
227214
}
228215
return false;
229216
}

platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/collections/AbstractLongList.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.swirlds.merkledb.config.MerkleDbConfig;
1313
import com.swirlds.merkledb.utilities.MerkleDbFileUtils;
1414
import edu.umd.cs.findbugs.annotations.NonNull;
15+
import edu.umd.cs.findbugs.annotations.Nullable;
1516
import java.io.IOException;
1617
import java.nio.ByteBuffer;
1718
import java.nio.channels.FileChannel;
@@ -20,8 +21,10 @@
2021
import java.nio.file.StandardOpenOption;
2122
import java.util.ArrayList;
2223
import java.util.List;
24+
import java.util.Objects;
2325
import java.util.concurrent.atomic.AtomicLong;
2426
import java.util.concurrent.atomic.AtomicReferenceArray;
27+
import java.util.function.BooleanSupplier;
2528
import java.util.stream.LongStream;
2629
import java.util.stream.StreamSupport;
2730

@@ -781,20 +784,30 @@ private void checkValue(final long value) {
781784
}
782785
}
783786

784-
/** {@inheritDoc} */
787+
/**
788+
* {@inheritDoc}
789+
*
790+
* <p>This long list implementation checks the condition (if not null) before every list
791+
* item is processed.
792+
*/
785793
@Override
786-
public <T extends Throwable> void forEach(final LongAction<T> action) throws InterruptedException, T {
794+
public <T extends Throwable> boolean forEach(
795+
@NonNull final LongAction<T> action, @Nullable final BooleanSupplier cond) throws InterruptedException, T {
787796
final long max = maxValidIndex.get();
788797
if (max < 0) {
789798
// Empty list, nothing to do
790-
return;
799+
return true;
791800
}
792-
for (long i = minValidIndex.get(); i <= max; i++) {
801+
Objects.requireNonNull(action);
802+
final BooleanSupplier condition = cond != null ? cond : () -> true;
803+
long i = minValidIndex.get();
804+
for (; (i <= max) && condition.getAsBoolean(); i++) {
793805
final long value = get(i);
794806
if (value != IMPERMISSIBLE_VALUE) {
795807
action.handle(i, value);
796808
}
797809
}
810+
return i == max + 1;
798811
}
799812

800813
/**

platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/collections/CASableLongIndex.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// SPDX-License-Identifier: Apache-2.0
22
package com.swirlds.merkledb.collections;
33

4+
import edu.umd.cs.findbugs.annotations.NonNull;
5+
import edu.umd.cs.findbugs.annotations.Nullable;
6+
import java.util.function.BooleanSupplier;
7+
48
/**
59
* An interface for classes that provide long index functionality. Such long indices must
610
* support Compare-And-Swap operations and iterations over all valid index entries.
@@ -33,17 +37,25 @@ public interface CASableLongIndex {
3337
/**
3438
* Iterates over all valid index entries and calls the specified action for each of them.
3539
*
36-
* @param action Action to call.
40+
* <p>If a condition to check is provided, implementations should do their best checking it,
41+
* but there is no guarantee it is checked before each entry in the list, or checked at all.
42+
* If the condition is {@code false}, no more index entries are iterated over, and this
43+
* method returns.
44+
*
3745
* @param <T> Type of throwables allowed to throw by this method
46+
* @param action Action to call
47+
* @param whileCondition Optional condition to check if this method should be stopped
48+
* @return {@code true} if all index items have been processed by this method
3849
* @throws InterruptedException If the thread running the method is interrupted
3950
* @throws T If an error occurs
4051
*/
41-
<T extends Throwable> void forEach(LongAction<T> action) throws InterruptedException, T;
52+
<T extends Throwable> boolean forEach(@NonNull LongAction<T> action, @Nullable BooleanSupplier whileCondition)
53+
throws InterruptedException, T;
4254

4355
/**
44-
* Action interface to use in {@link #forEach(LongAction)}. It could be a standard Java API
45-
* interface like BiFunction, but all these APIs work with boxed Long type instead of
46-
* primitive longs, which adds unnecessary load on GC. So let's use something more simple
56+
* Action interface to use in {@link #forEach(LongAction, BooleanSupplier)}. It could be a standard Java
57+
* API interface like BiFunction, but all these APIs work with boxed Long type instead of primitive
58+
* longs, which adds unnecessary load on GC. So let's use something more simple
4759
*
4860
* @param <T> Type of throwable allowed to throw by the action
4961
*/

0 commit comments

Comments
 (0)