grapes / som / TopologyManager / nccache.c @ 51317c83
History | View | Annotate | Download (3.79 KB)
1 |
#include <stdint.h> |
---|---|
2 |
#include <stdlib.h> |
3 |
#include <string.h> |
4 |
|
5 |
#include <stdio.h> |
6 |
|
7 |
#include "net_helper.h" |
8 |
#include "nccache.h" |
9 |
|
10 |
#define MAX_PEERS 50 |
11 |
struct cache_entry {
|
12 |
struct nodeID *id;
|
13 |
uint64_t timestamp; |
14 |
}; |
15 |
|
16 |
struct nodeID *nodeid(const struct cache_entry *c, int i) |
17 |
{ |
18 |
if (c[i].timestamp == 0) { |
19 |
return NULL; |
20 |
} |
21 |
|
22 |
//fprintf(stderr, "Returning ID for TS=%lld: %p\n", c[i].timestamp, c[i].id);
|
23 |
|
24 |
return c[i].id;
|
25 |
} |
26 |
|
27 |
int cache_add(struct cache_entry *c, struct nodeID *neighbour) |
28 |
{ |
29 |
int i;
|
30 |
|
31 |
for (i = 0; c[i].timestamp != 0; i++); |
32 |
c[i].id = nodeid_dup(neighbour); |
33 |
c[i++].timestamp = 1;
|
34 |
c[i].timestamp = 0;
|
35 |
|
36 |
return i;
|
37 |
} |
38 |
|
39 |
int cache_del(struct cache_entry *c, struct nodeID *neighbour) |
40 |
{ |
41 |
int i;
|
42 |
int found = 0; |
43 |
|
44 |
for (i = 0; c[i].timestamp != 0; i++) { |
45 |
if (nodeid_equal(c[i].id, neighbour)) {
|
46 |
found = 1;
|
47 |
} |
48 |
if (found) {
|
49 |
c[i] = c[i+1];
|
50 |
} |
51 |
} |
52 |
|
53 |
return i;
|
54 |
} |
55 |
|
56 |
void cache_update(struct cache_entry *c) |
57 |
{ |
58 |
int i;
|
59 |
|
60 |
for (i = 0; c[i].timestamp != 0; i++) { |
61 |
c[i].timestamp++; |
62 |
} |
63 |
} |
64 |
|
65 |
struct cache_entry *cache_init(int n) |
66 |
{ |
67 |
struct cache_entry *res;
|
68 |
|
69 |
res = malloc(sizeof(struct cache_entry) * n); |
70 |
if (res) {
|
71 |
memset(res, 0, sizeof(struct cache_entry) * n); |
72 |
} |
73 |
|
74 |
return res;
|
75 |
} |
76 |
|
77 |
void cache_free(struct cache_entry *c) |
78 |
{ |
79 |
int i;
|
80 |
|
81 |
for (i = 0; c[i].timestamp != 0; i++) { |
82 |
free(c[i].id); |
83 |
} |
84 |
free(c); |
85 |
} |
86 |
|
87 |
int fill_cache_entry(struct cache_entry *c, const struct nodeID *s) |
88 |
{ |
89 |
c->id = nodeid_dup(s); |
90 |
c->timestamp = 1;
|
91 |
#warning Timestamps are probably wrong...
|
92 |
return 1; |
93 |
} |
94 |
|
95 |
int in_cache(const struct cache_entry *c, const struct cache_entry *elem) |
96 |
{ |
97 |
int i;
|
98 |
|
99 |
for (i = 0; c[i].timestamp != 0; i++) { |
100 |
if (nodeid_equal(c[i].id, elem->id)) {
|
101 |
return 1; |
102 |
} |
103 |
} |
104 |
|
105 |
return 0; |
106 |
} |
107 |
|
108 |
struct nodeID *rand_peer(struct cache_entry *c) |
109 |
{ |
110 |
int i, j;
|
111 |
|
112 |
for (i = 0; c[i].timestamp != 0; i++); |
113 |
if (i == 0) { |
114 |
return NULL; |
115 |
} |
116 |
j = ((double)rand() / (double)RAND_MAX) * i; |
117 |
|
118 |
return c[j].id;
|
119 |
} |
120 |
|
121 |
struct cache_entry *entries_undump(const uint8_t *buff, int size) |
122 |
{ |
123 |
struct cache_entry *res;
|
124 |
int i = 0; |
125 |
const uint8_t *p = buff;
|
126 |
|
127 |
res = malloc(sizeof(struct cache_entry) * MAX_PEERS); |
128 |
memset(res, 0, sizeof(struct cache_entry) * MAX_PEERS); |
129 |
while (p - buff < size) {
|
130 |
int len;
|
131 |
|
132 |
memcpy(&res[i].timestamp, p, sizeof(uint64_t));
|
133 |
p += sizeof(uint64_t);
|
134 |
res[i++].id = nodeid_undump(p, &len); |
135 |
p += len; |
136 |
} |
137 |
if (p - buff != size) { fprintf(stderr, "Waz!! %d != %d\n", p - buff, size); exit(-1);} |
138 |
|
139 |
return res;
|
140 |
} |
141 |
|
142 |
int entry_dump(uint8_t *b, struct cache_entry *e, int i) |
143 |
{ |
144 |
int res;
|
145 |
|
146 |
res = sizeof(uint64_t);
|
147 |
memcpy(b, &e[i].timestamp, sizeof(uint64_t));
|
148 |
res += nodeid_dump(b + res, e[i].id); |
149 |
|
150 |
return res;
|
151 |
} |
152 |
|
153 |
struct cache_entry *merge_caches(struct cache_entry *c1, struct cache_entry *c2, int cache_size) |
154 |
{ |
155 |
int i, n1, n2;
|
156 |
struct cache_entry *new_cache;
|
157 |
|
158 |
new_cache = malloc(sizeof(struct cache_entry) * cache_size); |
159 |
if (new_cache == NULL) { |
160 |
return NULL; |
161 |
} |
162 |
memset(new_cache, 0, sizeof(struct cache_entry) * cache_size); |
163 |
|
164 |
for (i = 0, n1 = 0, n2 = 0; i < cache_size;) { |
165 |
if ((c1[n1].timestamp == 0) && (c2[n2].timestamp == 0)) { |
166 |
return new_cache;
|
167 |
} |
168 |
if (c1[n1].timestamp == 0) { |
169 |
if (!in_cache(new_cache, &c2[n2])) {
|
170 |
new_cache[i++] = c2[n2]; |
171 |
c2[n2].id = NULL;
|
172 |
} |
173 |
n2++; |
174 |
} else if (c2[n2].timestamp == 0) { |
175 |
if (!in_cache(new_cache, &c1[n1])) {
|
176 |
new_cache[i++] = c1[n1]; |
177 |
c1[n1].id = NULL;
|
178 |
} |
179 |
n1++; |
180 |
} else {
|
181 |
if (c2[n2].timestamp > c1[n1].timestamp) {
|
182 |
if (!in_cache(new_cache, &c1[n1])) {
|
183 |
new_cache[i++] = c1[n1]; |
184 |
c1[n1].id = NULL;
|
185 |
} |
186 |
n1++; |
187 |
} else {
|
188 |
if (!in_cache(new_cache, &c2[n2])) {
|
189 |
new_cache[i++] = c2[n2]; |
190 |
c2[n2].id = NULL;
|
191 |
} |
192 |
n2++; |
193 |
} |
194 |
} |
195 |
} |
196 |
|
197 |
return new_cache;
|
198 |
} |