Statistics
| Branch: | Revision:

grapes / src / Cache / topocache.c @ 505990dd

History | View | Annotate | Download (14.7 KB)

1 8ab58ec7 Luca Abeni
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see lgpl-2.1.txt
5
 */
6
7 480921a6 Luca Abeni
#include <stdint.h>
8
#include <stdlib.h>
9
#include <string.h>
10
11
#include <stdio.h>
12 53f45580 Luca Abeni
#undef NDEBUG
13
#include <assert.h>
14 480921a6 Luca Abeni
15 155319cd Luca Abeni
#include "net_helper.h"
16 faa3a9c7 Luca Abeni
#include "topocache.h"
17 92775ce4 Luca Abeni
#include "int_coding.h"
18 480921a6 Luca Abeni
19
struct cache_entry {
20 651ed37d Luca
  struct nodeID *id;
21 c82982d7 Luca Abeni
  uint32_t timestamp;
22 480921a6 Luca Abeni
};
23
24 11485577 Luca Abeni
struct peer_cache {
25
  struct cache_entry *entries;
26
  int cache_size;
27
  int current_size;
28
  int metadata_size;
29 18d83f26 Luca Abeni
  uint8_t *metadata;
30
  int max_timestamp;
31 11485577 Luca Abeni
};
32
33 194ec532 Luca Abeni
static int cache_insert(struct peer_cache *c, struct cache_entry *e, const void *meta)
34
{
35
  int i, position;
36
37
  if (c->current_size == c->cache_size) {
38
    return -2;
39
  }
40 8738ac23 Andrea Zito
  position = 0;
41 194ec532 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
42 53f45580 Luca Abeni
    assert(e->id);
43
    assert(c->entries[i].id);
44 8738ac23 Andrea Zito
    if (c->entries[i].timestamp <= e->timestamp) {
45
      position = i + 1;
46
    }
47 c7658011 Luca Abeni
    if (nodeid_equal(e->id, c->entries[i].id)) {
48
      if (c->entries[i].timestamp > e->timestamp) {
49
        assert(i >= position);
50
        nodeid_free(c->entries[i].id);
51
        c->entries[i] = *e;
52
        memcpy(c->metadata + i * c->metadata_size, meta, c->metadata_size);
53 505990dd Luca Abeni
        if (position != i) {
54
          memmove(c->entries + position + 1, c->entries + position, sizeof(struct cache_entry) * (i - position));
55
          memmove(c->metadata + (position + 1) * c->metadata_size, c->metadata + position * c->metadata_size, (i -position) * c->metadata_size);
56
        }
57 c7658011 Luca Abeni
58
        return position;
59
      }
60
61
      return -1;
62
    }
63 194ec532 Luca Abeni
  }
64
65 a3538f58 Andrea Zito
  if (position != c->current_size) {
66
    memmove(c->entries + position + 1, c->entries + position, sizeof(struct cache_entry) * (c->current_size - position));
67
    memmove(c->metadata + (position + 1) * c->metadata_size, c->metadata + position * c->metadata_size, (c->current_size - position) * c->metadata_size);
68
  }
69 194ec532 Luca Abeni
  c->current_size++;
70
  c->entries[position] = *e;
71
  memcpy(c->metadata + position * c->metadata_size, meta, c->metadata_size);
72
73
  return position;
74
}
75
76 11485577 Luca Abeni
struct nodeID *nodeid(const struct peer_cache *c, int i)
77 480921a6 Luca Abeni
{
78 11485577 Luca Abeni
  if (i < c->current_size) {
79
    return c->entries[i].id;
80 480921a6 Luca Abeni
  }
81
82 11485577 Luca Abeni
  return NULL;
83 480921a6 Luca Abeni
}
84
85 fe701696 Luca
const void *get_metadata(const struct peer_cache *c, int *size)
86
{
87
  *size = c->metadata_size;
88
  return c->metadata;
89
}
90
91 b3878656 Luca Abeni
int cache_metadata_update(struct peer_cache *c, const struct nodeID *p, const void *meta, int meta_size)
92 90cea048 Luca
{
93
  int i;
94
95
  if (!meta_size || meta_size != c->metadata_size) {
96
    return -3;
97
  }
98
  for (i = 0; i < c->current_size; i++) {
99
    if (nodeid_equal(c->entries[i].id, p)) {
100
      memcpy(c->metadata + i * meta_size, meta, meta_size);
101
      return 1;
102
    }
103
  }
104
105
  return 0;
106
}
107
108 d74d9d89 Luca Abeni
int cache_add_ranked(struct peer_cache *c, struct nodeID *neighbour, const void *meta, int meta_size, ranking_function f, const void *tmeta)
109 480921a6 Luca Abeni
{
110 315d210f Luca Abeni
  int i, pos = 0;
111 480921a6 Luca Abeni
112 c38d0f2c Luca
  if (meta_size && meta_size != c->metadata_size) {
113 886456d7 Luca
    return -3;
114
  }
115 11485577 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
116
    if (nodeid_equal(c->entries[i].id, neighbour)) {
117 44dde345 Marco Biazzini
      if (f != NULL) {
118 5cf5fe25 Marco Biazzini
        cache_del(c,neighbour);
119 44dde345 Marco Biazzini
        if (i == c->current_size) break;
120 86254c5e Marco Biazzini
      } else {
121
          cache_metadata_update(c,neighbour,meta,meta_size);
122
          return -1;
123
      }
124 36b460c1 Csaba Kiraly
    }
125 315d210f Luca Abeni
    if ((f != NULL) && f(tmeta, meta, c->metadata+(c->metadata_size * i)) == 2) {
126 393aa781 Luca Abeni
      pos++;
127
    }
128 11485577 Luca Abeni
  }
129 44dde345 Marco Biazzini
  if (c->current_size == c->cache_size) {
130
    return -2;
131
  }
132 d87ac3b7 Marco Biazzini
  if (c->metadata_size) {
133
    memmove(c->metadata + (pos + 1) * c->metadata_size, c->metadata + pos * c->metadata_size, (c->current_size - pos) * c->metadata_size);
134
    if (meta_size) {
135 45505894 Marco Biazzini
      memcpy(c->metadata + pos * c->metadata_size, meta, meta_size);
136 d87ac3b7 Marco Biazzini
    } else {
137
      memset(c->metadata + pos * c->metadata_size, 0, c->metadata_size);
138
    }
139 886456d7 Luca
  }
140 374c45bb Luca
  for (i = c->current_size; i > pos; i--) {
141 a4d92a6c Luca Abeni
    c->entries[i] = c->entries[i - 1];
142 2bece9a3 Luca
  }
143 393aa781 Luca Abeni
  c->entries[pos].id = nodeid_dup(neighbour);
144
  c->entries[pos].timestamp = 1;
145 2bece9a3 Luca
  c->current_size++;
146 11485577 Luca Abeni
147
  return c->current_size;
148 480921a6 Luca Abeni
}
149
150 393aa781 Luca Abeni
int cache_add(struct peer_cache *c, struct nodeID *neighbour, const void *meta, int meta_size)
151
{
152
  return cache_add_ranked(c, neighbour, meta, meta_size, NULL, NULL);
153
}
154
155 b3878656 Luca Abeni
int cache_del(struct peer_cache *c, const struct nodeID *neighbour)
156 480921a6 Luca Abeni
{
157
  int i;
158
  int found = 0;
159
160 11485577 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
161
    if (nodeid_equal(c->entries[i].id, neighbour)) {
162
      nodeid_free(c->entries[i].id);
163
      c->current_size--;
164 480921a6 Luca Abeni
      found = 1;
165 255b9b59 Luca Abeni
      if (c->metadata_size && (i < c->current_size)) {
166
        memmove(c->metadata + c->metadata_size * i,
167 8719625f Luca Abeni
                c->metadata + c->metadata_size * (i + 1),
168 255b9b59 Luca Abeni
                c->metadata_size * (c->current_size - i));
169
      }
170 480921a6 Luca Abeni
    }
171 bf702aab Luca
    if (found && (i < c->current_size)) {
172
      c->entries[i] = c->entries[i + 1];
173 480921a6 Luca Abeni
    }
174
  }
175
176 11485577 Luca Abeni
  return c->current_size;
177 480921a6 Luca Abeni
}
178
179 f601563a Luca Abeni
void cache_update(struct peer_cache *c)
180 480921a6 Luca Abeni
{
181
  int i;
182
  
183 11485577 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
184 18d83f26 Luca Abeni
    if (c->max_timestamp && (c->entries[i].timestamp == c->max_timestamp)) {
185 f7520461 Marco Biazzini
      int j = i;
186
187
      while(j < c->current_size && c->entries[j].id) {
188
        nodeid_free(c->entries[j].id);
189
        c->entries[j++].id = NULL;
190
      }
191 d86ef3d5 CsabaKiraly
      c->current_size = i;        /* The cache is ordered by timestamp...
192
                                   all the other entries wiil be older than
193
                                   this one, so remove all of them
194
                                */
195
    } else {
196
      c->entries[i].timestamp++;
197
    }
198 480921a6 Luca Abeni
  }
199
}
200
201 18d83f26 Luca Abeni
struct peer_cache *cache_init(int n, int metadata_size, int max_timestamp)
202 480921a6 Luca Abeni
{
203 11485577 Luca Abeni
  struct peer_cache *res;
204
205
  res = malloc(sizeof(struct peer_cache));
206
  if (res == NULL) {
207
    return NULL;
208
  }
209 18d83f26 Luca Abeni
  res->max_timestamp = max_timestamp;
210 11485577 Luca Abeni
  res->cache_size = n;
211
  res->current_size = 0;
212
  res->entries = malloc(sizeof(struct cache_entry) * n);
213 35f870f1 Luca Abeni
  if (res->entries == NULL) {
214 11485577 Luca Abeni
    free(res);
215 480921a6 Luca Abeni
216 11485577 Luca Abeni
    return NULL;
217 480921a6 Luca Abeni
  }
218 11485577 Luca Abeni
  
219
  memset(res->entries, 0, sizeof(struct cache_entry) * n);
220 886456d7 Luca
  if (metadata_size) {
221
    res->metadata = malloc(metadata_size * n);
222
  } else {
223
    res->metadata = NULL;
224
  }
225
226
  if (res->metadata) {
227
    res->metadata_size = metadata_size;
228
    memset(res->metadata, 0, metadata_size * n);
229
  } else {
230
    res->metadata_size = 0;
231
  }
232 480921a6 Luca Abeni
233
  return res;
234
}
235
236 11485577 Luca Abeni
void cache_free(struct peer_cache *c)
237 6ee18244 Luca
{
238
  int i;
239
240 11485577 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
241 5adcd1d8 Luca Abeni
    if(c->entries[i].id) {
242
      nodeid_free(c->entries[i].id);
243
    }
244 6ee18244 Luca
  }
245 11485577 Luca Abeni
  free(c->entries);
246 886456d7 Luca
  free(c->metadata);
247 6ee18244 Luca
  free(c);
248
}
249
250 b81d3f0f Luca
static int in_cache(const struct peer_cache *c, const struct cache_entry *elem)
251 480921a6 Luca Abeni
{
252
  int i;
253
254 11485577 Luca Abeni
  for (i = 0; i < c->current_size; i++) {
255
    if (nodeid_equal(c->entries[i].id, elem->id)) {
256 9e444611 Marco Biazzini
      return i;
257 480921a6 Luca Abeni
    }
258
  }
259
260 9e444611 Marco Biazzini
  return -1;
261 480921a6 Luca Abeni
}
262
263 a166dc0b Luca Abeni
struct nodeID *rand_peer(const struct peer_cache *c, void **meta, int max)
264 480921a6 Luca Abeni
{
265 11485577 Luca Abeni
  int j;
266 480921a6 Luca Abeni
267 11485577 Luca Abeni
  if (c->current_size == 0) {
268 480921a6 Luca Abeni
    return NULL;
269
  }
270 b95a5127 Marco Biazzini
  if (!max || max >= c->current_size)
271
    max = c->current_size;
272
  else
273
    ++max;
274
  j = ((double)rand() / (double)RAND_MAX) * max;
275 480921a6 Luca Abeni
276 29ab6bd0 Luca Abeni
  if (meta) {
277 df98cd3a Luca Abeni
    *meta = c->metadata + (j * c->metadata_size);
278
  }
279
280 11485577 Luca Abeni
  return c->entries[j].id;
281 480921a6 Luca Abeni
}
282
283 a166dc0b Luca Abeni
struct nodeID *last_peer(const struct peer_cache *c)
284 194ec532 Luca Abeni
{
285
  if (c->current_size == 0) {
286
    return NULL;
287
  }
288
289
  return c->entries[c->current_size - 1].id;
290
}
291
292
struct peer_cache *rand_cache(struct peer_cache *c, int n)
293
{
294
  struct peer_cache *res;
295
296
cache_check(c);
297
  if (c->current_size < n) {
298
    n = c->current_size;
299
  }
300
  res = cache_init(n, c->metadata_size, c->max_timestamp);
301
302
  while(res->current_size < n) {
303
    int j;
304
305
    j = ((double)rand() / (double)RAND_MAX) * c->current_size;
306
    cache_insert(res, c->entries + j, c->metadata + c->metadata_size * j);
307
    c->current_size--;
308
    memmove(c->entries + j, c->entries + j + 1, sizeof(struct cache_entry) * (c->current_size - j));
309
    memmove(c->metadata + c->metadata_size * j, c->metadata + c->metadata_size * (j + 1), c->metadata_size * (c->current_size - j));
310
    c->entries[c->current_size].id = NULL;
311
cache_check(c);
312
  }
313
314
  return res;
315
}
316
317 11485577 Luca Abeni
struct peer_cache *entries_undump(const uint8_t *buff, int size)
318 480921a6 Luca Abeni
{
319 11485577 Luca Abeni
  struct peer_cache *res;
320 480921a6 Luca Abeni
  int i = 0;
321
  const uint8_t *p = buff;
322 886456d7 Luca
  uint8_t *meta;
323
  int cache_size, metadata_size;
324 11485577 Luca Abeni
325
  cache_size = int_rcpy(buff);
326 886456d7 Luca
  metadata_size = int_rcpy(buff + 4);
327
  p = buff + 8;
328 18d83f26 Luca Abeni
  res = cache_init(cache_size, metadata_size, 0);
329 886456d7 Luca
  meta = res->metadata;
330 480921a6 Luca Abeni
  while (p - buff < size) {
331
    int len;
332
333 11485577 Luca Abeni
    res->entries[i].timestamp = int_rcpy(p);
334 c82982d7 Luca Abeni
    p += sizeof(uint32_t);
335 11485577 Luca Abeni
    res->entries[i++].id = nodeid_undump(p, &len);
336 480921a6 Luca Abeni
    p += len;
337 886456d7 Luca
    if (metadata_size) {
338
      memcpy(meta, p, metadata_size);
339
      p += metadata_size;
340
      meta += metadata_size;
341
    }
342 480921a6 Luca Abeni
  }
343 11485577 Luca Abeni
  res->current_size = i;
344 53f45580 Luca Abeni
  assert(p - buff == size);
345 480921a6 Luca Abeni
346
  return res;
347
}
348
349 1a101c0b Luca Abeni
int cache_header_dump(uint8_t *b, const struct peer_cache *c, int include_me)
350 480921a6 Luca Abeni
{
351 1a101c0b Luca Abeni
  int_cpy(b, c->cache_size + (include_me ? 1 : 0));
352 886456d7 Luca
  int_cpy(b + 4, c->metadata_size);
353 c82982d7 Luca Abeni
354 886456d7 Luca
  return 8;
355 11485577 Luca Abeni
}
356 886456d7 Luca
357 a166dc0b Luca Abeni
int entry_dump(uint8_t *b, const struct peer_cache *c, int i, size_t max_write_size)
358 11485577 Luca Abeni
{
359
  int res;
360 20903c9c Csaba Kiraly
  int size = 0;
361 5adcd1d8 Luca Abeni
 
362
  if (i && (i >= c->cache_size - 1)) {
363
    return 0;
364
  }
365 11485577 Luca Abeni
  int_cpy(b, c->entries[i].timestamp);
366 20903c9c Csaba Kiraly
  size = +4;
367
  res = nodeid_dump(b + size, c->entries[i].id, max_write_size - size);
368
  if (res < 0 ) {
369
    return -1;
370
  }
371
  size += res;
372 886456d7 Luca
  if (c->metadata_size) {
373 20903c9c Csaba Kiraly
    if (c->metadata_size > max_write_size - size) {
374
      return -1;
375
    }
376
    memcpy(b + size, c->metadata + c->metadata_size * i, c->metadata_size);
377
    size += c->metadata_size;
378 886456d7 Luca
  }
379 480921a6 Luca Abeni
380 20903c9c Csaba Kiraly
  return size;
381 480921a6 Luca Abeni
}
382
383 973fb1fd Marco Biazzini
struct peer_cache *cache_rank (const struct peer_cache *c, ranking_function rank, const struct nodeID *target, const void *target_meta)
384
{
385 2edb3e55 Luca Abeni
  struct peer_cache *res;
386
  int i,j,pos;
387
388
  res = cache_init(c->cache_size, c->metadata_size, c->max_timestamp);
389
  if (res == NULL) {
390
    return res;
391
  }
392
393
  for (i = 0; i < c->current_size; i++) {
394
    if (!target || !nodeid_equal(c->entries[i].id,target)) {
395
      pos = 0;
396
      for (j=0; j<res->current_size;j++) {
397
        if (((rank != NULL) && rank(target_meta, c->metadata+(c->metadata_size * i), res->metadata+(res->metadata_size * j)) == 2) ||
398
            ((rank == NULL) && res->entries[j].timestamp < c->entries[i].timestamp)) {
399
          pos++;
400
        }
401
      }
402
      if (c->metadata_size) {
403
        memmove(res->metadata + (pos + 1) * res->metadata_size, res->metadata + pos * res->metadata_size, (res->current_size - pos) * res->metadata_size);
404
        memcpy(res->metadata + pos * res->metadata_size, c->metadata+(c->metadata_size * i), res->metadata_size);
405
      }
406
      for (j = res->current_size; j > pos; j--) {
407
        res->entries[j] = res->entries[j - 1];
408
      }
409
      res->entries[pos].id = nodeid_dup(c->entries[i].id);
410
      res->entries[pos].timestamp = c->entries[i].timestamp;
411
      res->current_size++;
412
    }
413
  }
414
415
  return res;
416 973fb1fd Marco Biazzini
}
417
418 a166dc0b Luca Abeni
struct peer_cache *cache_union(const struct peer_cache *c1, const struct peer_cache *c2, int *size)
419 2edb3e55 Luca Abeni
{
420
  int n, pos;
421
  struct peer_cache *new_cache;
422
  uint8_t *meta;
423
424
  if (c1->metadata_size != c2->metadata_size) {
425
    return NULL;
426
  }
427
428
  new_cache = cache_init(c1->current_size + c2->current_size, c1->metadata_size, c1->max_timestamp);
429
  if (new_cache == NULL) {
430
    return NULL;
431
  }
432
433
  meta = new_cache->metadata;
434
435
  for (n = 0; n < c1->current_size; n++) {
436
    if (new_cache->metadata_size) {
437
      memcpy(meta, c1->metadata + n * c1->metadata_size, c1->metadata_size);
438
      meta += new_cache->metadata_size;
439
    }
440
    new_cache->entries[new_cache->current_size++] = c1->entries[n];
441
    c1->entries[n].id = NULL;
442
  }
443 6f80ff91 Marco Biazzini
  
444 2edb3e55 Luca Abeni
  for (n = 0; n < c2->current_size; n++) {
445
    pos = in_cache(new_cache, &c2->entries[n]);
446
    if (pos >= 0 && new_cache->entries[pos].timestamp > c2->entries[n].timestamp) {
447
      cache_metadata_update(new_cache, c2->entries[n].id, c2->metadata + n * c2->metadata_size, c2->metadata_size);
448
      new_cache->entries[pos].timestamp = c2->entries[n].timestamp;
449
    }
450
    if (pos < 0) {
451
      if (new_cache->metadata_size) {
452
        memcpy(meta, c2->metadata + n * c2->metadata_size, c2->metadata_size);
453
        meta += new_cache->metadata_size;
454
      }
455
      new_cache->entries[new_cache->current_size++] = c2->entries[n];
456
      c2->entries[n].id = NULL;
457
    }
458
  }
459
  *size = new_cache->current_size;
460 6f80ff91 Marco Biazzini
461 2edb3e55 Luca Abeni
  return new_cache;
462
}
463 6f80ff91 Marco Biazzini
464 2edb3e55 Luca Abeni
int cache_resize (struct peer_cache *c, int size)
465
{
466
  int dif = size - c->cache_size;
467 6f80ff91 Marco Biazzini
468 2edb3e55 Luca Abeni
  if (!dif) {
469
    return c->current_size;
470
  }
471 6f80ff91 Marco Biazzini
472 2edb3e55 Luca Abeni
  c->entries = realloc(c->entries, sizeof(struct cache_entry) * size);
473
  if (dif > 0) {
474
    memset(c->entries + c->cache_size, 0, sizeof(struct cache_entry) * dif);
475
  } else if (c->current_size > size) {
476
    c->current_size = size;
477
  }
478 6f80ff91 Marco Biazzini
479 2edb3e55 Luca Abeni
  if (c->metadata_size) {
480
    c->metadata = realloc(c->metadata, c->metadata_size * size);
481
    if (dif > 0) {
482
      memset(c->metadata + c->metadata_size * c->cache_size, 0, c->metadata_size * dif);
483
    }
484
  }
485 6f80ff91 Marco Biazzini
486 2edb3e55 Luca Abeni
  c->cache_size = size;
487 6f80ff91 Marco Biazzini
488 2edb3e55 Luca Abeni
  return c->current_size;
489 6f80ff91 Marco Biazzini
}
490
  
491 a166dc0b Luca Abeni
struct peer_cache *merge_caches(const struct peer_cache *c1, const struct peer_cache *c2, int newsize, int *source)
492 480921a6 Luca Abeni
{
493 11485577 Luca Abeni
  int n1, n2;
494
  struct peer_cache *new_cache;
495 886456d7 Luca
  uint8_t *meta;
496 480921a6 Luca Abeni
497 18d83f26 Luca Abeni
  new_cache = cache_init(newsize, c1->metadata_size, c1->max_timestamp);
498 480921a6 Luca Abeni
  if (new_cache == NULL) {
499
    return NULL;
500
  }
501
502 886456d7 Luca
  meta = new_cache->metadata;
503 661d190d Luca Abeni
  *source = 0;
504 11485577 Luca Abeni
  for (n1 = 0, n2 = 0; new_cache->current_size < new_cache->cache_size;) {
505
    if ((n1 == c1->current_size) && (n2 == c2->current_size)) {
506 480921a6 Luca Abeni
      return new_cache;
507
    }
508 11485577 Luca Abeni
    if (n1 == c1->current_size) {
509 9e444611 Marco Biazzini
      if (in_cache(new_cache, &c2->entries[n2]) < 0) {
510 886456d7 Luca
        if (new_cache->metadata_size) {
511
          memcpy(meta, c2->metadata + n2 * c2->metadata_size, c2->metadata_size);
512
          meta += new_cache->metadata_size;
513
        }
514 11485577 Luca Abeni
        new_cache->entries[new_cache->current_size++] = c2->entries[n2];
515
        c2->entries[n2].id = NULL;
516 661d190d Luca Abeni
        *source |= 0x02;
517 480921a6 Luca Abeni
      }
518
      n2++;
519 11485577 Luca Abeni
    } else if (n2 == c2->current_size) {
520 9e444611 Marco Biazzini
      if (in_cache(new_cache, &c1->entries[n1]) < 0) {
521 886456d7 Luca
        if (new_cache->metadata_size) {
522
          memcpy(meta, c1->metadata + n1 * c1->metadata_size, c1->metadata_size);
523
          meta += new_cache->metadata_size;
524
        }
525 11485577 Luca Abeni
        new_cache->entries[new_cache->current_size++] = c1->entries[n1];
526
        c1->entries[n1].id = NULL;
527 661d190d Luca Abeni
        *source |= 0x01;
528 480921a6 Luca Abeni
      }
529
      n1++;
530
    } else {
531 eb29e340 Luca
      if (c2->entries[n2].timestamp > c1->entries[n1].timestamp) {
532 9e444611 Marco Biazzini
        if (in_cache(new_cache, &c1->entries[n1]) < 0) {
533 886456d7 Luca
          if (new_cache->metadata_size) {
534
            memcpy(meta, c1->metadata + n1 * c1->metadata_size, c1->metadata_size);
535
            meta += new_cache->metadata_size;
536
          }
537 11485577 Luca Abeni
          new_cache->entries[new_cache->current_size++] = c1->entries[n1];
538
          c1->entries[n1].id = NULL;
539 661d190d Luca Abeni
          *source |= 0x01;
540 480921a6 Luca Abeni
        }
541
        n1++;
542
      } else {
543 9e444611 Marco Biazzini
        if (in_cache(new_cache, &c2->entries[n2]) < 0) {
544 886456d7 Luca
          if (new_cache->metadata_size) {
545
            memcpy(meta, c2->metadata + n2 * c2->metadata_size, c2->metadata_size);
546
            meta += new_cache->metadata_size;
547
          }
548 11485577 Luca Abeni
          new_cache->entries[new_cache->current_size++] = c2->entries[n2];
549
          c2->entries[n2].id = NULL;
550 661d190d Luca Abeni
          *source |= 0x02;
551 480921a6 Luca Abeni
        }
552
        n2++;
553
      }
554
    }
555
  }
556
557
  return new_cache;
558
}
559 194ec532 Luca Abeni
560
void cache_check(const struct peer_cache *c)
561
{
562
  int i, j;
563
564
  for (i = 0; i < c->current_size; i++) {
565
    for (j = i + 1; j < c->current_size; j++) {
566 53f45580 Luca Abeni
      assert(!nodeid_equal(c->entries[i].id, c->entries[j].id));
567 194ec532 Luca Abeni
    }
568
  }
569
}