Skip to content

Commit

Permalink
updated main
Browse files Browse the repository at this point in the history
  • Loading branch information
tomfran committed Oct 21, 2023
1 parent f161355 commit 88e8a64
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 60 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ An implementation of the Log-Structured Merge Tree (LSM tree) data structure in
4. [Benchmarks](#Benchmarks)
5. [Implementation status](#Implementation-status)

To interact with a toy tree you can use `./gradlew run`
To interact with a toy tree you can use `./gradlew run -q` to spawn a console.

![console.png](misc%2Fconsole.png)

---

Expand Down Expand Up @@ -122,7 +124,7 @@ the operation on the node. All of them have an average time complexity of `O(log

---

## Benchmarks
# Benchmarks

I am using [JMH](https://openjdk.java.net/projects/code-tools/jmh/) to run benchmarks,
the results are obtained on AMD Ryzen™ 5 4600H with 16GB of RAM and 512GB SSD.
Expand All @@ -131,7 +133,7 @@ the results are obtained on AMD Ryzen™ 5 4600H with 16GB of RAM and 512GB SSD.
To run them use `./gradlew jmh`.

### SSTable
## SSTable

- Negative access: the key is not present in the table, hence the Bloom filter will likely stop the search;
- Random access: the key is present in the table, the order of the keys is random.
Expand All @@ -144,7 +146,7 @@ c.t.l.sstable.SSTableBenchmark.randomAccess thrpt 5 7989.945 ± 40
```

### Bloom filter
## Bloom filter

- Add: add keys to a 1M keys Bloom filter with 0.01 false positive rate;
- Contains: test whether the keys are present in the Bloom filter.
Expand All @@ -156,7 +158,7 @@ c.t.l.bloom.BloomFilterBenchmark.contains thrpt 5 3567392.634 ± 220377
```

### Skip-List
## Skip-List

- Get: get keys from a 100k keys skip-list;
- Add/Remove: add and remove keys from a 100k keys skip-list.
Expand All @@ -169,7 +171,7 @@ c.t.l.memtable.SkipListBenchmark.get thrpt 5 487265.620 ± 8201
```

### Tree
## Tree

- Get: get elements from a tree with 1M keys;
- Add: add 1M distinct elements to a tree with a memtable size of 2^18
Expand Down
Binary file added misc/console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 1 addition & 3 deletions src/jmh/java/com/tomfran/lsm/sstable/SSTableBenchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,11 @@ public void setup() throws IOException {

Files.createDirectory(dir);

// generate random items
var l = new ObjectOpenHashSet<ByteArrayPair>();
for (int i = 0; i < NUM_ITEMS * 2; i++) {
l.add(getRandomPair());
}

// sort and divide into inserted and skipped
var items = l.stream()
.sorted((a, b) -> ByteArrayComparator.compare(a.key(), b.key()))
.toList();
Expand All @@ -95,7 +93,7 @@ public void setup() throws IOException {
}

@TearDown
public void teardown() throws IOException {
public void teardown() {
sstable.close();
deleteDir(dir);
}
Expand Down
15 changes: 5 additions & 10 deletions src/jmh/java/com/tomfran/lsm/utils/BenchmarkUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.tomfran.lsm.tree.LSMTree;
import com.tomfran.lsm.types.ByteArrayPair;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -38,17 +39,11 @@ public static void shuffleItems(ByteArrayPair[] v) {
}
}

public static void deleteDir(Path dir) throws IOException {
try (var files = Files.list(dir)) {
files.forEach(f -> {
try {
Files.delete(f);
} catch (IOException e) {
e.printStackTrace();
}
});
public static void deleteDir(Path dir) {
try (var f = Files.walk(dir)) {
f.map(Path::toFile).forEach(File::delete);
} catch (Exception ignored) {
}
Files.delete(dir);
}

}
82 changes: 41 additions & 41 deletions src/main/java/com/tomfran/lsm/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,82 @@
import com.tomfran.lsm.types.ByteArrayPair;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;
import java.util.stream.Stream;

public class Main {

static final String DIRECTORY = "LSM-data";

public static void main(String[] args) throws IOException {
public static void main(String[] args) {

if (new File(DIRECTORY).exists())
deleteDir();

LSMTree tree = new LSMTree(3, 2, DIRECTORY);
LSMTree tree = new LSMTree(5, 2, DIRECTORY);

Scanner scanner = new Scanner(System.in);
scanner.useDelimiter("\n");

System.out.println(
"""
LSM Tree console
Commands:
- ins <key> <value> : insert a key-value pair
- get <key> : get a value for a key
- del <key> : delete a key-value pair
- exit : exit the application
"""
);
String intro = """
| __| \\ | __ __| \s
| \\__ \\ |\\/ | ____| | _| -_) -_)\s
____| ____/ _| _| _| _| \\___| \\___|\s
""";

String help = """
Commands:
- s/set <key> <value> : insert a key-value pair;
- g/get <key> : get a value for a key;
- d/del <key> : delete a key-value pair;
- e/exit : exit the application;
- d/help : show this list.
""";

System.out.println(intro);
System.out.println(help);

boolean exit = false;

while (!exit) {
System.out.print("Enter a command: ");
System.out.print("> ");
String command = scanner.nextLine();

var parts = command.split(" ");
String[] parts = command.split(" ");

String msg;
switch (parts[0]) {
case "exit" -> {
System.out.println("Exiting...");
exit = true;
case "s", "set" -> {
tree.add(new ByteArrayPair(parts[1].getBytes(), parts[2].getBytes()));
System.out.println("ok");
}
case "ins" -> tree.add(new ByteArrayPair(parts[1].getBytes(), parts[2].getBytes()));
case "del" -> tree.delete(parts[1].getBytes());
case "get" -> {
String key = parts[1];
byte[] value = tree.get(key.getBytes());

var msg = (value == null || value.length == 0) ? "No value found for key " + key :
"Value for key " + key + " is " + new String(value);
System.out.println(msg);
case "d", "del" -> {
tree.delete(parts[1].getBytes());
System.out.println("ok");
}
default -> System.out.println("Unknown command: " + command);
case "g", "get" -> {
byte[] value = tree.get(parts[1].getBytes());
System.out.println((value == null || value.length == 0) ? "not found" : new String(value));
}
case "h", "help" -> System.out.println(help);
case "e", "exit" -> exit = true;
default -> System.out.println("Unknown command");
}
System.out.println();
}
tree.stop();
scanner.close();

deleteDir();
}

static private void deleteDir() throws IOException {
try (var files = Files.list(Path.of(DIRECTORY))) {
files.forEach(f -> {
try {
Files.delete(f);
} catch (IOException e) {
e.printStackTrace();
}
});
static private void deleteDir() {
try (Stream<Path> f = Files.walk(Path.of(DIRECTORY))) {
f.map(Path::toFile).forEach(File::delete);
} catch (Exception ignored) {
}
Files.delete(Path.of(DIRECTORY));
}

}

0 comments on commit 88e8a64

Please sign in to comment.