Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g595.Manucharyan.task3 #279

Merged
merged 28 commits into from Dec 9, 2016
Merged

g595.Manucharyan.task3 #279

merged 28 commits into from Dec 9, 2016

Conversation

vanderwardan
Copy link
Contributor

No description provided.

@ignorer ignorer self-assigned this Nov 22, 2016

import ru.mipt.java2016.homework.base.task2.KeyValueStorage;

import static java.lang.Math.max;
Copy link
Collaborator

@ignorer ignorer Nov 25, 2016

Choose a reason for hiding this comment

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

Здесь в последних двух абзацах довольно коротко поясняют за статик импорт, и когда его нужно/не нужно использовать.
Что касается конкретно данного случая, он не попадает ни под одно из описаний. Можешь, конечно, оставить, однако лично я удивлён, что тебе оказалось проще написать import static, нежели просто заюзать Math.max() в одном месте в коде.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

просто, когда я написал max() он предложил подключить это (там было несколько вариантов), я просто нажал enter и забил)

public class ConcreteStrategyStringRandomAccess implements SerializationStrategyRandomAccess<String> {
@Override
public void serializeToFile(String value, RandomAccessFile output) throws IOException {
writeString(output, value);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Какая клёвая реализация... А точно убрать один уровень вызовов никак нельзя? Лично мне кажется, что я вижу, как можно это сделать.
И кстати, попробуй вернуть назад writeUTF, вроде должно побыстрее начать работать :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ну, можно inline написать 😃


private static final long MAX_CACHE_SIZE = 100L;

private SerializationStrategyRandomAccess<K> keySerializationStrategy;
Copy link
Collaborator

Choose a reason for hiding this comment

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

final же можно сделать - вряд ли ты будешь менять стратегию в процессе работы над хранилищем.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

да, врятли...

@Override
public boolean exists(K key) {
if (isClosed) {
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Тут бы IllegalStateException был кстати. А вообще эту проверку лучше в отдельную функцию вынести. А вот в close() не надо, он при повторном закрытии ничего не должен делать.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

У меня в close() и не было ничего) А так да, мне приходила эта идея в голову, но я забил)

if (isClosed) {
return false;
}
if (cache.containsKey(key)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Идея предложила тебе заменить на return cache.containsKey(key) || base.containsKey(key), а ты её игноришь. Не надо так.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ну так же понятней, нет? Типа тут односложные ифы, и сразу понятно, что происходит, иначе надо думать(

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ну, не знаю, по мне так два однотипных условия в одном выглядят читабельнее. Вообще не суть.

File file2 = new File(path, mapStorageName);
mapStorage = new RandomAccessFile(file2, "rw");

if (file.exists() && file2.exists()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

При создании RandomAccessFile в режиме rw создаётся и файл, который ты подал в качестве аргумента. Получается, ты только что создал файлы (а если не создал, то вылететл IOException), а потом ещё специально что-то проверяешь?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Поправил


if (file.exists() && file2.exists()) {
uploadDataFromStorage();
} else if (!file.createNewFile() || file2.createNewFile()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

createNewFile() вернёт false только когда файл уже существет, то есть exist() вернул true. Такая проверка есть двумя строчками выше, так что по-моему лучше здесь if убрать, да и вообще, наверное, весь if-else блок, оставить только вызов функции. Объясни мне, зачем это ветвление здесь вообще.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true if the named file does not exist and was successfully created; false if the named file already exists. Если файл не удалось создать, то должно вернуться false, нет? Ветвление здесь вот зачем: есть два варианта, файлы уже есть, тогда загружаем их. Если же их нет, но и создать их не получилось, то что-то пошло не так

Copy link
Collaborator

Choose a reason for hiding this comment

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

Давай так.
exist возвращает true тогда и только тогда, когда файл есть.
createNewFile возвращает false тогда и только тогда, когда файл есть (ты привёл кусок документации).
[Тут чудеса матлогики]
В итоге получаем, что эти два условия эквивалентны.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ок

*/
public interface SerializationStrategyRandomAccess<Value> {

void serializeToFile(Value value, RandomAccessFile output) throws IOException;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Вместо RandomAccessFile лучше сделать DataOutput здесь - он является родителем RandomAccessFile, но при этом код становится гибче.


void serializeToFile(Value value, RandomAccessFile output) throws IOException;

Value deserializeFromFile(RandomAccessFile input) throws IOException;
Copy link
Collaborator

Choose a reason for hiding this comment

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

То же, но про DataInput. Как я и говорил на семинаре (и не на одном), лучше не цепляться за конкретную реализацию.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Исравил

private SerializationStrategyRandomAccess<V> valueSerializationStrategy;

//consist keys and offsets(the pair of begin and length)
private HashMap<K, Long> base = new HashMap<>();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Лучше тип переменной сделать Map, ты же внутри класса не используешь его как HashMap.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Странно, у меня так же было и во втором задании...

@ignorer
Copy link
Collaborator

ignorer commented Nov 25, 2016

Я так понимаю, ты сжимаешь хранилище только в close(), что плохо сказывается на его объёме в рантайме - постепенно оно заполняется мёртвыми бесполезными объектами, и нужно их оттуда убирать. Поправь.

private void reorganiseStorage() {
try {
File file1 = new File(pathname, storageName);
RandomAccessFile storage = new RandomAccessFile(file1, "rw");
Copy link
Collaborator

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.

Добавил

RandomAccessFile storage = new RandomAccessFile(file1, "rw");

File file = new File(pathname, "newStorage.txt");
RandomAccessFile newStorage = new RandomAccessFile(file, "rw");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Через DataOutputStream можно было бы наклепать, обернув BufferedOutputStream. Побыстрее должно работать.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

мне же нужно знать offset для каждого элемента, а у DataOutputStream нет такого функционала, или я что-то не понимаю?

Copy link
Collaborator

Choose a reason for hiding this comment

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

size()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Да, стало работать быстрее, спасибо)

@ignorer ignorer merged commit a64a565 into fediq:master Dec 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants