Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Moka v0.12.7 with different eviction policies: TinyLFU and LRU #1

Merged
merged 6 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2022 Tatsuya Kawano
Copyright 2022 - 2024 Tatsuya Kawano

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
59 changes: 43 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ The driver consists of two parts:
`native` (Rust) functions.
2. A Rust library that wraps Moka cache and implements the functions called by the
Java class.
- This library uses [jni crate][jni-crate], which provides a safe wrapper around
the JNI API.
- This library uses [`jni` crate][jni-crate], which provides a safe wrapper
around the JNI API.

The Rust library is compiled into a dynamic library that is loaded into the Java VM
at runtime.
Expand All @@ -33,7 +33,7 @@ at runtime.
## Prerequisites

- Java JDK to build the Caffeine Simulator and the Java part of the driver.
- Rust stable toolchain (1.51 or newer) to build Moka and the Rust part of the driver.
- Rust stable toolchain (1.75 or newer) to build Moka and the Rust part of the driver.

## Building the Driver

Expand All @@ -57,7 +57,7 @@ $ cargo build --release
Clone Caffeine's repository, and checkout a specific Git revision:

```console
$ REVISION=6800aa6573361e440c77d58b22e54c16d0ce2505
$ REVISION=4ba734a6cf2f7243c77d2ad8ea9d941f6e36175c

$ cd $SIM
$ git clone https://github.com/ben-manes/caffeine.git
Expand Down Expand Up @@ -98,38 +98,65 @@ Edit `application.conf` and add the following line in the `policies` section:

```properties
policies = [
# ...
product.Moka,
opt.Clairvoyant,
...
linked.Lru,
...
sketch.WindowTinyLfu,
...
product.Moka, # <--- Add this line.
]

admission = [
Always,
TinyLfu,
]
```

Build and run the Caffeine Simulator:

```console
## Replace `/path/to/trace/S3.lis` with the real path to the trace file:
$ TRACE=arc:/path/to/trace/S3.lis

## The path to the directory containing the dynamic library:
## The path to the directory containing the dynamic library.
$ DRV_LIB=$SIM/caffeine-sim-drivers/moka-driver-rs/target/release

## The path to the directory containing the ARC trace files.
## Replace `/path/to/...` with the real path.
$ ARC_DIR=/path/to/arc-trace-directory

## The path to the directory containing the Corda trace files.
$ CORDA_DIR=$SIM/caffeine/simulator/src/main/resources/com/github/benmanes/caffeine/cache/simulator/parser/corda/

$ cd $SIM/caffeine

## Run the simulator against the ARC S3 trace file.
$ ./gradlew simulator:simulate -q \
-Dcaffeine.simulator.files.paths.0=$TRACE \
--maximumSize=100_000,200_000,300_000,400_000,500_000,600_000,700_000,800_000 \
--jvmArgs="-XX:+UseParallelGC,-Xmx8g,-Djava.library.path=$DRV_LIB" \
--theme=light
-Dcaffeine.simulator.files.paths.0=arc:$ARC_DIR/S3.lis \
--maximumSize=100_000,200_000,300_000,400_000,500_000,600_000,700_000,800_000 \
-PjvmArgs="-XX:+UseParallelGC,-Xmx8g,-Djava.library.path=$DRV_LIB" \
--theme=light

$ mv $SIM/caffeine/simulator/build/reports/simulate{,-arc-s3}

## Run the simulator against the Corda vault service large trace file.
$ ./gradlew simulator:simulate -q \
-Dcaffeine.simulator.files.paths.0=corda:$CORDA_DIR/trace_vaultservice_large.gz \
--maximumSize=200_000,400_000,600_000,800_000,1_000_000,1_200_000,1_400_000,1_600_000 \
-PjvmArgs="-XX:+UseParallelGC,-Xmx8g,-Djava.library.path=$DRV_LIB" \
--theme=light

$ mv $SIM/caffeine/simulator/build/reports/simulate{,-corda-large}
```

## Modifying the Driver

If you want to modify the driver, e.g., to drive your own cache implementation, check
out the driver's codes and the "Getting Started" section of the jni crate's
out the driver's codes and the "Getting Started" section of the `jni` crate's
documentation:

- Driver's source code:
- Java part: [MokaPolicy.java](./moka-driver-java/MokaPolicy.java)
- Rust part: [src/lib.rs](./moka-driver-rs/src/lib.rs)
- jni crate: [Getting Started][jni-crate-getting-started]
- `jni` crate: [Getting Started][jni-crate-getting-started]

[jni-crate-getting-started]: https://docs.rs/jni/latest/jni/index.html#getting-started

Expand Down
64 changes: 48 additions & 16 deletions moka-driver-java/MokaPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static com.github.benmanes.caffeine.cache.simulator.policy.Policy.Characteristic.WEIGHTED;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import com.github.benmanes.caffeine.cache.simulator.BasicSettings;
Expand All @@ -13,38 +15,55 @@

@PolicySpec(name = "product.Moka", characteristics = WEIGHTED)
public final class MokaPolicy implements Policy {
private final long cachePointer;
private final PolicyStats policyStats;

static {
System.loadLibrary("moka");
}

public MokaPolicy(Config config, Set<Characteristic> characteristics) {
policyStats = new PolicyStats(name());
public MokaPolicy(Config config, String evictionPolicy) {
policyStats = new PolicyStats(name() + " (%s)", evictionPolicy);
BasicSettings settings = new BasicSettings(config);
long maximumSize = settings.maximumSize();
boolean isWeighted = characteristics.contains(WEIGHTED);
initCache(maximumSize, isWeighted);
boolean isWeighted = false;
cachePointer = initCache(maximumSize, isWeighted, evictionPolicy);
}

// public MokaPolicy(Config config, Set<Characteristic> characteristics) {
// policyStats = new PolicyStats(name());
// BasicSettings settings = new BasicSettings(config);
// long maximumSize = settings.maximumSize();
// boolean isWeighted = characteristics.contains(WEIGHTED);
// String evictionPolicy = "TinyLFU";
// cachePointer = initCache(maximumSize, isWeighted, evictionPolicy);
// }

public static Set<Policy> policies(Config config) {
HashSet<MokaPolicy> policies = new HashSet<>();
policies.add(new MokaPolicy(config, "TinyLFU"));
policies.add(new MokaPolicy(config, "LRU"));
return Collections.unmodifiableSet(policies);
}

@Override
public void record(AccessEvent event) {
int value = getFromCacheIfPresent(event.key());
int value = getFromCacheIfPresent(cachePointer, event.key());
if (value == -1) {
putToCache(event.key(), event.weight());
putToCache(cachePointer, event.key(), event.weight());
policyStats.recordWeightedMiss(event.weight());
} else {
policyStats.recordWeightedHit(event.weight());
if (event.weight() != value) {
putToCache(event.key(), event.weight());
putToCache(cachePointer, event.key(), event.weight());
}
}
}

// @Override
// public void finished() {
//
// }
@Override
public void finished() {
dropCache(cachePointer);
}

@Override
public PolicyStats stats() {
Expand All @@ -56,30 +75,43 @@ public PolicyStats stats() {
* --------------------------------------------------------------------------- */

/**
* Creates the shared singleton instance of the Moka cache with given
* parameters. Currently, moka::sync::Cache is used.
* Creates an instance of the Moka cache with given parameters and returns
* the pointer to the instance as a <code>long</code> value. Currently,
* <code>moka::sync::Cache</code> is used.
*
* @param maximumSize
* @param isWeighted
* @param evictionPolicy The eviction policy to use. <code>TinyLFU</code> or
* <code>LRU</code>.
* @return The pointer to the instance of the Moka cache.
*/
private static native void initCache(long maximumSize, boolean isWeighted);
private static native long initCache(long maximumSize, boolean isWeighted, String evictionPolicy);

/**
* Returns the value (which is the weight in int) of the given key if
* exists. Otherwise returns -1.
*
* @param cachePointer
* @param key
* @return The weight of the key if exists. Otherwise -1.
*/
private static native int getFromCacheIfPresent(long key);
private static native int getFromCacheIfPresent(long cachePointer, long key);

/**
* Stores the value (which is the weight in int) for the given key.
* Updates the value if already exists.
*
* @param cachePointer
* @param key
* @param weight
*/
private static native void putToCache(long key, int weight);
private static native void putToCache(long cachePointer, long key, int weight);

/**
* Drop the cache.
*
* @param cachePointer
*/
private static native void dropCache(long cachePointer);

}
13 changes: 6 additions & 7 deletions moka-driver-java/registry-patch.diff
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/Registry.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/Registry.java
index cf4f6b36..2882418e 100644
index 28207f6a..7a66cb81 100644
--- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/Registry.java
+++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/Registry.java
@@ -79,6 +79,8 @@ import com.google.auto.value.AutoValue;
@@ -78,6 +78,7 @@ import com.github.benmanes.caffeine.cache.simulator.policy.two_queue.TwoQueuePol
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.typesafe.config.Config;

+import io.crates.moka.cache.simulator.policy.product.MokaPolicy;
+
/**
* The registry of caching policies.
*
@@ -229,6 +231,7 @@ public final class Registry {
@@ -230,6 +231,7 @@ public final class Registry {
registerMany(CoherencePolicy.class, CoherencePolicy::policies);
registerMany(HazelcastPolicy.class, HazelcastPolicy::policies);
registerMany(ExpiringMapPolicy.class, ExpiringMapPolicy::policies);
+ register(MokaPolicy.class, MokaPolicy::new);
+ registerMany(MokaPolicy.class, MokaPolicy::policies);
}

@AutoValue
7 changes: 7 additions & 0 deletions moka-driver-rs/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"cSpell.words": [
"jlong",
"Moka",
"tinylfu"
]
}
Loading