From a8a24971573f935258c83c526a3019b5858d0714 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=A0krob=C3=A1nek?=
 <jiri.skrobanek@gmail.com>
Date: Tue, 27 Jul 2021 09:49:29 +0200
Subject: [PATCH] Figure of fat nodes

---
 201-persist/fat-nodes.asy | 75 +++++++++++++++++++++++++++++++++++++++
 201-persist/persist.tex   | 11 +++++-
 2 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 201-persist/fat-nodes.asy

diff --git a/201-persist/fat-nodes.asy b/201-persist/fat-nodes.asy
new file mode 100644
index 0000000..0120997
--- /dev/null
+++ b/201-persist/fat-nodes.asy
@@ -0,0 +1,75 @@
+DefaultHead=TeXHead;
+
+real factor = 0.4;
+
+object Node(string l, pair p){
+    label(l,p*factor);
+    return draw("", ellipse, p*factor, xmargin=3mm,FillDraw(white,black));
+}
+
+void Version(string l, pair p){
+    draw(box(factor*(p-(0.5cm,0.5cm)),factor*(p+(0.5cm,0.5cm))), black+linewidth(0.2mm));
+    label(l,p*factor);
+}
+
+void Container(pair p){
+    draw(box(factor*(p-(0.6cm,0.6cm)),factor*(p+(2.6cm,0.6cm))), black+linewidth(0.2mm));
+}
+
+object a = Node("A", (-3cm,0cm));
+object b = Node("B", (-3cm,-3cm));
+object c = Node("C", (-3cm,-6cm));
+object d = Node("D", (-3cm,3cm));
+
+Container((0cm,0cm));
+Version("1",(0cm,0cm));
+Version("2",(1cm,0cm));
+Version("4",(2cm,0cm));
+
+Container((5cm,0cm));
+Version("5",(5cm,0cm));
+
+Container((0cm,-3cm));
+Version("2",(0cm,-3cm));
+Version("3",(1cm,-3cm));
+
+Container((0cm,-6cm));
+Version("3",(0cm,-6cm));
+Version("5",(1cm,-6cm));
+
+Container((0cm,3cm));
+Version("4",(0cm,3cm));
+
+
+pair left(object p){
+    return point(p,dir(-120));
+}
+
+pair right(object p){
+    return point(p,dir(0));
+}
+
+pair top(object p){
+    return point(p,dir(90));
+}
+
+pair bottom(object p){
+    return point(p,dir(-90));
+}
+
+draw(right(a)--(factor*-0.6cm,0cm), Arrow);
+draw(right(b)--(factor*-0.6cm,factor*-3cm), Arrow);
+draw(right(c)--(factor*-0.6cm,factor*-6cm), Arrow);
+draw(right(d)--(factor*-0.6cm,factor*3cm), Arrow);
+draw((factor*2.6cm,0cm)--(factor*4.4cm,0cm), Arrow);
+
+draw(arc((-4cm,-3cm)*factor, r=3cm*factor, angle1=270, angle2=90),dotted, arrow=Arrow(TeXHead));
+draw(bottom(d)--top(a),dotted,arrow=Arrow(TeXHead));
+draw(top(b)--bottom(a),dotted,arrow=Arrow(TeXHead));
+
+draw((factor*1cm,factor*-0.5cm)--(factor*1cm,factor*-2.4cm),arrow=Arrow(TeXHead),L=Label("l", position=MidPoint));
+draw((factor*2cm,factor*-0.5cm)--(factor*2cm,factor*-2.4cm),arrow=Arrow(TeXHead),L=Label("l", position=MidPoint));
+draw((factor*1cm,factor*-3.5cm)--(factor*1cm,factor*-5.4cm),arrow=Arrow(TeXHead),L=Label("l", position=MidPoint));
+draw((factor*2cm,factor*0.5cm)--(factor*2cm,factor*2.4cm),arrow=Arrow(TeXHead),L=Label("r", position=MidPoint));
+draw((factor*5cm,factor*0.5cm)--(factor*5cm,factor*3cm)--(factor*2.6cm,factor*3cm),arrow=Arrow(TeXHead),L=Label("r", position=MidPoint));
+draw((factor*5cm,factor*-0.5cm)--(factor*5cm,factor*-6cm)--(factor*2.6cm,factor*-6cm),arrow=Arrow(TeXHead),L=Label("l", position=MidPoint));
\ No newline at end of file
diff --git a/201-persist/persist.tex b/201-persist/persist.tex
index 83d2d65..cdf8224 100644
--- a/201-persist/persist.tex
+++ b/201-persist/persist.tex
@@ -37,7 +37,9 @@ Multi-threading is easier when there is confidence that existing objects will no
 
 \section{Basic Constructs}
 
-We will explore several easy concepts, which we will later combine to reach optimal persistent pointer-based structure. Before that however, we notice that some data structures are persistent in their default implementation. Take stack for example. 
+We will explore several easy concepts, which we will later combine to reach optimal persistent pointer-based structure. 
+Before that however, we notice that some data structures are persistent in their default implementation. 
+Take stack for example. 
 
 \subsection{Persistent Stack}
 
@@ -141,6 +143,13 @@ The order in which these allocations are executed can be arbitrary.
 We can place an upper bound on the number of newly allocated fat nodes -- total number of vertices in the tree (including deleted vertices). 
 At most one new slot is occupied for every vertex in the tree.
 
+Consider a tree with one vertex A and a sequence of updates. 
+First B is inserted as a left child of A, then C is inserted as a left child of B, then D is inserted as a right child of A, finally B is deleted and C becomes left child of A. 
+These operations are captured by a schema of fat vertices in figure \figref{taf-nodes}. 
+Inverse pointers for the latest version are dotted.
+
+\figure[fat-nodes]{fat-nodes.pdf}{Fat Nodes}
+
 To take advantage of fat nodes, we need the balancing algorithm to limit the number of vertices that change in one operation. 
 It is sufficient that the changes can be amortized to a constant number per update.
 Furthermore, we need a limit on the number of pointers that can target one vertex at one time.
-- 
GitLab