Statistics
| Branch: | Revision:

grapes / src / PeerSet / peerset_ops.c @ 9c3d2b9e

History | View | Annotate | Download (3.69 KB)

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

    
8
#include <stdlib.h>
9
#include <stdint.h>
10
#include <string.h>
11
#include <limits.h>
12

    
13
#include "peerset_private.h"
14
#include "peer.h"
15
#include "peerset.h"
16
#include "chunkidset.h"
17
#include "net_helper.h"
18
#include "config.h"
19

    
20
#define DEFAULT_SIZE_INCREMENT 32
21

    
22
struct nodeID;
23

    
24
struct peerset *peerset_init(const char *config)
25
{
26
  struct peerset *p;
27
  struct tag *cfg_tags;
28
  int res;
29

    
30
  p = malloc(sizeof(struct peerset));
31
  if (p == NULL) {
32
    return NULL;
33
  }
34
  p->n_elements = 0;
35
  cfg_tags = config_parse(config);
36
  if (!cfg_tags) {
37
    free(p);
38
    return NULL;
39
  }
40
  res = config_value_int(cfg_tags, "size", &p->size);
41
  if (!res) {
42
    p->size = 0;
43
  }
44
  free(cfg_tags);
45
  if (p->size) {
46
    p->elements = malloc(p->size * sizeof(struct peer));
47
  } else {
48
    p->elements = NULL;
49
  }
50

    
51
  return p;
52
}
53

    
54
static int peerset_check_insert_pos(const struct peerset *h, const struct nodeID *id);
55

    
56
int peerset_add_peer(struct peerset *h, struct nodeID *id)
57
{
58
  struct peer *e;
59
  int pos;
60

    
61
  pos = peerset_check_insert_pos(h, id);
62
  if (pos < 0){
63
    return 0;
64
  }
65

    
66
  if (h->n_elements == h->size) {
67
    int *res;
68

    
69
    res = realloc(h->elements, (h->size + DEFAULT_SIZE_INCREMENT) * sizeof(struct peer));
70
    if (res == NULL) {
71
      return -1;
72
    }
73
    h->size += DEFAULT_SIZE_INCREMENT;
74
    h->elements = (struct peer*) res;
75
  }
76

    
77
  memmove(&h->elements[pos + 1], &h->elements[pos] , ((h->n_elements++) - pos) * sizeof(struct peer));
78

    
79
  e = &(h->elements[pos]);
80
  e->id = nodeid_dup(id);
81
  gettimeofday(&e->creation_timestamp,NULL);
82
  e->bmap = chunkID_set_init("type=bitmap");
83
  timerclear(&e->bmap_timestamp);
84
  e->cb_size = INT_MAX;
85

    
86
  return h->n_elements;
87
}
88

    
89
void peerset_add_peers(struct peerset *h, struct nodeID **ids, int n)
90
{
91
  int i;
92

    
93
  for (i = 0; i < n; i++) {
94
    peerset_add_peer(h, ids[i]);
95
  }
96
}
97

    
98
int peerset_size(const struct peerset *h)
99
{
100
  return h->n_elements;
101
}
102

    
103
struct peer* peerset_get_peers(const struct peerset *h)
104
{
105
  return h->elements;
106
}
107

    
108
struct peer *peerset_get_peer(const struct peerset *h, const struct nodeID *id)
109
{
110
  int i = peerset_check(h,id);
111
  return (i<0) ? NULL : &(h->elements[i]);
112
}
113

    
114
int peerset_remove_peer(struct peerset *h, const struct nodeID *id){
115
  int i = peerset_check(h,id);
116
  if (i >= 0) {
117
    struct peer *e = h->elements + i;
118
    nodeid_free(e->id);
119
    chunkID_set_free(e->bmap);
120
    memmove(e, e + 1, ((h->n_elements--) - (i+1)) * sizeof(struct peer));
121
    return i;
122
  }
123
  return -1;
124
}
125

    
126
static int nodeid_peer_cmp(const void *id, const void *peer)
127
{
128
  return nodeid_cmp( (const struct nodeID *) id, ((const struct peer *) peer)->id);
129
}
130

    
131
int peerset_check(const struct peerset *h, const struct nodeID *id)
132
{
133
  struct peer *p;
134

    
135
  p = bsearch(id, h->elements, (size_t) h->n_elements, sizeof(h->elements[0]), nodeid_peer_cmp);
136

    
137
  return p ? p - h->elements : -1;
138
}
139

    
140
static int peerset_check_insert_pos(const struct peerset *h, const struct nodeID *id)
141
{
142
  int a, b, c, r;
143

    
144
  if (! h->n_elements) {
145
    return 0;
146
  }
147

    
148
  a = 0;
149
  b = c = h->n_elements - 1;
150

    
151
  while ((r = nodeid_peer_cmp(id, &h->elements[b])) != 0) {
152
    if (r > 0) {
153
      if (b == c) {
154
        return b + 1;
155
      } else {
156
        a = b + 1;
157
      }
158
    } else {
159
      if (b == a) {
160
        return b;
161
      } else {
162
        c = b;
163
      }
164
    }
165
    b = (a + c) / 2;
166
  }
167

    
168
  return -1;
169
}
170

    
171
void peerset_clear(struct peerset *h, int size)
172
{
173
  int i;
174

    
175
  for (i = 0; i < h->n_elements; i++) {
176
    struct peer *e = h->elements + i;
177
    nodeid_free(e->id);
178
    chunkID_set_free(e->bmap);
179
  }
180

    
181
  h->n_elements = 0;
182
  h->size = size;
183
  h->elements = realloc(h->elements, size * sizeof(struct peer));
184
  if (h->elements == NULL) {
185
    h->size = 0;
186
  }
187
}