source: CIVL/examples/verifyThis/treeBuffer/treebuffer_caterpillar.cvl@ 397ae5f

main test-branch
Last change on this file since 397ae5f was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 2.7 KB
Line 
1#include <seq.cvh>
2#include <stdlib.h>
3#include "treebuffer.h"
4
5struct Node {
6 Node * parent;
7 int data;
8 // reference counter. A Node object can be deleted iff its
9 // ref_count == 0 :
10 int ref_count;
11 // number of ancesters. Node.num_ancest == Node.parent->num_ancest + 1
12 int num_ancest;
13};
14
15struct Tree {
16 int history;
17 Node * xs; // reference to the last added node
18 Node * ys; // caterpillar
19};
20
21/* ********** helper functions ********** */
22// garbage collection ...
23void gc(Node * node) {
24 if (node == NULL || node->ref_count > 0)
25 return;
26
27 Node * next = node->parent;
28
29 free(node);
30 if (next != NULL) {
31 next->ref_count--;
32 gc(next);
33 }
34}
35
36/* ********** functions implements interfaces ********** */
37Node * make_node(int data) {
38 Node * node = (Node*)malloc(sizeof(Node));
39
40 node->parent = NULL;
41 node->data = data;
42 node->ref_count = 0;
43 node->num_ancest = 0;
44 return node;
45}
46
47int get_data(Node * node) {
48 $assert(node, "attempt to get data from a invalid node reference");
49 return node->data;
50}
51
52Tree * empty(int history) {
53 Tree * tree = (Tree*)malloc(sizeof(Tree));
54
55 tree->history = history;
56 tree->xs = NULL;
57 tree->ys = NULL;
58 return tree;
59}
60
61Tree * add(Tree * tree, int data) {
62 Node * node = make_node(data);
63 Tree * new_tree = empty(tree->history);
64
65 if (tree->xs == NULL) {
66 new_tree->xs = node;
67 new_tree->xs->ref_count++;
68 new_tree->ys = tree->ys;
69 if (tree->ys!=NULL)
70 tree->ys->ref_count++;
71 } else if(tree->xs->num_ancest < tree->history - 2) {
72 node->parent = tree->xs;
73 node->parent->ref_count++;
74 node->num_ancest = node->parent->num_ancest + 1;
75 new_tree->xs = node;
76 new_tree->xs->ref_count++;
77 new_tree->ys = tree->ys;
78 if (tree->ys != NULL)
79 new_tree->ys->ref_count++;
80 } else {
81 node->parent = tree->xs;
82 node->parent->ref_count++;
83 node->num_ancest = node->parent->num_ancest + 1;
84 new_tree->ys = node;
85 new_tree->ys->ref_count++;
86 }
87 return new_tree;
88}
89
90// Note: "ancestors" is an 0-terminated array:
91void take(Tree * tree, Node * ancestors[]) {
92 int history = tree->history;
93 int i = 0;
94 Node * ancestor = tree->xs;
95
96 while (i < history && ancestor != NULL) {
97 ancestors[i++] = ancestor;
98 ancestor = ancestor->parent;
99 }
100 ancestor = tree->ys;
101 while (i < history && ancestor != NULL) {
102 ancestors[i++] = ancestor;
103 ancestor = ancestor->parent;
104 }
105 ancestors[i] = 0;
106}
107
108void delete(Tree * tree) {
109 // took ys off and garbage collection:
110 if (tree->ys != NULL) {
111 Node * ys = tree->ys;
112
113 tree->ys = NULL;
114 ys->ref_count--;
115 gc(ys);
116 }
117 if (tree->xs != NULL) {
118 Node * xs = tree->xs;
119
120 tree->xs = NULL;
121 xs->ref_count--;
122 gc(xs);
123 }
124 free(tree);
125}
126
127
Note: See TracBrowser for help on using the repository browser.