From 87092bd64fe4247ea5d656c1006994762e4f53e3 Mon Sep 17 00:00:00 2001 From: Dmitry Zuikov Date: Mon, 16 Oct 2023 09:34:14 +0300 Subject: [PATCH] docs/notes/garbage-collection --- docs/notes/garbage-collection-notes.txt | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/notes/garbage-collection-notes.txt diff --git a/docs/notes/garbage-collection-notes.txt b/docs/notes/garbage-collection-notes.txt new file mode 100644 index 00000000..6194f5c2 --- /dev/null +++ b/docs/notes/garbage-collection-notes.txt @@ -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, где <> - номер <<поколения>>. + +устанавливаем sorage/blocks на blocks-N. + +Новые блоки начинают писаться в него. + +При чтении делаем две вещи: + +1. инкрементируем "refcount" для каждого блока + +2. если через какое-то время T refcount для блока /= 0, +то переносим его в новое поколение. + +3. если спустя TBD - refcounf == 0, то блок +можно удалить? + +мутноватая тема. спустя какое время? + +Ок, другой вариант. Делаем клон сторейджа полностью, со +ссылками. собираем мусов в нём, относительно тех ссылок, +которые в нём зафиксированы. + +В процессе работы с новым сторейджем действительно выполняем +копирование из "старого" поколения в новое, если блок +оказался востребованным в новом поколении. + +<<Старая>> копия сторейджа иммутабельна, в смысле новые +ссылки и блоки не создаются. + +Когда закончили сборку, то просто добавляем все выжившие +блоки обратно в новое поколение, а временный каталог для +сборки прибиваем. + +Развитие идеи в том, что мы не делаем копий блоков, а +оперируем только ссылками. тогда, допустим, в начале цикла +сборки мы устанавливаем всем блокам refcount=0, делаем +снапшот ссылок, сканируем ссылки из этого снапшота и ищем +выжившие блоки, потом удаляем те, которые не выжили. + +В процессе удаления хорошо бы понять, что новых ссылок не +появилось и они не указывают на блоки, которых у нас нет, а +так же хорошо бы не удалять блоки в процессе обновления +ссылки. + +TO BE CONTINUED... + +