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

ДЗ№4. Тяпуев Дмитрий. Магистратура. Политех #202

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e176c7d
all done
typuichik123 Sep 27, 2023
26f5bb7
fixed codeclimate
typuichik123 Sep 27, 2023
5a89728
fixes
typuichik123 Sep 27, 2023
b6e47b3
Merge branch 'main' into main
incubos Sep 27, 2023
269b43f
fix new test
typuichik123 Sep 27, 2023
6ecdff5
Merge branch 'polis-vk:main' into main
typuichik123 Oct 2, 2023
c162794
Homework 2 done
typuichik123 Oct 4, 2023
ca1356b
fixes
typuichik123 Oct 4, 2023
6280634
fix codeclimate
typuichik123 Oct 4, 2023
8244af7
Merge branch 'main' into main
lamtev Oct 4, 2023
e23dcff
Merge branch 'main' into homework2
incubos Oct 5, 2023
d4d384a
fix all
typuichik123 Oct 8, 2023
43569ac
fix codeclimate
typuichik123 Oct 8, 2023
89533ca
last fix codeclimate
typuichik123 Oct 8, 2023
0fca460
last fix codeclimate
typuichik123 Oct 8, 2023
ef2c3b0
чужой тест повалился по таймауту, загрузил код без изменений
typuichik123 Oct 8, 2023
57e1652
Merge remote-tracking branch 'origin/main' into homework3
typuichik123 Oct 9, 2023
9957684
Merge branch 'polis-vk:main' into main
typuichik123 Oct 11, 2023
9e8f1b3
Merge remote-tracking branch 'origin/main' into homework3
typuichik123 Oct 11, 2023
5f758a6
Merge branch 'polis-vk:main' into main
typuichik123 Oct 17, 2023
aa7dfa7
Merge remote-tracking branch 'origin/main' into homework3
typuichik123 Oct 17, 2023
30d534a
Merge branch 'polis-vk:main' into main
typuichik123 Oct 20, 2023
b750479
Merge branch 'polis-vk:main' into main
typuichik123 Oct 23, 2023
0dec53e
Merge remote-tracking branch 'origin/main' into homework3
typuichik123 Oct 26, 2023
2e5a3d4
Merge branch 'polis-vk:main' into main
typuichik123 Oct 26, 2023
d614b11
Merge remote-tracking branch 'origin/main' into homework3
typuichik123 Oct 26, 2023
3899bc4
Homework 4 done
typuichik123 Oct 27, 2023
fd682b5
fixes
typuichik123 Oct 27, 2023
e7e25ca
Merge branch 'polis-vk:main' into main
typuichik123 Oct 27, 2023
52230fd
several fixes for codeclimate
typuichik123 Oct 27, 2023
1767600
several fixes for codeclimate
typuichik123 Oct 27, 2023
06bb1b9
Merge branch 'main' into homework4
typuichik123 Oct 27, 2023
028150c
several fixes for codeclimate
typuichik123 Oct 28, 2023
273a787
several fixes for codeclimate
typuichik123 Oct 28, 2023
6b80d94
fix codeclimate
typuichik123 Oct 28, 2023
5603493
fix codeclimate
typuichik123 Oct 28, 2023
c8b8aad
Merge branch 'polis-vk:main' into main
typuichik123 Nov 8, 2023
d7da6f4
Merge branch 'polis-vk:main' into main
typuichik123 Nov 9, 2023
d759686
Merge branch 'main' into homework4
typuichik123 Nov 12, 2023
e7570ab
Merge branch 'main' into homework4
typuichik123 Nov 13, 2023
e6de16c
Some fixes
typuichik123 Nov 13, 2023
35c51db
Merge remote-tracking branch 'origin/homework4' into homework4
typuichik123 Nov 13, 2023
71ede3a
Last fixes
typuichik123 Nov 13, 2023
25a2985
Last fixes
typuichik123 Nov 13, 2023
b5487db
Merge branch 'main' into homework4
Marashov-Alexander Nov 14, 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
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
import ru.vk.itmo.Dao;
import ru.vk.itmo.Entry;
import ru.vk.itmo.test.DaoFactory;
import ru.vk.itmo.tyapuevdmitrij.InMemoryDao;
import ru.vk.itmo.tyapuevdmitrij.MemorySegmentDao;

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.nio.charset.StandardCharsets;

@DaoFactory(stage = 2)
@DaoFactory(stage = 4)
public class DaoFactoryImplementation implements DaoFactory.Factory<MemorySegment, Entry<MemorySegment>> {

@Override
public Dao<MemorySegment, Entry<MemorySegment>> createDao() {
return new InMemoryDao();
return new MemorySegmentDao();
}

@Override
public Dao<MemorySegment, Entry<MemorySegment>> createDao(Config config) {
return new InMemoryDao(config);
return new MemorySegmentDao(config);
}

@Override
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/ru/vk/itmo/tyapuevdmitrij/FilesException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.vk.itmo.tyapuevdmitrij;

public class FilesException extends RuntimeException {
public FilesException(String message, Throwable cause) {
super(message, cause);
}
}
154 changes: 0 additions & 154 deletions src/main/java/ru/vk/itmo/tyapuevdmitrij/InMemoryDao.java

This file was deleted.

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

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.Path;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class MemorySegmentDao implements Dao<MemorySegment, Entry<MemorySegment>> {
private static final Comparator<MemorySegment> MEMORY_SEGMENT_COMPARATOR = (segment1, segment2) -> {
long offset = segment1.mismatch(segment2);
if (offset == -1) {
return 0;
}
if (offset == segment1.byteSize()) {
return -1;
}
if (offset == segment2.byteSize()) {
return 1;
}
return segment1.get(ValueLayout.JAVA_BYTE, offset) - segment2.get(ValueLayout.JAVA_BYTE, offset);
};
private final ConcurrentNavigableMap<MemorySegment, Entry<MemorySegment>> memTable =
new ConcurrentSkipListMap<>(MEMORY_SEGMENT_COMPARATOR);

private final Arena readArena;
private final Path ssTablePath;
private long ssTablesEntryQuantity;
private boolean compacted;
private final Storage storage;

public MemorySegmentDao() {
ssTablePath = null;
readArena = null;
storage = null;
}

public MemorySegmentDao(Config config) {
ssTablePath = config.basePath();
readArena = Arena.ofShared();
storage = new Storage(ssTablePath, readArena);
}

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

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

@Override
public Entry<MemorySegment> get(MemorySegment key) {
Entry<MemorySegment> value = memTable.get(key);
if (value != null && value.value() == null) {
return null;
}
if (value != null || storage.ssTables == null) {
return value;
}
Iterator<Entry<MemorySegment>> iterator = storage.range(Collections.emptyIterator(),
key,
null,
MEMORY_SEGMENT_COMPARATOR);

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

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

@Override
public void compact() throws IOException {
if (storage.ssTablesQuantity == 0 && memTable.isEmpty()) {
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Не рассматривается еще один кейс: если количество таблиц == 1, а memTable is empty, то компактить тоже нет смысла

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Исправил

}
Iterator<Entry<MemorySegment>> dataIterator = get(null, null);
Arena writeArena = Arena.ofConfined();
Copy link
Contributor

Choose a reason for hiding this comment

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

Лучше создавать под try-with-resources. Иначе, в случае исключения между созданием и закрытием, будет потеря памяти

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Исправил

MemorySegment buffer = NmapBuffer.getWriteBufferToSsTable(getCompactionTableByteSize(),
ssTablePath,
storage.ssTablesQuantity,
writeArena,
true);
long bufferByteSize = buffer.byteSize();
buffer.set(ValueLayout.JAVA_LONG_UNALIGNED, bufferByteSize - Long.BYTES, ssTablesEntryQuantity);
long dataOffset = 0;
long indexOffset = bufferByteSize - Long.BYTES - ssTablesEntryQuantity * 2L * Long.BYTES;
while (dataIterator.hasNext()) {
Entry<MemorySegment> entry = dataIterator.next();
buffer.set(ValueLayout.JAVA_LONG_UNALIGNED, indexOffset, dataOffset);
indexOffset += Long.BYTES;
buffer.set(ValueLayout.JAVA_LONG_UNALIGNED, dataOffset, entry.key().byteSize());
dataOffset += Long.BYTES;
MemorySegment.copy(entry.key(), 0, buffer, dataOffset, entry.key().byteSize());
dataOffset += entry.key().byteSize();
buffer.set(ValueLayout.JAVA_LONG_UNALIGNED, indexOffset, dataOffset);
indexOffset += Long.BYTES;
buffer.set(ValueLayout.JAVA_LONG_UNALIGNED, dataOffset, entry.value().byteSize());
dataOffset += Long.BYTES;
MemorySegment.copy(entry.value(), 0, buffer, dataOffset, entry.value().byteSize());
dataOffset += entry.value().byteSize();
}
if (writeArena.scope().isAlive()) {
writeArena.close();
}
StorageHelper.deleteOldSsTables(ssTablePath);
StorageHelper.renameCompactedSsTable(ssTablePath);
compacted = true;
}

@Override
public void close() throws IOException {
if (compacted) {
readArena.close();
Copy link
Contributor

Choose a reason for hiding this comment

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

думаю, проверка на isAlive должна быть выше всех. Иначе вы не проверяете на isAlive, а просто закрываете арену

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Исправил

return;
}
if (memTable.isEmpty()) {
readArena.close();
return;
}
if (!readArena.scope().isAlive()) {
return;
}
readArena.close();
storage.save(memTable.values(), ssTablePath);

}

private long getCompactionTableByteSize() {
Iterator<Entry<MemorySegment>> dataIterator = get(null, null);
long compactionTableByteSize = 0;
long countEntry = 0;
while (dataIterator.hasNext()) {
Entry<MemorySegment> entry = dataIterator.next();
compactionTableByteSize += entry.key().byteSize();
compactionTableByteSize += entry.value().byteSize();
countEntry++;
}
ssTablesEntryQuantity = countEntry;
return compactionTableByteSize + countEntry * 4L * Long.BYTES + Long.BYTES;
}
}
Loading
Loading