mirror of https://github.com/voidlizard/hbs2
docs/notes/garbage-collection
This commit is contained in:
parent
9f745148e6
commit
87092bd64f
|
@ -0,0 +1,116 @@
|
||||||
|
|
||||||
|
Немного про сборку мусора в HBS2
|
||||||
|
|
||||||
|
Предпосылки:
|
||||||
|
|
||||||
|
- В блоках / содержимом транзакций может быть всё, что
|
||||||
|
угодно. Например, ссылки. Нет возможности заставить
|
||||||
|
разработчиков не делать ссылки изнутри бинарных блоков,
|
||||||
|
так же как и нет возможности надёжно отслеживать наличие
|
||||||
|
рукояток для сборщика мусора для структур данных.
|
||||||
|
|
||||||
|
Ведь приложения могут быть сторонними, в том числе
|
||||||
|
такими, которые вообще не пользуются Haskell и
|
||||||
|
библиотеками hbs2.
|
||||||
|
|
||||||
|
Простой пример: текстовый документ, который содержит
|
||||||
|
ссылки в текстовом виде.
|
||||||
|
|
||||||
|
|
||||||
|
Из этого получается, что мы не можем полагаться на наше
|
||||||
|
представление об устройстве блоков, и должны переложить это
|
||||||
|
на пользователя.
|
||||||
|
|
||||||
|
Каким образом:
|
||||||
|
|
||||||
|
Первая мысль: сделать некие pinned refs, в каждой такой
|
||||||
|
ссылке - дерево хэшей блоков, и эти блоки не трогать при
|
||||||
|
сборке, если есть pinned ref.
|
||||||
|
|
||||||
|
При сборке мусора использовать только их.
|
||||||
|
|
||||||
|
Все, что не pinned --- будет собираться.
|
||||||
|
|
||||||
|
Минус подхода: как быть с хостами, на которых нет pinned
|
||||||
|
ref?
|
||||||
|
|
||||||
|
Если pinned ref делать локальными. Если их не делать
|
||||||
|
локальными, то нужен протокол, который крайне похож на
|
||||||
|
refchan/reflog.
|
||||||
|
|
||||||
|
Выглядит не очень.
|
||||||
|
|
||||||
|
Другой подход: мы действуем в рамках имеющихся ссылок,
|
||||||
|
ссылки парсим, контент распознаём при помощи tryDetect.
|
||||||
|
|
||||||
|
Количество подобных структур стараемся не увеличивать.
|
||||||
|
|
||||||
|
Pinned refs для надёжности можно сделать тоже.
|
||||||
|
|
||||||
|
Далее.
|
||||||
|
|
||||||
|
Может ли сборщик быть инкрементальным?
|
||||||
|
|
||||||
|
Или даже так: может ли он быть НЕ инкрементальным?
|
||||||
|
|
||||||
|
Ссылки обновляются всё время, мы не можем "остановить мир"
|
||||||
|
без угрозы потери консистентности.
|
||||||
|
|
||||||
|
Поэтому, как бы поступить?
|
||||||
|
|
||||||
|
допустим, началась сборка.
|
||||||
|
|
||||||
|
storage/refs не трогаем, пускай пишут ссылки.
|
||||||
|
|
||||||
|
storage/blocks делаем файлом.
|
||||||
|
|
||||||
|
в нём - ссылка на "текущий" каталог блоков.
|
||||||
|
|
||||||
|
Когда пошёл процесс GC, создаём новый пустой каталог
|
||||||
|
blocks-N, где <<N>> - номер <<поколения>>.
|
||||||
|
|
||||||
|
устанавливаем sorage/blocks на blocks-N.
|
||||||
|
|
||||||
|
Новые блоки начинают писаться в него.
|
||||||
|
|
||||||
|
При чтении делаем две вещи:
|
||||||
|
|
||||||
|
1. инкрементируем "refcount" для каждого блока
|
||||||
|
|
||||||
|
2. если через какое-то время T refcount для блока /= 0,
|
||||||
|
то переносим его в новое поколение.
|
||||||
|
|
||||||
|
3. если спустя TBD - refcounf == 0, то блок
|
||||||
|
можно удалить?
|
||||||
|
|
||||||
|
мутноватая тема. спустя какое время?
|
||||||
|
|
||||||
|
Ок, другой вариант. Делаем клон сторейджа полностью, со
|
||||||
|
ссылками. собираем мусов в нём, относительно тех ссылок,
|
||||||
|
которые в нём зафиксированы.
|
||||||
|
|
||||||
|
В процессе работы с новым сторейджем действительно выполняем
|
||||||
|
копирование из "старого" поколения в новое, если блок
|
||||||
|
оказался востребованным в новом поколении.
|
||||||
|
|
||||||
|
<<Старая>> копия сторейджа иммутабельна, в смысле новые
|
||||||
|
ссылки и блоки не создаются.
|
||||||
|
|
||||||
|
Когда закончили сборку, то просто добавляем все выжившие
|
||||||
|
блоки обратно в новое поколение, а временный каталог для
|
||||||
|
сборки прибиваем.
|
||||||
|
|
||||||
|
Развитие идеи в том, что мы не делаем копий блоков, а
|
||||||
|
оперируем только ссылками. тогда, допустим, в начале цикла
|
||||||
|
сборки мы устанавливаем всем блокам refcount=0, делаем
|
||||||
|
снапшот ссылок, сканируем ссылки из этого снапшота и ищем
|
||||||
|
выжившие блоки, потом удаляем те, которые не выжили.
|
||||||
|
|
||||||
|
В процессе удаления хорошо бы понять, что новых ссылок не
|
||||||
|
появилось и они не указывают на блоки, которых у нас нет, а
|
||||||
|
так же хорошо бы не удалять блоки в процессе обновления
|
||||||
|
ссылки.
|
||||||
|
|
||||||
|
TO BE CONTINUED...
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue