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

Качмар Евгений, ИТМО ФИТиП М33331, Reverse Iterator #297

Open
wants to merge 74 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
b9fb7df
add all files to check code style
Sep 25, 2023
63cd280
optimize map values, if symplified
Sep 26, 2023
c25d10a
add 2 blank lines
Sep 26, 2023
e080066
remove redundant iterator anonumus class
Sep 26, 2023
d41b0e1
Merge branch 'main' into main
incubos Sep 27, 2023
05a9ba0
fixed comparator
Sep 27, 2023
1355424
Merge branch 'main' of github.com:Jenshen30/2023-nosql-lsm
Sep 27, 2023
3275eb6
Merge branch 'main' into main
Jenshen30 Sep 28, 2023
c857426
Merge branch 'polis-vk:main' into main
Jenshen30 Oct 1, 2023
7eca3c6
init commit
Oct 3, 2023
0592055
remove statement
Oct 3, 2023
89313f9
clean codestyle
Oct 3, 2023
cfe3308
some clean, renaming
Oct 3, 2023
8474dea
some clean
Oct 3, 2023
907b17a
replace all magical values to constants
Oct 3, 2023
c0b4abf
Merge branch 'main' into main
incubos Oct 5, 2023
5d44f3d
Merge branch 'main' into main
Jenshen30 Oct 9, 2023
52d32e5
prepare for binsearch
Oct 9, 2023
166cb3d
fixed chenges
Oct 9, 2023
a061de3
Merge branch 'main' of github.com:Jenshen30/2023-nosql-lsm
Oct 9, 2023
3f6eb17
changes
Oct 9, 2023
6468b3e
3rd task init
Oct 16, 2023
97a00f3
add 3rd task
Oct 18, 2023
aaac68d
add 3rd task
Oct 18, 2023
a4c2e7d
add 3rd task
Oct 18, 2023
e35cd92
add 3rd task
Oct 18, 2023
ae3723e
add 3rd task
Oct 18, 2023
fc982a5
add 3rd task
Oct 18, 2023
504b0b5
add 3rd task
Oct 18, 2023
1025d4b
clear for code format
Oct 18, 2023
2260e6d
Merge branch 'main' into 3rdtask
Jenshen30 Oct 18, 2023
49f5e61
changes
Oct 9, 2023
06e42f6
fixed
Oct 18, 2023
785bbb5
fixed
Oct 18, 2023
c6ddd98
da
Oct 18, 2023
e6e74d4
da
Oct 18, 2023
0ec702e
da
Oct 18, 2023
2655807
was late, because one little test:(
Oct 18, 2023
4c71c45
was late, because one little test:(
Oct 18, 2023
f1e92a4
refactored
Oct 18, 2023
f7c97bb
refactored
Oct 18, 2023
b818d10
refactored
Oct 18, 2023
da21ff1
refactored
Oct 18, 2023
bbe9fc8
Merge branch 'main' into 3rdtask
incubos Oct 19, 2023
444f3d5
Merge branch 'main' into 3rdtask
incubos Oct 20, 2023
6de4b16
Merge branch 'main' into 3rdtask
incubos Oct 20, 2023
abc1d9c
Merge branch 'main' into 3rdtask
incubos Oct 20, 2023
562c924
Merge branch 'polis-vk:main' into main
Jenshen30 Oct 30, 2023
04cf565
first commit for 4th
Nov 1, 2023
c122a68
Merge branch 'main' of github.com:Jenshen30/2023-nosql-lsm into 4task
Nov 1, 2023
6707aad
mmm, codeclimate
Nov 1, 2023
f499825
mmm, codeclimate
Nov 1, 2023
f48b5f2
mmm, codeclimate
Nov 1, 2023
cfd528b
mmm, codeclimate
Nov 1, 2023
510d890
mmm, codeclimate
Nov 1, 2023
e643993
fixed
Nov 1, 2023
0bc60e2
mmm, codeclimate
Nov 1, 2023
52cc057
mmm, codeclimate
Nov 1, 2023
95c04ce
mmm, codeclimate
Nov 1, 2023
dec80cb
mmm, codeclimate
Nov 1, 2023
b7cf38e
fixed timestamps
Nov 1, 2023
69287ff
fixed timestamps
Nov 1, 2023
d01433f
Merge branch 'main' into 4task
incubos Nov 2, 2023
a03ddbc
Merge branch 'main' into 4task
Jenshen30 Nov 16, 2023
6492359
upload changes
Nov 16, 2023
07da600
fixed
Nov 29, 2023
cbbc475
minor
Nov 29, 2023
115ba3c
code cimate
Nov 29, 2023
89cb2dc
code cimate
Nov 29, 2023
c554338
code cimate
Nov 29, 2023
a5eb570
code cimate
Nov 29, 2023
31c8509
add aditional task
Dec 4, 2023
ac2e977
codeclimate///
Dec 4, 2023
a4328e6
Merge branch 'main' into additionaltask
Jenshen30 Dec 4, 2023
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
9 changes: 9 additions & 0 deletions src/main/java/ru/vk/itmo/test/kachmareugene/InMemoryDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public InMemoryDao(Config conf) {

@Override
public Iterator<Entry<MemorySegment>> get(MemorySegment from, MemorySegment to) {
if (new MemSegComparatorNull().compare(from, to) > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Создание объекта на каждый вызов get. Зачем?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И вы все еще нарушаете инвариант Comparable:

The implementor must ensure that signum(compare(x, y)) == -signum(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

return reverseIter(from, to);
}

SortedMap<MemorySegment, Entry<MemorySegment>> dataSlice;

if (from == null && to == null) {
Expand All @@ -44,6 +48,11 @@ public Iterator<Entry<MemorySegment>> get(MemorySegment from, MemorySegment to)
return new SSTableIterator(dataSlice.values().iterator(), controller, from, to);
}

private Iterator<Entry<MemorySegment>> reverseIter(MemorySegment fromRightSide, MemorySegment toLeftSide) {
return new SSTableIterator(getMemTable().reversed().values().iterator(),
controller, fromRightSide, toLeftSide, true, new MemSegComparatorNull().reversed());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь вы создаете еще 2 компаратора, один из которых полностью идентичен созданному ранее. Итого создание 3 компараторов при каждом вызове get, когда можно их вообще не создавать

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всегда передается полная мапа, начало игнорируется, поэтому тестов, где from не последний элемент нет. Непонятно тогда, зачем обрезать конец мапы в случае натурального порядка, если он все равно учитывает конец внутри

}

@Override
public Entry<MemorySegment> get(MemorySegment key) {
if (key == null) {
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/ru/vk/itmo/test/kachmareugene/IteratorUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ru.vk.itmo.test.kachmareugene;

import ru.vk.itmo.Entry;

import java.lang.foreign.MemorySegment;
import java.util.SortedMap;

public class IteratorUtils {
private IteratorUtils() {
}

public static void insertNew(SortedMap<MemorySegment, SSTableRowInfo> mp,
SSTablesController controller, SSTableRowInfo info, MemorySegment to) {
Entry<MemorySegment> kv = controller.getRow(info);

if (kv == null) {
return;
}

if (!mp.containsKey(kv.key())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putIfAbsent

Не должно быть лишних обращений к структурам данных (особенно конкурентным)

mp.put(kv.key(), info);
return;
}
SSTableRowInfo old = mp.get(kv.key());

SSTableRowInfo oldInfo = old.ssTableInd > info.ssTableInd ? info : old;
SSTableRowInfo newInfo = old.ssTableInd < info.ssTableInd ? info : old;

mp.put(controller.getRow(newInfo).key(), newInfo);

// tail recursion
if (oldInfo.isReversedToIter) {
insertNew(mp, controller, controller.getPrevInfo(oldInfo, to), to);
} else {
insertNew(mp, controller, controller.getNextInfo(oldInfo, to), to);
}
Comment on lines +32 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше заменить на цикл. Рекурсия тут не оправдана

}
}
52 changes: 26 additions & 26 deletions src/main/java/ru/vk/itmo/test/kachmareugene/SSTableIterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,51 +14,46 @@ public class SSTableIterator implements Iterator<Entry<MemorySegment>> {

private final Iterator<Entry<MemorySegment>> memTableIterator;
private final SSTablesController controller;
private final Comparator<MemorySegment> comp = new MemSegComparatorNull();
private final SortedMap<MemorySegment, SSTableRowInfo> mp = new TreeMap<>(comp);
private final Comparator<MemorySegment> comp;
private final SortedMap<MemorySegment, SSTableRowInfo> mp;
private final MemorySegment from;
private final MemorySegment to;
private Entry<MemorySegment> head;
private Entry<MemorySegment> keeper;
private boolean isReversed;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final


public SSTableIterator(Iterator<Entry<MemorySegment>> it, SSTablesController controller,
MemorySegment from, MemorySegment to) {
memTableIterator = it;
this.memTableIterator = it;
this.controller = controller;
this.comp = new MemSegComparatorNull();
this.mp = new TreeMap<>(comp);

this.from = from;
this.to = to;

positioningIterator();
}

private void insertNew(SSTableRowInfo info) {
Entry<MemorySegment> kv = controller.getRow(info);

if (kv == null) {
return;
}

if (!mp.containsKey(kv.key())) {
mp.put(kv.key(), info);
return;
}
SSTableRowInfo old = mp.get(kv.key());

SSTableRowInfo oldInfo = old.ssTableInd > info.ssTableInd ? info : old;
SSTableRowInfo newInfo = old.ssTableInd < info.ssTableInd ? info : old;
public SSTableIterator(Iterator<Entry<MemorySegment>> it, SSTablesController controller,
MemorySegment from, MemorySegment to, boolean isReversed, Comparator<MemorySegment> comp) {
Comment on lines +38 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Конструктор - копия первого, в котором почему-то явно не инициализировано isReversed, из-за чего оно не final

this.memTableIterator = it;
this.controller = controller;
this.comp = comp;
this.mp = new TreeMap<>(comp);

mp.put(controller.getRow(newInfo).key(), newInfo);
this.from = from;
this.to = to;
this.isReversed = isReversed;

// tail recursion
insertNew(controller.getNextInfo(oldInfo, to));
positioningIterator();
}

private void positioningIterator() {
List<SSTableRowInfo> rawData = controller.firstGreaterKeys(from);
List<SSTableRowInfo> rawData = controller.firstKeys(from, isReversed);

for (var info : rawData) {
insertNew(info);
IteratorUtils.insertNew(mp, controller, info, to);
}
}

Expand Down Expand Up @@ -138,7 +133,13 @@ private void changeState() {
}

private void updateMp(MemorySegment key) {
insertNew(controller.getNextInfo(mp.remove(key), to));
if (isReversed) {
IteratorUtils.insertNew(mp, controller,
controller.getPrevInfo(mp.remove(key), to), to);
return;
}
IteratorUtils.insertNew(mp, controller,
controller.getNextInfo(mp.remove(key), to), to);
Comment on lines +136 to +142
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хочется какой-то консистентности. Или все такие места

if (isReversed) {
    ...
}  else {
    ...
}

Или

if (isReversed) {
    ...
    return
} 
...

}

private boolean isBetween(MemorySegment who) {
Expand All @@ -150,8 +151,7 @@ private boolean isBetween(MemorySegment who) {
private Map.Entry<MemorySegment, SSTableRowInfo> getFirstMin() {
Map.Entry<MemorySegment, SSTableRowInfo> minSStablesEntry = mp.firstEntry();
while (!mp.isEmpty() && !isBetween(minSStablesEntry.getKey())) {
mp.remove(minSStablesEntry.getKey());
insertNew(controller.getNextInfo(minSStablesEntry.getValue(), to));
updateMp(minSStablesEntry.getKey());
minSStablesEntry = mp.firstEntry();
}
return minSStablesEntry;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/ru/vk/itmo/test/kachmareugene/SSTableRowInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class SSTableRowInfo {
long rowShift;
private final long valueSize;
int ssTableInd;
boolean isReversedToIter;

public SSTableRowInfo(long keyOffset, long keySize, long valueOffset,
long valueSize, int ssTableInd, long rowShift) {
Expand All @@ -18,6 +19,17 @@ public SSTableRowInfo(long keyOffset, long keySize, long valueOffset,
this.rowShift = rowShift;
}

public SSTableRowInfo(long keyOffset, long keySize, long valueOffset,
long valueSize, int ssTableInd, long rowShift, boolean isReversedToIter) {
this.keyOffset = keyOffset;
this.valueOffset = valueOffset;
this.keySize = keySize;
this.valueSize = valueSize;
this.ssTableInd = ssTableInd;
this.rowShift = rowShift;
this.isReversedToIter = isReversedToIter;
}

public boolean isDeletedData() {
return valueSize < 0;
}
Expand Down
56 changes: 28 additions & 28 deletions src/main/java/ru/vk/itmo/test/kachmareugene/SSTablesController.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,47 +71,34 @@ private List<Path> openFiles(Path dir, String fileNamePref, List<MemorySegment>
}
}

private boolean greaterThen(long keyOffset, long keySize,
MemorySegment mapped, MemorySegment key) {

return segComp.compare(key, mapped.asSlice(keyOffset, keySize)) > 0;
}

//Gives offset for line in index file
private long searchKeyInFile(int ind, MemorySegment mapped, MemorySegment key) {
long l = -1;
long r = getNumberOfEntries(mapped);

while (r - l > 1) {
long mid = (l + r) / 2;
SSTableRowInfo info = createRowInfo(ind, mid);
if (greaterThen(info.keyOffset, info.keySize, mapped, key)) {
l = mid;
} else {
r = mid;
}
}
return r == getNumberOfEntries(mapped) ? -1 : r;
}

//return - List ordered form the latest created sstable to the first.
public List<SSTableRowInfo> firstGreaterKeys(MemorySegment key) {
public List<SSTableRowInfo> firstKeys(MemorySegment key, boolean isReversed) {
List<SSTableRowInfo> ans = new ArrayList<>();

for (int i = ssTables.size() - 1; i >= 0; i--) {
long entryIndexesLine = 0;
if (key != null) {
entryIndexesLine = searchKeyInFile(i, ssTables.get(i), key);
if (isReversed) {
entryIndexesLine = Utils.searchKeyInFileReversed(this, i,
getNumberOfEntries(ssTables.get(i)),
ssTables.get(i), key, segComp);
} else {
entryIndexesLine = Utils.searchKeyInFile(this, i,
getNumberOfEntries(ssTables.get(i)), ssTables.get(i), key, segComp);
}
}
if (entryIndexesLine < 0) {
continue;
}
ans.add(createRowInfo(i, entryIndexesLine));
SSTableRowInfo row = createRowInfo(i, entryIndexesLine);
row.isReversedToIter = isReversed;

ans.add(row);
}
return ans;
}

private SSTableRowInfo createRowInfo(int ind, final long rowIndex) {
public SSTableRowInfo createRowInfo(int ind, final long rowIndex) {
long start = ssTables.get(ind).get(ValueLayout.JAVA_LONG_UNALIGNED, rowIndex * ONE_LINE_SIZE + Long.BYTES);
long size = ssTables.get(ind).get(ValueLayout.JAVA_LONG_UNALIGNED, rowIndex * ONE_LINE_SIZE + Long.BYTES * 2);

Expand All @@ -122,7 +109,8 @@ private SSTableRowInfo createRowInfo(int ind, final long rowIndex) {

public SSTableRowInfo searchInSStables(MemorySegment key) {
for (int i = ssTables.size() - 1; i >= 0; i--) {
long ind = searchKeyInFile(i, ssTables.get(i), key);
long ind = Utils.searchKeyInFile(this, i,
getNumberOfEntries(ssTables.get(i)), ssTables.get(i), key, segComp);
if (ind >= 0) {
return createRowInfo(i, ind);
}
Expand Down Expand Up @@ -160,6 +148,18 @@ public SSTableRowInfo getNextInfo(SSTableRowInfo info, MemorySegment maxKey) {
return null;
}

public SSTableRowInfo getPrevInfo(SSTableRowInfo info, MemorySegment minKey) {
for (long t = info.rowShift - 1; t >= 0; t--) {
var inf = createRowInfo(info.ssTableInd, t);

Entry<MemorySegment> row = getRow(inf);
if (segComp.compare(row.key(), minKey) > 0) {
return inf;
}
}
return null;
}

private long getNumberOfEntries(MemorySegment memSeg) {
return memSeg.get(ValueLayout.JAVA_LONG_UNALIGNED, 0);
}
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/ru/vk/itmo/test/kachmareugene/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,56 @@ public static MemorySegment getValueOrNull(Entry<MemorySegment> kv) {
}
return value;
}

private static boolean greaterThen(Comparator<MemorySegment> segComp, long keyOffset, long keySize,
MemorySegment mapped, MemorySegment key) {

return segComp.compare(key, mapped.asSlice(keyOffset, keySize)) > 0;
}

private static boolean greaterEqThen(Comparator<MemorySegment> segComp, long keyOffset, long keySize,
MemorySegment mapped, MemorySegment key) {

return segComp.compare(key, mapped.asSlice(keyOffset, keySize)) >= 0;
}

//Gives offset for line in index file
public static long searchKeyInFile(SSTablesController controller,
int ind, long numberOfEntries,
MemorySegment mapped, MemorySegment key,
Comparator<MemorySegment> segComp) {
long l = -1;
long r = numberOfEntries;

while (r - l > 1) {
long mid = (l + r) / 2;
SSTableRowInfo info = controller.createRowInfo(ind, mid);
if (greaterThen(segComp, info.keyOffset, info.keySize, mapped, key)) {
l = mid;
} else {
r = mid;
}
}
return r == numberOfEntries ? -1 : r;
}

public static long searchKeyInFileReversed(SSTablesController controller,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Просто идея
Функция аналогичная предыдущей. Раз вы уже выделили компаратор в отдельные функции, то можно просто передавать его как параметр

int ind, long numberOfEntries,
MemorySegment mapped, MemorySegment key,
Comparator<MemorySegment> segComp) {
long l = -1;
long r = numberOfEntries;

while (r - l > 1) {
long mid = (l + r) / 2;
SSTableRowInfo info = controller.createRowInfo(ind, mid);
if (greaterEqThen(segComp, info.keyOffset, info.keySize, mapped, key)) {
l = mid;
} else {
r = mid;
}
}
return l;
}

}
Loading
Loading