diff --git a/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java b/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java index 923b647..8c7505e 100644 --- a/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java +++ b/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java @@ -34,14 +34,17 @@ public class LocalBucketing { Linker linker; // used to read/write to WASM AtomicReference memRef; // reference to start of WASM's memory private final Set pinnedAddresses; + private final Set pinnedEventIds; private final HashMap sdkKeyAddresses; - private final HashMap variableTypeMap = new HashMap(); + private final HashMap variableTypeMap = new HashMap<>(); private final Logger logger = Logger.getLogger(LocalBucketing.class.getName()); + private final Map configMetadataCache = new HashMap<>(); public LocalBucketing() { OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); pinnedAddresses = new HashSet<>(); + pinnedEventIds = new HashSet<>(); sdkKeyAddresses = new HashMap<>(); store = Store.withoutData(); @@ -195,17 +198,18 @@ private byte[] readAssemblyScriptUint8Array(int address) { } public synchronized void storeConfig(String sdkKey, String config) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); int configAddress = newUint8ArrayParameter(config.getBytes(StandardCharsets.UTF_8)); Func setConfigDataPtr = linker.get(store, "", "setConfigDataUTF8").get().func(); WasmFunctions.Consumer2 fn = WasmFunctions.consumer(store, setConfigDataPtr, I32, I32); fn.accept(sdkKeyAddress, configAddress); + configMetadataCache.put(sdkKey, internalGetConfigMetadata(sdkKeyAddress)); } public synchronized void setPlatformData(String platformData) { - unpinAll(); + unPinAllEventIds(); int platformDataAddress = newUint8ArrayParameter(platformData.getBytes(StandardCharsets.UTF_8)); Func setPlatformDataPtr = linker.get(store, "", "setPlatformDataUTF8").get().func(); WasmFunctions.Consumer1 fn = WasmFunctions.consumer(store, setPlatformDataPtr, I32); @@ -213,7 +217,7 @@ public synchronized void setPlatformData(String platformData) { } public synchronized void setClientCustomData(String sdkKey, String customData) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); int customDataAddress = newUint8ArrayParameter(customData.getBytes(StandardCharsets.UTF_8)); Func setCustomClientDataPtr = linker.get(store, "", "setClientCustomDataUTF8").get().func(); @@ -222,7 +226,7 @@ public synchronized void setClientCustomData(String sdkKey, String customData) { } public synchronized BucketedUserConfig generateBucketedConfig(String sdkKey, DevCycleUser user) throws JsonProcessingException { - unpinAll(); + unPinAllEventIds(); String userString = OBJECT_MAPPER.writeValueAsString(user); int sdkKeyAddress = getSDKKeyAddress(sdkKey); @@ -261,7 +265,7 @@ public synchronized byte[] getVariableForUserProtobuf(byte[] serializedParams) { } public synchronized void initEventQueue(String sdkKey, String clientUUID, String options) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); int clientUUIDAddress = newWasmString(clientUUID); int optionsAddress = newWasmString(options); @@ -272,9 +276,9 @@ public synchronized void initEventQueue(String sdkKey, String clientUUID, String } public synchronized void queueEvent(String sdkKey, String user, String event) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = newWasmString(sdkKey); - int userAddress = getPinnedParameter(user); + int userAddress = getPinnedEventId(user); int eventAddress = newWasmString(event); Func queueEventPtr = linker.get(store, "", "queueEvent").get().func(); @@ -283,9 +287,9 @@ public synchronized void queueEvent(String sdkKey, String user, String event) { } public synchronized void queueAggregateEvent(String sdkKey, String event, String variableVariationMap) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); - int eventAddress = getPinnedParameter(event); + int eventAddress = getPinnedEventId(event); int variableVariationMapAddress = newWasmString(variableVariationMap); Func queueAggregateEventPtr = linker.get(store, "", "queueAggregateEvent").get().func(); @@ -294,7 +298,7 @@ public synchronized void queueAggregateEvent(String sdkKey, String event, String } public synchronized FlushPayload[] flushEventQueue(String sdkKey) throws JsonProcessingException { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); Func flushEventQueuePtr = linker.get(store, "", "flushEventQueue").get().func(); @@ -317,7 +321,7 @@ public synchronized FlushPayload[] flushEventQueue(String sdkKey) throws JsonPro } public synchronized void onPayloadFailure(String sdkKey, String payloadId, boolean retryable) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); int payloadIdAddress = newWasmString(payloadId); @@ -327,7 +331,7 @@ public synchronized void onPayloadFailure(String sdkKey, String payloadId, boole } public synchronized void onPayloadSuccess(String sdkKey, String payloadId) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); int payloadIdAddress = newWasmString(payloadId); @@ -337,7 +341,7 @@ public synchronized void onPayloadSuccess(String sdkKey, String payloadId) { } public synchronized int getEventQueueSize(String sdkKey) { - unpinAll(); + unPinAllEventIds(); int sdkKeyAddress = getSDKKeyAddress(sdkKey); Func getEventQueueSizePtr = linker.get(store, "", "eventQueueSize").get().func(); @@ -359,11 +363,22 @@ private void unpinParameter(int address) { unpin.accept(address); } - private void unpinAll() { + private void unPinAllEventIds() { + for (int address : pinnedEventIds) { + unpinParameter(address); + } + pinnedEventIds.clear(); + } + + private void unPinAllParameters() { for (int address : pinnedAddresses) { unpinParameter(address); } + for (int address : pinnedEventIds) { + unpinParameter(address); + } pinnedAddresses.clear(); + pinnedEventIds.clear(); } private int getPinnedParameter(String param) { @@ -373,6 +388,13 @@ private int getPinnedParameter(String param) { return address; } + private int getPinnedEventId(String param) { + int address = newWasmString(param); + pinParameter(address); + pinnedEventIds.add(address); + return address; + } + private int getSDKKeyAddress(String sdkKey) { if (!sdkKeyAddresses.containsKey(sdkKey)) { int sdkKeyAddress = newWasmString(sdkKey); @@ -384,7 +406,17 @@ private int getSDKKeyAddress(String sdkKey) { } public String getConfigMetadata(String sdkKey) { - int sdkKeyAddress = getSDKKeyAddress(sdkKey); + if (configMetadataCache.containsKey(sdkKey)) { + return configMetadataCache.get(sdkKey); + } else { + int sdkKeyAddress = getSDKKeyAddress(sdkKey); + String metadata = internalGetConfigMetadata(sdkKeyAddress); + configMetadataCache.put(sdkKey, metadata); + return metadata; + } + } + + private String internalGetConfigMetadata(int sdkKeyAddress) { Func getConfigMetadataPtr = linker.get(store, "", "getConfigMetadata").get().func(); WasmFunctions.Function1 getConfigMetadata = WasmFunctions.func( store, getConfigMetadataPtr, I32, I32);