Size: a a a

Rust — русскоговорящее сообществo

2020 August 17

Э

Эрик in Rust — русскоговорящее сообществo
Alex Zhukovsky
Вопрос знатокам - как можно решить такую задачку? https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=58363f779a0136430ad6b491fb5af1f0



В чём суть: есть арк на хэшмапу, нужно смутировать мапу так, чтобы те кто держат ссылки созданные до вызова функции не увидели изменений, а после - увидели. Проблема в том что нужно сделать за О(1) памяти. то есть просто саллоцировать новую мапу и подменить не вариант.



Как это видится у меня в голове: нужно сделать take() на None, дождаться пока счетчик ссылок упадёт до 1, и после этого спокойно мутировать его, после чего сунуть обратно. Но как это сделать чтобы борровчекер не возмущался - не знаю.
> ссылки созданные до вызова функции
А как ты хочешь, чтобы старые ссылки вели на старую мапу, а новые на другую, но не клонируя мапу?
источник

AZ

Alex Zhukovsky in Rust — русскоговорящее сообществo
Вафель
Ну evmap утверждает что её имплементация не требует оверхэда на синхронизацию, кроме момента когда ты "обновляешь" мапу (явно через WriteHandle::refresh)

Если у тебя обновления на 1% мапы, то думаю это самое то
> For read-heavy workloads, the scheme used by this module is particularly useful. Writers can afford to refresh after every write, which provides up-to-date reads, and readers remain fast as they do not need to ever take locks.
звучит как то что нужно, спасибо, гляну
источник

В

Вафель in Rust — русскоговорящее сообществo
Yevhenii Babichenko
Ну под капотом у неё, как я понял, примерно то, что я предложил, только с кучей оптимизации
Смотрел доклад автора про то, как она сделана, но уже всё забыл 🤣
источник

В

Вафель in Rust — русскоговорящее сообществo
Alex Zhukovsky
звучит как то что нужно, спасибо, гляну
класс 👍
источник

YB

Yevhenii Babichenko in Rust — русскоговорящее сообществo
Задача без какого-то рода логов не решаема, если хочется вменяемого потребления памяти
источник

R

Roman in Rust — русскоговорящее сообществo
Мапа O(1) по памяти это уже сложно. Даже без синхронизации
источник

Э

Эрик in Rust — русскоговорящее сообществo
Vlad Stepanov
Решительно не понимаю, как оно работает, там же &mut self требуется в write :(

Ручная сборка такого-же поведения с нуля — падает с ожидаемым cannot borrow data in a `& reference as mutable`. Где можно почитать про то, почему с File так работает?
struct Yoba<T: Write>(T);

let y: Yoba<&File> = Yoba(&file);
источник

AZ

Alex Zhukovsky in Rust — русскоговорящее сообществo
Вафель
класс 👍
с другой стороны я не вижу особо апишек для модификации существующих записей, только вставки
источник

R

Roman in Rust — русскоговорящее сообществo
Так вставь на тот же ключ
источник

AZ

Alex Zhukovsky in Rust — русскоговорящее сообществo
а не, апдейт есть. Тогда подходит
источник

A

Artem in Rust — русскоговорящее сообществo
Roman
Мапа O(1) по памяти это уже сложно. Даже без синхронизации
на ограниченном домене — вполне себе легко
источник

AZ

Alex Zhukovsky in Rust — русскоговорящее сообществo
Roman
Так вставь на тот же ключ
вставка в тот же ключ это либо паника, либо просто вставка, потому что там multivalue
источник

R

Roman in Rust — русскоговорящее сообществo
Artem
на ограниченном домене — вполне себе легко
Этого в задаче небыло
источник

R

Roman in Rust — русскоговорящее сообществo
Alex Zhukovsky
вставка в тот же ключ это либо паника, либо просто вставка, потому что там multivalue
Странно. Я б ожидал, что старое значение останется жить, пока читают, а новые читатели уже новое значение увидят
источник

AZ

Alex Zhukovsky in Rust — русскоговорящее сообществo
Roman
Странно. Я б ожидал, что старое значение останется жить, пока читают, а новые читатели уже новое значение увидят
Пример из доки же:

book_reviews_w.insert("Grimms' Fairy Tales", "Masterpiece.");
book_reviews_w.insert("Grimms' Fairy Tales", "Eh, the title seemed weird.");
assert_eq!(book_reviews_r.get("Grimms' Fairy Tales").map(|rs| rs.len()), Some(2));
источник

SS

Sergey Shmakov in Rust — русскоговорящее сообществo
ни у кого во время билда не было такого? error: linking with link.exe failed: exit code: 1120
источник

R

Roman in Rust — русскоговорящее сообществo
Alex Zhukovsky
Пример из доки же:

book_reviews_w.insert("Grimms' Fairy Tales", "Masterpiece.");
book_reviews_w.insert("Grimms' Fairy Tales", "Eh, the title seemed weird.");
assert_eq!(book_reviews_r.get("Grimms' Fairy Tales").map(|rs| rs.len()), Some(2));
Ну ок
источник

A

Artem in Rust — русскоговорящее сообществo
Alex Zhukovsky
и вот эти 2 гига хочется срезать
Посмотри в персистентные структуры данных. Навскиду наискал в duckduckgo вот это:
https://github.com/orium/rpds
источник

Э

Эрик in Rust — русскоговорящее сообществo
Vlad Stepanov
Решительно не понимаю, как оно работает, там же &mut self требуется в write :(

Ручная сборка такого-же поведения с нуля — падает с ожидаемым cannot borrow data in a `& reference as mutable`. Где можно почитать про то, почему с File так работает?
Если всё ещё не понимаешь, то смотри такую штуку:

struct Qwe(RefCell<Box<[u8]>>);

impl io::Write for &Qwe {
 fn write(self: &mut &Qwe, b: &[u8]) -> io::Result<usize> {
   self.0.borrow_mut().write(b)
 }
}
источник

Э

Эрик in Rust — русскоговорящее сообществo
Sergey Shmakov
ни у кого во время билда не было такого? error: linking with link.exe failed: exit code: 1120
Что за link.exe?
источник