smntc
an in-memory multimodal graph database
Loading...
Searching...
No Matches
Binary.c
Go to the documentation of this file.
1// Encoding binary 11
2// ^
3// |
4// ZERO ONE |
5// o==================o=================o
6// ^ CODE
7// |
8// |
9// |
10// the o===================o the
11// ^ smallest ^ biggest
12// | address is | address is
13// | ZERO | ONE
14// the first | | the second
15// edge is +--------+---------+ edge is
16// ZERO | ONE
17// o ROOT
18//
19
20#include <stdlib.h>
21#include "errors.h"
22#include "Graph.h"
23
24#define BINARY_CLUSTER_LENGTH 3
25#define BINARY_BITS_IN_INT ((int)sizeof(int) * 8)
26
27struct Binary {
28 unsigned int root;
29 unsigned int zero;
30 unsigned int one;
31 struct Graph *graph;
32};
33
42struct Binary *Binary_construct(unsigned int root, struct Graph *graph, int *error)
43{
44 struct Binary *this = malloc(sizeof(struct Binary));
45
46 if (0 == this) {
47 *error = ERROR_NO_MEMORY;
48 return 0;
49 }
50
51 this->root = root;
52 this->graph = graph;
53
54 unsigned int cluster[BINARY_CLUSTER_LENGTH];
55
56 Graph_addCluster(this->graph, BINARY_CLUSTER_LENGTH - 1, cluster, error);
57
58 if (*error) {
59 return 0;
60 }
61
62 this->zero = cluster[0];
63
64 Graph_addEdge(graph, this->root, this->zero, error);
65
66 if (*error) {
67 return 0;
68 }
69
70 Graph_addCluster(this->graph, BINARY_CLUSTER_LENGTH - 1, cluster, error);
71
72 if (*error) {
73 return 0;
74 }
75
76 this->one = cluster[0];
77
78 Graph_addEdge(graph, this->root, this->one, error);
79
80 if (*error) {
81 return 0;
82 }
83
84 return this;
85}
86
87struct Binary *Binary_destruct(struct Binary *this)
88{
89 if (0 != this) {
90 free(this);
91 }
92
93 return 0;
94}
95
96unsigned int Binary_writeCode(struct Binary *this, unsigned int input, int *error)
97{
98 int offset = 0; // count leading zeroes
99
100 for (int index = BINARY_BITS_IN_INT - 1; index >= 0; index--) {
101 if ((input >> index) & 1) {
102 break;
103 }
104 offset++;
105 }
106
107 // traverse clusters
108
109 unsigned int bufferA[BINARY_CLUSTER_LENGTH];
110 unsigned int *currentCluster = bufferA;
111
112 unsigned int bufferB[BINARY_CLUSTER_LENGTH];
113 unsigned int *nextCluster = bufferB;
114
115 unsigned int *swapper = 0;
116
117 currentCluster[BINARY_CLUSTER_LENGTH - 1] = 0;
118 if (input & 1) {
119 Graph_readCluster(this->graph, this->one, BINARY_CLUSTER_LENGTH, currentCluster, error);
120 } else {
121 Graph_readCluster(this->graph, this->zero, BINARY_CLUSTER_LENGTH, currentCluster, error);
122 }
123
124 if (*error) {
125 return 0;
126 }
127
128 int limit = BINARY_BITS_IN_INT - offset - 1;
129
130 for (int index = 1; index <= limit; index++) {
131
132 nextCluster[BINARY_CLUSTER_LENGTH - 1] = 0; // for checking at the end if already protruded
133
134 if ((input >> index) & 1) { // next is one
135
136 unsigned int lastTarget = Graph_readLastTarget(this->graph, currentCluster[1], error);
137
138 if (*error) {
139 return 0;
140 }
141
142 if (0 == lastTarget) {
143
144 Graph_addCluster(this->graph, BINARY_CLUSTER_LENGTH - 1, nextCluster, error);
145
146 if (*error) {
147 return 0;
148 }
149
150 Graph_addEdge(this->graph, currentCluster[1], nextCluster[0], error);
151
152 if (*error) {
153 return 0;
154 }
155
156 } else {
157
158 Graph_readCluster(this->graph, lastTarget, BINARY_CLUSTER_LENGTH, nextCluster, error);
159
160 if (*error) {
161 return 0;
162 }
163 }
164
165 } else { // next is zero
166
167 unsigned int lastTarget = Graph_readLastTarget(this->graph, currentCluster[0], error);
168
169 if (*error) {
170 return 0;
171 }
172
173 if (0 == lastTarget) {
174
175 Graph_addCluster(this->graph, BINARY_CLUSTER_LENGTH - 1, nextCluster, error);
176
177 if (*error) {
178 return 0;
179 }
180
181 Graph_addEdge(this->graph, currentCluster[0], nextCluster[0], error);
182
183 if (*error) {
184 return 0;
185 }
186
187 } else {
188
189 Graph_readCluster(this->graph, lastTarget, BINARY_CLUSTER_LENGTH, nextCluster, error);
190
191 if (*error) {
192 return 0;
193 }
194 }
195 }
196
197 swapper = currentCluster;
198 currentCluster = nextCluster;
199 nextCluster = swapper;
200 }
201
202 // provide last vertex in cluster
203
204 if (0 != currentCluster[BINARY_CLUSTER_LENGTH - 1]) {
205 return currentCluster[BINARY_CLUSTER_LENGTH - 1];
206 } else {
207 return Graph_protrudeCluster(this->graph, currentCluster[BINARY_CLUSTER_LENGTH - 2], error);
208 }
209}
210
211unsigned int Binary_readCode(struct Binary *this, unsigned int code, int *error)
212{
213 unsigned int output = 0;
214
215 unsigned int buffer[BINARY_CLUSTER_LENGTH];
216 unsigned int *cluster = buffer;
217
218 Graph_readCluster(this->graph, code, BINARY_CLUSTER_LENGTH, cluster, error); // reverse order
219
220 if (*error) {
221 return 0;
222 }
223 unsigned int first = cluster[1];
224 unsigned int second = cluster[2];
225 unsigned int swapper = 0;
226
227 while (1) {
228
229 unsigned int zeroSource = Graph_readLastSource(this->graph, first, error);
230
231 if (*error) {
232 return 0;
233 }
234
235 if (zeroSource == this->root) { // finish
236
237 if (first == this->one) {
238 output++;
239 }
240
241 return output;
242 }
243
244 cluster[BINARY_CLUSTER_LENGTH - 1] = 0;
245 Graph_readCluster(this->graph, zeroSource, BINARY_CLUSTER_LENGTH, cluster, error); // order unknown
246
247 if (*error) {
248 return 0;
249 }
250
251 if (0 == cluster[BINARY_CLUSTER_LENGTH - 1]) { // two vertices
252 first = cluster[0];
253 second = cluster[1];
254 } else { // three vertices
255 if (cluster[2] < cluster[0]) { // bound to one
256 first = cluster[0];
257 second = cluster[2];
258 } else { // bound to zero
259 first = cluster[0];
260 second = cluster[1];
261 }
262 }
263
264 if (first > second) {
265 output++;
266 output = output << 1;
267 } else {
268 output = output << 1;
269 }
270
271 if (first > second) {
272 swapper = first;
273 first = second;
274 second = swapper;
275 }
276 }
277}
unsigned int Binary_writeCode(struct Binary *this, unsigned int input, int *error)
It writes binary value from an unsigned integer into a graph.
Definition Binary.c:96
struct Binary * Binary_destruct(struct Binary *this)
Definition Binary.c:87
#define BINARY_BITS_IN_INT
Definition Binary.c:25
unsigned int Binary_readCode(struct Binary *this, unsigned int code, int *error)
It reads binary value into an unsigned integer when given a vertex from a binary cluster.
Definition Binary.c:211
struct Binary * Binary_construct(unsigned int root, struct Graph *graph, int *error)
ssssw
Definition Binary.c:42
#define BINARY_CLUSTER_LENGTH
Definition Binary.c:24
void Graph_addEdge(struct Graph *this, unsigned int source, unsigned int target, int *error)
It adds a directed edge from a source vertex to a target vertex.
Definition Graph.c:298
unsigned int Graph_protrudeCluster(struct Graph *this, unsigned int predecessor, int *error)
Definition Graph.c:824
unsigned int Graph_readLastTarget(const struct Graph *this, unsigned int source, int *error)
It reads the last target vertex of a source vertex, if it exists.
Definition Graph.c:712
unsigned int Graph_readLastSource(const struct Graph *this, unsigned int target, int *error)
It reads the last source vertex of a target vertex, if it exists.
Definition Graph.c:680
void Graph_readCluster(const struct Graph *this, unsigned int predecessor, unsigned int length, unsigned int *vertices, int *error)
Definition Graph.c:776
void Graph_addCluster(struct Graph *this, unsigned int length, unsigned int *vertices, int *error)
Definition Graph.c:744
#define ERROR_NO_MEMORY
Definition errors.h:5
unsigned int one
Definition Binary.c:30
unsigned int root
Definition Binary.c:28
struct Graph * graph
Definition Binary.c:31
unsigned int zero
Definition Binary.c:29
Definition Graph.c:20