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

Решетников Алексей, Магистратура ИТМО "Распределенные веб-сервисы", sampled index #305

Closed
wants to merge 3 commits into from
Closed
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
53 changes: 51 additions & 2 deletions src/main/java/ru/vk/itmo/reference/SSTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import static ru.vk.itmo.reference.SampledIndex.SAMPLED_INDEX_STEP;

/**
* Persistent SSTable in data file and index file.
*
Expand All @@ -19,6 +23,7 @@ final class SSTable {
final int sequence;

private final MemorySegment index;
private final List<SampledIndex> sampledIndices;
private final MemorySegment data;
private final long size;

Expand All @@ -30,6 +35,23 @@ final class SSTable {
this.index = index;
this.data = data;
this.size = index.byteSize() / Long.BYTES;

this.sampledIndices = new ArrayList<>();
for (int indexOffset = 0; indexOffset < size; indexOffset += SAMPLED_INDEX_STEP) {
// | [kv][kv][kv][kv][kv][kv][kv] | [kv][kv][kv][kv]...[kv]
// ^
// |
// keyAtTheStart
final long keyAtTheStartOffset = entryOffset(indexOffset);
final long keyAtTheStartLength = getLength(keyAtTheStartOffset);

sampledIndices.add(
new SampledIndex(
keyAtTheStartOffset + Long.BYTES, keyAtTheStartLength,
indexOffset
)
);
}
}

SSTable withSequence(final int sequence) {
Expand All @@ -39,6 +61,33 @@ SSTable withSequence(final int sequence) {
data);
}

private long sampledIndexBinarySearch(final MemorySegment key) {
int low = 0;
int high = sampledIndices.size() - 1;

while (low <= high) {
final int mid = (low + high) >>> 1;
final SampledIndex sampledIndex = sampledIndices.get(mid);

final long keyAtTheStartOffset = sampledIndex.keyAtTheStartOffset();
final long keyAtTheStartLength = sampledIndex.keyAtTheStartLength();
final int compare = MemorySegmentComparator.compare(
data, keyAtTheStartOffset, keyAtTheStartLength,
key, 0L, key.byteSize()
);

if (compare < 0) {
low = mid + 1;
} else if (compare > 0) {
high = mid - 1;
} else {
return sampledIndex.offset();
}
}

return sampledIndices.get(high).offset();
}

/**
* Returns index of the entry if found; otherwise, (-(insertion point) - 1).
* The insertion point is defined as the point at which the key would be inserted:
Expand All @@ -48,8 +97,8 @@ SSTable withSequence(final int sequence) {
* if and only if the key is found.
*/
private long entryBinarySearch(final MemorySegment key) {
long low = 0L;
long high = size - 1;
long low = sampledIndexBinarySearch(key);
long high = low + SAMPLED_INDEX_STEP;

while (low <= high) {
final long mid = (low + high) >>> 1;
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/ru/vk/itmo/reference/SampledIndex.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.vk.itmo.reference;

public record SampledIndex(
long keyAtTheStartOffset,
long keyAtTheStartLength,
long offset
) {
static final int SAMPLED_INDEX_STEP = 16;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @author incubos
*/
@DaoFactory(stage = 5)
@DaoFactory(stage = 500)
public class ReferenceDaoFactory implements DaoFactory.Factory<MemorySegment, Entry<MemorySegment>> {
@Override
public Dao<MemorySegment, Entry<MemorySegment>> createDao(final Config config) throws IOException {
Expand Down
Loading