Statistics
| Branch: | Revision:

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
}