From 7b8e9145d73c2e055e52b2778c6c970d97fc3617 Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Wed, 23 Oct 2024 13:39:37 -0500 Subject: [PATCH] formalize space type in generics formalize space --- .../adapter/diag/DriverAdapterLoader.java | 3 +- .../api/activityimpl/BaseOpDispenser.java | 15 ++++---- .../api/activityimpl/OpDispenser.java | 9 +++-- .../adapters/api/activityimpl/OpMapper.java | 21 +++++++---- .../docs/BundledDriverAdapterDocs.java | 6 ++- .../uniform/BaseDriverAdapter.java | 19 +++++----- .../api/activityimpl/uniform/BaseSpace.java | 36 ++++++++++++++++++ .../activityimpl/uniform/DriverAdapter.java | 7 ++-- .../api/activityimpl/uniform/Space.java | 37 +++++++++++++++++++ .../api/activityimpl/SimpleActivity.java | 12 +++--- .../uniform/StandardActivity.java | 24 ++++++------ 11 files changed, 141 insertions(+), 48 deletions(-) create mode 100644 nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseSpace.java create mode 100644 nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/Space.java diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapter/diag/DriverAdapterLoader.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapter/diag/DriverAdapterLoader.java index f16dd88f8..c243b4e66 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapter/diag/DriverAdapterLoader.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapter/diag/DriverAdapterLoader.java @@ -19,10 +19,11 @@ package io.nosqlbench.adapter.diag; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.nb.api.labels.NBLabels; import io.nosqlbench.nb.api.components.core.NBComponent; public interface DriverAdapterLoader { - public DriverAdapter load(NBComponent parent, NBLabels childLabels); + public DriverAdapter load(NBComponent parent, NBLabels childLabels); } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/BaseOpDispenser.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/BaseOpDispenser.java index 8a7f45d2a..d100b98e8 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/BaseOpDispenser.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/BaseOpDispenser.java @@ -19,6 +19,7 @@ package io.nosqlbench.adapters.api.activityimpl; import com.codahale.metrics.Timer; import groovy.lang.Binding; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.adapters.api.evalctx.*; import io.nosqlbench.adapters.api.metrics.ThreadLocalNamedTimers; @@ -42,10 +43,10 @@ import java.util.concurrent.TimeUnit; * Some details are tracked per op template, which aligns to the life-cycle of the op dispenser. * Thus, each op dispenser is where the stats for all related operations are kept. * - * @param + * @param * The type of operation */ -public abstract class BaseOpDispenser extends NBBaseComponent implements OpDispenser{ +public abstract class BaseOpDispenser extends NBBaseComponent implements OpDispenser{ protected final static Logger logger = LogManager.getLogger(BaseOpDispenser.class); public static final String VERIFIER = "verifier"; public static final String VERIFIER_INIT = "verifier-init"; @@ -55,7 +56,7 @@ public abstract class BaseOpDispenser extends NBBaseComponent i public static final String STOP_TIMERS = "stop-timers"; private final String opName; - protected final DriverAdapter adapter; + protected final DriverAdapter adapter; private final NBLabels labels; public final Timer verifierTimer; private boolean instrument; @@ -77,7 +78,7 @@ public abstract class BaseOpDispenser extends NBBaseComponent i private final CycleFunction _verifier; private final ThreadLocal> tlVerifier; - protected BaseOpDispenser(final DriverAdapter adapter, final ParsedOp op) { + protected BaseOpDispenser(final DriverAdapter adapter, final ParsedOp op) { super(adapter); opName = op.getName(); this.adapter = adapter; @@ -177,7 +178,7 @@ public abstract class BaseOpDispenser extends NBBaseComponent i return this.opName; } - public DriverAdapter getAdapter() { + public DriverAdapter getAdapter() { return this.adapter; } @@ -227,8 +228,8 @@ public abstract class BaseOpDispenser extends NBBaseComponent i } @Override - public final T apply(long value) { - T op = getOp(value); + public final OP apply(long value) { + OP op = getOp(value); return op; } } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpDispenser.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpDispenser.java index 57ff77e0e..9a5a823fd 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpDispenser.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpDispenser.java @@ -16,6 +16,7 @@ package io.nosqlbench.adapters.api.activityimpl; +import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.adapters.api.evalctx.CycleFunction; import java.util.function.LongFunction; @@ -64,11 +65,11 @@ import java.util.function.LongFunction; * are easy to understand at the mapping level ({@link OpMapper}), * and streamlined for fast execution at the synthesis level ({@link OpDispenser}). * - * @param The parameter type of the actual operation which will be used + * @param The parameter type of the actual operation which will be used * to hold all the details for executing an operation, - * something that implements {@link Runnable}. + * something that implements {@link Op}. */ -public interface OpDispenser extends LongFunction, OpResultTracker { +public interface OpDispenser extends LongFunction, OpResultTracker { /** * The apply method in an op dispenser should do all the work of @@ -82,7 +83,7 @@ public interface OpDispenser extends LongFunction, OpResultTracker { * @return an executable operation */ - T getOp(long value); + OP getOp(long value); CycleFunction getVerifier(); diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpMapper.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpMapper.java index 066c5fa8f..8bd2acc74 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpMapper.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/OpMapper.java @@ -17,17 +17,21 @@ package io.nosqlbench.adapters.api.activityimpl; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.adapters.api.templating.ParsedOp; +import java.util.function.BiFunction; import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.LongFunction; /** *

*

Synopsis

* An OpMapper is responsible for converting parsed op templates * into dispensers of operations based on the intention of the user. - * + *

* Op Templates as expressed as a set of field values, some literal, and * some dynamic, to be generated based on a specific cycle value. *

@@ -79,16 +83,19 @@ import java.util.function.Function; * to hold all the details for executing an operation, * generally something that implements {@link Runnable}. */ -public interface OpMapper extends Function> { +public interface OpMapper + extends BiFunction, OpDispenser> { /** * Interrogate the parsed command, and provide a new * - * @param op The {@link ParsedOp} which is the parsed version of the user-provided op template. - * This contains all the fields provided by the user, as well as explicit knowledge of - * which ones are static and dynamic. + * @param op + * The {@link ParsedOp} which is the parsed version of the user-provided op template. + * This contains all the fields provided by the user, as well as explicit knowledge of + * which ones are static and dynamic. + * @param spaceInitF * @return An OpDispenser which can be used to synthesize real operations. */ - @Override - OpDispenser apply(ParsedOp op); + OpDispenser apply(ParsedOp op, LongFunction spaceInitF); + } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/docs/BundledDriverAdapterDocs.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/docs/BundledDriverAdapterDocs.java index 457e950cd..c247f9fbf 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/docs/BundledDriverAdapterDocs.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/docs/BundledDriverAdapterDocs.java @@ -18,6 +18,7 @@ package io.nosqlbench.adapters.api.activityimpl.docs; import io.nosqlbench.adapter.diag.DriverAdapterLoader; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.nb.api.docsapi.BundledMarkdownManifest; import io.nosqlbench.nb.api.docsapi.Docs; @@ -40,7 +41,10 @@ public class BundledDriverAdapterDocs implements BundledMarkdownManifest { List> namedProviders = loader.getNamedProviders(); for (SimpleServiceLoader.Component namedProvider : namedProviders) { DriverAdapterLoader driverAdapterLoader = namedProvider.provider.get(); - DriverAdapter driverAdapter = driverAdapterLoader.load(NBComponent.EMPTY_COMPONENT, NBLabels.forKV()); + DriverAdapter driverAdapter = driverAdapterLoader.load( + NBComponent.EMPTY_COMPONENT, + NBLabels.forKV() + ); DocsBinder bundledDocs = driverAdapter.getBundledDocs(); docs = docs.merge(bundledDocs); } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseDriverAdapter.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseDriverAdapter.java index 7976e6ff5..20654c2b1 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseDriverAdapter.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseDriverAdapter.java @@ -32,12 +32,13 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.function.LongFunction; +import java.util.function.LongToIntFunction; import java.util.stream.Collectors; -public abstract class BaseDriverAdapter extends NBBaseComponent implements DriverAdapter, NBConfigurable, NBReconfigurable { +public abstract class BaseDriverAdapter extends NBBaseComponent implements DriverAdapter, NBConfigurable, NBReconfigurable { private final static Logger logger = LogManager.getLogger("ADAPTER"); - private StringDriverSpaceCache spaceCache; + private ConcurrentSpaceCache spaceCache; private NBConfiguration cfg; private LongFunction spaceF; @@ -62,7 +63,7 @@ public abstract class BaseDriverAdapter extends NBBaseComponent mappers.addAll(stmtRemappers); mappers.addAll(getOpFieldRemappers()); - if (mappers.size() == 0) { + if (mappers.isEmpty()) { return (i) -> i; } @@ -121,7 +122,7 @@ public abstract class BaseDriverAdapter extends NBBaseComponent *

Provide a list of field remappers which operate on arbitrary fields. * Each function is applied to the op template fields.

* - * @return + * @return op field remappers, an empty list by default */ @Override public List, Map>> getOpFieldRemappers() { @@ -129,9 +130,9 @@ public abstract class BaseDriverAdapter extends NBBaseComponent } @Override - public final synchronized StringDriverSpaceCache getSpaceCache() { + public final synchronized ConcurrentSpaceCache getSpaceCache() { if (spaceCache == null) { - spaceCache = new StringDriverSpaceCache<>(this, getSpaceInitializer(getConfiguration())); + spaceCache = new ConcurrentSpaceCache(getSpaceInitializer(getConfiguration())); } return spaceCache; } @@ -192,8 +193,8 @@ public abstract class BaseDriverAdapter extends NBBaseComponent @Override public LongFunction getSpaceFunc(ParsedOp pop) { - LongFunction spaceNameF = pop.getAsFunctionOr("space", "default"); - StringDriverSpaceCache cache = getSpaceCache(); - return l -> getSpaceCache().get(spaceNameF.apply(l)); + LongToIntFunction spaceIdxF = pop.getAsFunctionOrInt("space", 0); + ConcurrentSpaceCache cache = getSpaceCache(); + return l -> getSpaceCache().get(spaceIdxF.applyAsInt(l)); } } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseSpace.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseSpace.java new file mode 100644 index 000000000..3b6aa280c --- /dev/null +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/BaseSpace.java @@ -0,0 +1,36 @@ +package io.nosqlbench.adapters.api.activityimpl.uniform; + +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed 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. + */ + + +import java.util.function.IntFunction; +import java.util.function.LongFunction; + +public class BaseSpace implements Space { + + private final String spaceName; + + public BaseSpace(long idx) { + this.spaceName = String.valueOf(idx); + } + + @Override + public String getName() { + return spaceName; + } +} diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/DriverAdapter.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/DriverAdapter.java index a05adeb14..d55603f57 100644 --- a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/DriverAdapter.java +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/DriverAdapter.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; +import java.util.function.IntFunction; import java.util.function.LongFunction; /** @@ -55,7 +56,7 @@ import java.util.function.LongFunction; * during construction of R type operations, or even for individual * operations. */ -public interface DriverAdapter extends NBComponent { +public interface DriverAdapter extends NBComponent { /** *

@@ -101,7 +102,7 @@ public interface DriverAdapter extends NBComponent * * @return a synthesizer function for {@link OPTYPE} op generation */ - OpMapper getOpMapper(); + OpMapper getOpMapper(); /** * The preprocessor function allows the driver adapter to remap @@ -159,7 +160,7 @@ public interface DriverAdapter extends NBComponent * @return A function which can initialize a new Space, which is a place to hold * object state related to retained objects for the lifetime of a native driver. */ - default Function getSpaceInitializer(NBConfiguration cfg) { + default LongFunction getSpaceInitializer(NBConfiguration cfg) { return n -> null; } diff --git a/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/Space.java b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/Space.java new file mode 100644 index 000000000..6ee1961cb --- /dev/null +++ b/nb-apis/adapters-api/src/main/java/io/nosqlbench/adapters/api/activityimpl/uniform/Space.java @@ -0,0 +1,37 @@ +package io.nosqlbench.adapters.api.activityimpl.uniform; + +/* + * Copyright (c) 2022 nosqlbench + * + * Licensed 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. + */ + + +import io.nosqlbench.nb.api.components.core.NBNamedElement; + +/** + *

A space is simply a separate namespace associated with an instance of a + * native client or driver. This allows for the emulation of many clients + * in testing scenarios. Within the operations for an adapter, the space + * may be needed, for example, to construct prepared statements, or other + * 'session-attached' objects. Put any state that you would normally + * associate with an instance of a native driver into a space, and use + * the {@link DriverAdapter#getSpaceCache()} to access it when needed.

+ */ +public interface Space extends NBNamedElement, AutoCloseable { + + @Override + default void close() throws Exception { + } +} diff --git a/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java b/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java index 4765f161f..c841f47cb 100644 --- a/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java +++ b/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/SimpleActivity.java @@ -23,6 +23,7 @@ import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityimpl.OpDispenser; import io.nosqlbench.adapters.api.activityimpl.OpMapper; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.decorators.SyntheticOpTemplateProvider; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.CycleOp; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; @@ -58,6 +59,7 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Function; +import java.util.function.LongFunction; /** * A default implementation of an Activity, suitable for building upon. @@ -395,7 +397,7 @@ public class SimpleActivity extends NBStatusComponent implements Activity, Invok protected OpSequence> createOpSourceFromParsedOps( // Map> adapterCache, // Map> mapperCache, - List> adapters, + List> adapters, List pops ) { try { @@ -424,10 +426,10 @@ public class SimpleActivity extends NBStatusComponent implements Activity, Invok continue; } - DriverAdapter adapter = adapters.get(i); - OpMapper opMapper = adapter.getOpMapper(); - OpDispenser dispenser = opMapper.apply(pop); - + DriverAdapter adapter = adapters.get(i); + OpMapper opMapper = adapter.getOpMapper(); + LongFunction spaceFunc = adapter.getSpaceFunc(pop); + OpDispenser dispenser = opMapper.apply(pop, spaceFunc); String dryrunSpec = pop.takeStaticConfigOr("dryrun", "none"); if ("op".equalsIgnoreCase(dryrunSpec)) { dispenser = new DryRunOpDispenserWrapper((DriverAdapter) adapter, pop, dispenser); diff --git a/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java b/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java index d3154d15d..b2a297021 100644 --- a/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java +++ b/nb-engine/nb-engine-core/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java @@ -23,6 +23,7 @@ import io.nosqlbench.adapters.api.activityconfig.yaml.OpsDocList; import io.nosqlbench.adapters.api.activityimpl.OpDispenser; import io.nosqlbench.adapters.api.activityimpl.OpMapper; import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; +import io.nosqlbench.adapters.api.activityimpl.uniform.Space; import io.nosqlbench.adapters.api.activityimpl.uniform.decorators.SyntheticOpTemplateProvider; import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.adapters.api.templating.ParsedOp; @@ -62,7 +63,7 @@ import java.util.concurrent.ConcurrentHashMap; public class StandardActivity extends SimpleActivity implements SyntheticOpTemplateProvider, ActivityDefObserver { private static final Logger logger = LogManager.getLogger("ACTIVITY"); private final OpSequence> sequence; - private final ConcurrentHashMap> adapters = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> adapters = new ConcurrentHashMap<>(); public StandardActivity(NBComponent parent, ActivityDef activityDef) { super(parent, activityDef); @@ -92,11 +93,11 @@ public class StandardActivity extends SimpleActivity implements List pops = new ArrayList<>(); - List> adapterlist = new ArrayList<>(); + List> adapterlist = new ArrayList<>(); NBConfigModel supersetConfig = ConfigModel.of(StandardActivity.class).add(yamlmodel); Optional defaultDriverOption = defaultDriverName; - ConcurrentHashMap> mappers = new ConcurrentHashMap<>(); + ConcurrentHashMap> mappers = new ConcurrentHashMap<>(); for (OpTemplate ot : opTemplates) { // ParsedOp incompleteOpDef = new ParsedOp(ot, NBConfiguration.empty(), List.of(), this); String driverName = ot.getOptionalStringParam("driver", String.class) @@ -112,7 +113,7 @@ public class StandardActivity extends SimpleActivity implements // HERE if (!adapters.containsKey(driverName)) { - DriverAdapter adapter = Optional.of(driverName) + DriverAdapter adapter = Optional.of(driverName) .flatMap( name -> ServiceSelector.of( name, @@ -144,7 +145,7 @@ public class StandardActivity extends SimpleActivity implements supersetConfig.assertValidConfig(activityDef.getParams().getStringStringMap()); - DriverAdapter adapter = adapters.get(driverName); + DriverAdapter adapter = adapters.get(driverName); adapterlist.add(adapter); ParsedOp pop = new ParsedOp(ot, adapter.getConfiguration(), List.of(adapter.getPreprocessor()), this); Optional discard = pop.takeOptionalStaticValue("driver", String.class); @@ -261,19 +262,20 @@ public class StandardActivity extends SimpleActivity implements */ @Override public void shutdownActivity() { - for (Map.Entry> entry : adapters.entrySet()) { + for (Map.Entry> entry : adapters.entrySet()) { String adapterName = entry.getKey(); DriverAdapter adapter = entry.getValue(); - adapter.getSpaceCache().getElements().forEach((spaceName, space) -> { - if (space instanceof AutoCloseable autocloseable) { + for (Space space : adapter.getSpaceCache()) { + if (space instanceof AutoCloseable autoCloseable) { try { - autocloseable.close(); + // TODO This should be invariant now, remove conditional? + autoCloseable.close(); } catch (Exception e) { throw new RuntimeException("Error while shutting down state space for " + - "adapter=" + adapterName + ", space=" + spaceName + ": " + e, e); + "adapter=" + adapterName + ", space=" + space.getName() + ": " + e, e); } } - }); + } } }