Statistics
| Branch: | Revision:

grapes / TopologyManager / nccache.c @ e1630aa8

History | View | Annotate | Download (3.85 KB)

1 480921a6 Luca Abeni
#include <stdint.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
#include <stdio.h>
6
7
#include "msglayer.h"
8
#include "nccache.h"
9
10
#define MAX_PEERS 50
11
struct cache_entry {
12
  struct socketID *id;
13
  uint64_t timestamp;
14
};
15
16
struct socketID *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 socketID *neighbour)
28
{
29
  int i;
30
31
  for (i = 0; c->timestamp != 0; i++);
32
  c[i].id = sockid_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 socketID *neighbour)
40
{
41
  int i;
42
  int found = 0;
43
44
  for (i = 0; c->timestamp != 0; i++) {
45
    if (sockid_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
int fill_cache_entry(struct cache_entry *c, const struct socketID *s)
78
{
79
  c->id = sockid_dup(s);
80
  c->timestamp = 1;
81
#warning Timestamps are probably wrong...
82
  return 1;
83
}
84
85
int in_cache(const struct cache_entry *c, const struct cache_entry *elem)
86
{
87
  int i;
88
89
  for (i = 0; c[i].timestamp != 0; i++) {
90
    if (sockid_equal(c[i].id, elem->id)) {
91
      return 1;
92
    }
93
  }
94
95
  return 0;
96
}
97
98
struct socketID *rand_peer(struct cache_entry *c)
99
{
100
  int i, j;
101
102
  for (i = 0; c[i].timestamp != 0; i++);
103
  if (i == 0) {
104
    return NULL;
105
  }
106
  j = ((double)rand() / (double)RAND_MAX) * i;
107
108
  return c[j].id;
109
}
110
111
struct cache_entry *entries_undump(const uint8_t *buff, int size)
112
{
113
  struct cache_entry *res;
114
  int i = 0;
115
  const uint8_t *p = buff;
116
  
117
  res = malloc(sizeof(struct cache_entry) * MAX_PEERS);
118
  memset(res, 0, sizeof(struct cache_entry) * MAX_PEERS);
119
  while (p - buff < size) {
120
    int len;
121
122
    memcpy(&res[i].timestamp, p, sizeof(uint64_t));
123
    p += sizeof(uint64_t);
124
    res[i++].id = sockid_undump(p, &len);
125
    p += len;
126
  }
127
if (p - buff != size) { fprintf(stderr, "Waz!! %d != %d\n", p - buff, size); exit(-1);}
128
129
  return res;
130
}
131
132
int entry_dump(uint8_t *b, struct cache_entry *e, int i)
133
{
134
  int res;
135
  
136
  res = sizeof(uint64_t);
137
  memcpy(b, &e[i].timestamp, sizeof(uint64_t));
138
  res += sockid_dump(b + res, e[i].id);
139
140
  return res;
141
}
142
143
struct cache_entry *merge_caches(const struct cache_entry *c1, const struct cache_entry *c2, int cache_size)
144
{
145
  int i, n1, n2;
146
  struct cache_entry *new_cache;
147
148
  new_cache = malloc(sizeof(struct cache_entry) * cache_size);
149
  if (new_cache == NULL) {
150
    return NULL;
151
  }
152
  memset(new_cache, 0, sizeof(struct cache_entry) * cache_size);
153
154
  for (i = 0, n1 = 0, n2 = 0; i < cache_size;) {
155
    if ((c1[n1].timestamp == 0) && (c2[n2].timestamp == 0)) {
156
      return new_cache;
157
    }
158
    if (c1[n1].timestamp == 0) {
159
      if (!in_cache(new_cache, &c2[n2])) {
160
        new_cache[i++] = c2[n2];
161 e1630aa8 Luca
      } else {
162
        free(c2[n2].id);
163 480921a6 Luca Abeni
      }
164
      n2++;
165
    } else if (c2[n2].timestamp == 0) {
166
      if (!in_cache(new_cache, &c1[n1])) {
167
        new_cache[i++] = c1[n1];
168 e1630aa8 Luca
      } else {
169
        free(c1[n1].id);
170 480921a6 Luca Abeni
      }
171
      n1++;
172
    } else {
173
      if (c2[n2].timestamp > c1[n1].timestamp) {
174
        if (!in_cache(new_cache, &c1[n1])) {
175
          new_cache[i++] = c1[n1];
176 e1630aa8 Luca
        } else {
177
          free(c1[n1].id);
178 480921a6 Luca Abeni
        }
179
        n1++;
180
      } else {
181
        if (!in_cache(new_cache, &c2[n2])) {
182
          new_cache[i++] = c2[n2];
183 e1630aa8 Luca
        } else {
184
          free(c2[n2].id);
185 480921a6 Luca Abeni
        }
186
        n2++;
187
      }
188
    }
189
  }
190
191 e1630aa8 Luca
  while (c1[n1].timestamp != 0) {
192
    free(c1[n1++].id);
193
  }
194
  while (c2[n2].timestamp != 0) {
195
    free(c2[n2++].id);
196
  }
197
198 480921a6 Luca Abeni
  return new_cache;
199
}