Statistics
| Branch: | Revision:

grapes / som / TopologyManager / nccache.c @ 8ab58ec7

History | View | Annotate | Download (3.87 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see lgpl-2.1.txt
5
 */
6

    
7
#include <stdint.h>
8
#include <stdlib.h>
9
#include <string.h>
10

    
11
#include <stdio.h>
12

    
13
#include "net_helper.h"
14
#include "nccache.h"
15

    
16
#define MAX_PEERS 50
17
struct cache_entry {
18
  struct nodeID *id;
19
  uint64_t timestamp;
20
};
21

    
22
struct nodeID *nodeid(const struct cache_entry *c, int i)
23
{
24
  if (c[i].timestamp == 0) {
25
    return NULL;
26
  }
27

    
28
  //fprintf(stderr, "Returning ID for TS=%lld: %p\n", c[i].timestamp, c[i].id);
29

    
30
  return c[i].id;
31
}
32

    
33
int cache_add(struct cache_entry *c, struct nodeID *neighbour)
34
{
35
  int i;
36

    
37
  for (i = 0; c[i].timestamp != 0; i++);
38
  c[i].id = nodeid_dup(neighbour);
39
  c[i++].timestamp = 1;
40
  c[i].timestamp = 0;
41
  
42
  return i;
43
}
44

    
45
int cache_del(struct cache_entry *c, struct nodeID *neighbour)
46
{
47
  int i;
48
  int found = 0;
49

    
50
  for (i = 0; c[i].timestamp != 0; i++) {
51
    if (nodeid_equal(c[i].id, neighbour)) {
52
      found = 1;
53
    }
54
    if (found) {
55
      c[i] = c[i+1];
56
    }
57
  }
58

    
59
  return i;
60
}
61

    
62
void cache_update(struct cache_entry *c)
63
{
64
  int i;
65
  
66
  for (i = 0; c[i].timestamp != 0; i++) {
67
      c[i].timestamp++;
68
  }
69
}
70

    
71
struct cache_entry *cache_init(int n)
72
{
73
  struct cache_entry *res;
74

    
75
  res = malloc(sizeof(struct cache_entry) * n);
76
  if (res) {
77
    memset(res, 0, sizeof(struct cache_entry) * n);
78
  }
79

    
80
  return res;
81
}
82

    
83
void cache_free(struct cache_entry *c)
84
{
85
  int i;
86

    
87
  for (i = 0; c[i].timestamp != 0; i++) {
88
    free(c[i].id);
89
  }
90
  free(c);
91
}
92

    
93
int fill_cache_entry(struct cache_entry *c, const struct nodeID *s)
94
{
95
  c->id = nodeid_dup(s);
96
  c->timestamp = 1;
97
#warning Timestamps are probably wrong...
98
  return 1;
99
}
100

    
101
int in_cache(const struct cache_entry *c, const struct cache_entry *elem)
102
{
103
  int i;
104

    
105
  for (i = 0; c[i].timestamp != 0; i++) {
106
    if (nodeid_equal(c[i].id, elem->id)) {
107
      return 1;
108
    }
109
  }
110

    
111
  return 0;
112
}
113

    
114
struct nodeID *rand_peer(struct cache_entry *c)
115
{
116
  int i, j;
117

    
118
  for (i = 0; c[i].timestamp != 0; i++);
119
  if (i == 0) {
120
    return NULL;
121
  }
122
  j = ((double)rand() / (double)RAND_MAX) * i;
123

    
124
  return c[j].id;
125
}
126

    
127
struct cache_entry *entries_undump(const uint8_t *buff, int size)
128
{
129
  struct cache_entry *res;
130
  int i = 0;
131
  const uint8_t *p = buff;
132
  
133
  res = malloc(sizeof(struct cache_entry) * MAX_PEERS);
134
  memset(res, 0, sizeof(struct cache_entry) * MAX_PEERS);
135
  while (p - buff < size) {
136
    int len;
137

    
138
    memcpy(&res[i].timestamp, p, sizeof(uint64_t));
139
    p += sizeof(uint64_t);
140
    res[i++].id = nodeid_undump(p, &len);
141
    p += len;
142
  }
143
if (p - buff != size) { fprintf(stderr, "Waz!! %d != %d\n", p - buff, size); exit(-1);}
144

    
145
  return res;
146
}
147

    
148
int entry_dump(uint8_t *b, struct cache_entry *e, int i)
149
{
150
  int res;
151
  
152
  res = sizeof(uint64_t);
153
  memcpy(b, &e[i].timestamp, sizeof(uint64_t));
154
  res += nodeid_dump(b + res, e[i].id);
155

    
156
  return res;
157
}
158

    
159
struct cache_entry *merge_caches(struct cache_entry *c1, struct cache_entry *c2, int cache_size)
160
{
161
  int i, n1, n2;
162
  struct cache_entry *new_cache;
163

    
164
  new_cache = malloc(sizeof(struct cache_entry) * cache_size);
165
  if (new_cache == NULL) {
166
    return NULL;
167
  }
168
  memset(new_cache, 0, sizeof(struct cache_entry) * cache_size);
169

    
170
  for (i = 0, n1 = 0, n2 = 0; i < cache_size;) {
171
    if ((c1[n1].timestamp == 0) && (c2[n2].timestamp == 0)) {
172
      return new_cache;
173
    }
174
    if (c1[n1].timestamp == 0) {
175
      if (!in_cache(new_cache, &c2[n2])) {
176
        new_cache[i++] = c2[n2];
177
        c2[n2].id = NULL;
178
      }
179
      n2++;
180
    } else if (c2[n2].timestamp == 0) {
181
      if (!in_cache(new_cache, &c1[n1])) {
182
        new_cache[i++] = c1[n1];
183
        c1[n1].id = NULL;
184
      }
185
      n1++;
186
    } else {
187
      if (c2[n2].timestamp > c1[n1].timestamp) {
188
        if (!in_cache(new_cache, &c1[n1])) {
189
          new_cache[i++] = c1[n1];
190
          c1[n1].id = NULL;
191
        }
192
        n1++;
193
      } else {
194
        if (!in_cache(new_cache, &c2[n2])) {
195
          new_cache[i++] = c2[n2];
196
          c2[n2].id = NULL;
197
        }
198
        n2++;
199
      }
200
    }
201
  }
202

    
203
  return new_cache;
204
}