Skip to content
This repository has been archived by the owner on Mar 3, 2024. It is now read-only.

Commit

Permalink
add filter
Browse files Browse the repository at this point in the history
  • Loading branch information
yulalenk committed Feb 1, 2024
1 parent b2e0aed commit 1329a26
Show file tree
Hide file tree
Showing 12 changed files with 1,048 additions and 230 deletions.

This file was deleted.

113 changes: 113 additions & 0 deletions src/main/java/ru/vk/itmo/alenkovayulya/AlenkovaDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ru.vk.itmo.alenkovayulya;

import ru.vk.itmo.Config;
import ru.vk.itmo.Dao;
import ru.vk.itmo.Entry;

import java.io.IOException;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;

public class AlenkovaDao implements Dao<MemorySegment, Entry<MemorySegment>> {

private final Comparator<MemorySegment> comparator = AlenkovaDao::compare;
private final NavigableMap<MemorySegment, Entry<MemorySegment>> storage = new ConcurrentSkipListMap<>(comparator);
private final Arena arena;
private final DiskStorage diskStorage;
private final Path path;

public AlenkovaDao(Config config) throws IOException {
this.path = config.basePath().resolve("data");
Files.createDirectories(path);

arena = Arena.ofShared();

this.diskStorage = new DiskStorage(DiskStorage.loadOrRecover(path, arena));
}

static int compare(MemorySegment memorySegment1, MemorySegment memorySegment2) {
long mismatch = memorySegment1.mismatch(memorySegment2);
if (mismatch == -1) {
return 0;
}

if (mismatch == memorySegment1.byteSize()) {
return -1;
}

if (mismatch == memorySegment2.byteSize()) {
return 1;
}
byte b1 = memorySegment1.get(ValueLayout.JAVA_BYTE, mismatch);
byte b2 = memorySegment2.get(ValueLayout.JAVA_BYTE, mismatch);
return Byte.compare(b1, b2);
}

@Override
public Iterator<Entry<MemorySegment>> get(MemorySegment from, MemorySegment to) {
return diskStorage.range(getInMemory(from, to), from, to);
}

private Iterator<Entry<MemorySegment>> getInMemory(MemorySegment from, MemorySegment to) {
if (from == null && to == null) {
return storage.values().iterator();
}
if (from == null) {
return storage.headMap(to).values().iterator();
}
if (to == null) {
return storage.tailMap(from).values().iterator();
}
return storage.subMap(from, to).values().iterator();
}

@Override
public void upsert(Entry<MemorySegment> entry) {
storage.put(entry.key(), entry);
}

@Override
public Entry<MemorySegment> get(MemorySegment key) {
Entry<MemorySegment> entry = storage.get(key);
if (entry != null) {
if (entry.value() == null) {
return null;
}
return entry;
}

Iterator<Entry<MemorySegment>> iterator = diskStorage.rangeWithBloorFilter(Collections.emptyIterator(), key, null);

if (!iterator.hasNext()) {
return null;
}
Entry<MemorySegment> next = iterator.next();
if (compare(next.key(), key) == 0) {
return next;
}
return null;
}

@Override
public void compact() throws IOException {
DiskStorage.compact(path, this::all);
}

@Override
public void close() throws IOException {
if (!arena.scope().isAlive()) {
return;
}

arena.close();

if (!storage.isEmpty()) {
DiskStorage.saveNextSSTable(path, storage.values());
}
}
}
Loading

0 comments on commit 1329a26

Please sign in to comment.