-
Notifications
You must be signed in to change notification settings - Fork 78
Качмар Евгений, ИТМО ФИТиП М33331, Reverse Iterator #297
base: main
Are you sure you want to change the base?
Changes from all commits
b9fb7df
63cd280
c25d10a
e080066
d41b0e1
05a9ba0
1355424
3275eb6
c857426
7eca3c6
0592055
89313f9
cfe3308
8474dea
907b17a
c0b4abf
5d44f3d
52d32e5
166cb3d
a061de3
3f6eb17
6468b3e
97a00f3
aaac68d
a4c2e7d
e35cd92
ae3723e
fc982a5
504b0b5
1025d4b
2260e6d
49f5e61
06e42f6
785bbb5
c6ddd98
e6e74d4
0ec702e
2655807
4c71c45
f1e92a4
f7c97bb
b818d10
da21ff1
bbe9fc8
444f3d5
6de4b16
abc1d9c
562c924
04cf565
c122a68
6707aad
f499825
f48b5f2
cfd528b
510d890
e643993
0bc60e2
52cc057
95c04ce
dec80cb
b7cf38e
69287ff
d01433f
a03ddbc
6492359
07da600
cbbc475
115ba3c
89cb2dc
c554338
a5eb570
31c8509
ac2e977
a4328e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
return reverseIter(from, to); | ||
} | ||
|
||
SortedMap<MemorySegment, Entry<MemorySegment>> dataSlice; | ||
|
||
if (from == null && to == null) { | ||
|
@@ -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()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь вы создаете еще 2 компаратора, один из которых полностью идентичен созданному ранее. Итого создание 3 компараторов при каждом вызове There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Всегда передается полная мапа, начало игнорируется, поэтому тестов, где |
||
} | ||
|
||
@Override | ||
public Entry<MemorySegment> get(MemorySegment key) { | ||
if (key == null) { | ||
|
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())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Не должно быть лишних обращений к структурам данных (особенно конкурентным) |
||
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Лучше заменить на цикл. Рекурсия тут не оправдана |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Конструктор - копия первого, в котором почему-то явно не инициализировано |
||
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); | ||
} | ||
} | ||
|
||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Хочется какой-то консистентности. Или все такие места if (isReversed) {
...
} else {
...
} Или if (isReversed) {
...
return
}
... |
||
} | ||
|
||
private boolean isBetween(MemorySegment who) { | ||
|
@@ -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; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Создание объекта на каждый вызов
get
. Зачем?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
И вы все еще нарушаете инвариант
Comparable
: