Statistics
| Branch: | Revision:

grapes / src / PeerSet / peerset_ops.c @ b79c8e3a

History | View | Annotate | Download (5.1 KB)

1 8ab58ec7 Luca Abeni
/*
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 c139c4f2 CsabaKiraly
#include <stdlib.h>
9 67700aad Luca Baldesi
#include <stdio.h>
10 c139c4f2 CsabaKiraly
#include <stdint.h>
11 9e6eebab Csaba Kiraly
#include <string.h>
12 7180e574 CsabaKiraly
#include <limits.h>
13 c139c4f2 CsabaKiraly
14 47f2affa CsabaKiraly
#include "peerset_private.h"
15
#include "peer.h"
16
#include "peerset.h"
17 fb76785c CsabaKiraly
#include "chunkidset.h"
18 a4f059a8 CsabaKiraly
#include "net_helper.h"
19 176b8de8 Luca Baldesi
#include "grapes_config.h"
20 c139c4f2 CsabaKiraly
21
#define DEFAULT_SIZE_INCREMENT 32
22
23 b79c8e3a Luca Baldesi
void peer_init_data(struct peer *p)
24
{
25
        if (p)
26
        {
27
                p->metadata = NULL;
28
                p->user_data = NULL;
29
        }
30
}
31
32
void peer_deinit_data(struct peer *p)
33
{
34
        if(p && p->metadata)
35
                free(p->metadata);
36
        if(p && p->metadata)
37
                free(p->user_data);
38
}
39
40
peer_deinit_f peer_deinit = peer_deinit_data;
41
peer_init_f peer_init = peer_init_data;
42
43 391fed9c Luca Abeni
static int nodeid_peer_cmp(const void *id, const void *p)
44
{
45
  const struct peer *peer = *(struct peer *const *)p;
46
47 67700aad Luca Baldesi
  if(id && p)
48
    return nodeid_cmp( (const struct nodeID *) id, peer->id);
49
  else
50
  {
51
    //fprintf(stderr,"[DEBUG] wrong peer or id\n");
52
    return 0;
53
  }
54 391fed9c Luca Abeni
}
55
56
static int peerset_check_insert_pos(const struct peerset *h, const struct nodeID *id)
57
{
58
  int a, b, c, r;
59
60
  if (! h->n_elements) {
61
    return 0;
62
  }
63
64
  a = 0;
65
  b = c = h->n_elements - 1;
66
67
  while ((r = nodeid_peer_cmp(id, &h->elements[b])) != 0) {
68
    if (r > 0) {
69
      if (b == c) {
70
        return b + 1;
71
      } else {
72
        a = b + 1;
73
      }
74
    } else {
75
      if (b == a) {
76
        return b;
77
      } else {
78
        c = b;
79
      }
80
    }
81
    b = (a + c) / 2;
82
  }
83
84
  return -1;
85
}
86
87 47f2affa CsabaKiraly
88 04df3b0f Luca
struct peerset *peerset_init(const char *config)
89 c139c4f2 CsabaKiraly
{
90 47f2affa CsabaKiraly
  struct peerset *p;
91 04df3b0f Luca
  struct tag *cfg_tags;
92
  int res;
93 c139c4f2 CsabaKiraly
94 47f2affa CsabaKiraly
  p = malloc(sizeof(struct peerset));
95 c139c4f2 CsabaKiraly
  if (p == NULL) {
96
    return NULL;
97
  }
98
  p->n_elements = 0;
99 176b8de8 Luca Baldesi
  cfg_tags = grapes_config_parse(config);
100 7913b03a Csaba Kiraly
  if (!cfg_tags) {
101
    free(p);
102
    return NULL;
103
  }
104 176b8de8 Luca Baldesi
  res = grapes_config_value_int(cfg_tags, "size", &p->size);
105 3e48a5d3 Csaba Kiraly
  if (!res) {
106 04df3b0f Luca
    p->size = 0;
107
  }
108
  free(cfg_tags);
109 c139c4f2 CsabaKiraly
  if (p->size) {
110 82438fe3 Luca Abeni
    p->elements = malloc(p->size * sizeof(struct peer *));
111 c139c4f2 CsabaKiraly
  } else {
112
    p->elements = NULL;
113
  }
114
115
  return p;
116
}
117
118 41012841 Luca Baldesi
void peerset_destroy(struct peerset **h)
119
{
120
        peerset_clear(*h,0);
121
        free(*h);
122
        *h = NULL;
123
}
124
125 c5922d21 Luca Abeni
int peerset_push_peer(struct peerset *h, struct peer *e)
126 91566cec Luca Baldesi
{
127
  int pos;
128
129
  pos = peerset_check_insert_pos(h, e->id);
130
  if (pos < 0){
131
    return 0;
132
  }
133
134
  if (h->n_elements == h->size) {
135
    struct peer **res;
136
137
    res = realloc(h->elements, (h->size + DEFAULT_SIZE_INCREMENT) * sizeof(struct peer *));
138
    if (res == NULL) {
139
      return -1;
140
    }
141
    h->size += DEFAULT_SIZE_INCREMENT;
142
    h->elements = res;
143
  }
144
145
  memmove(&h->elements[pos + 1], &h->elements[pos] , ((h->n_elements++) - pos) * sizeof(struct peer *));
146
147
  h->elements[pos] = e;;
148
149
  return h->n_elements;
150
}
151
152 fe3ab307 Luca Baldesi
int peerset_add_peer(struct peerset *h,const  struct nodeID *id)
153 c139c4f2 CsabaKiraly
{
154 fb76785c CsabaKiraly
  struct peer *e;
155 ee18ff79 Csaba Kiraly
  int pos;
156
157
  pos = peerset_check_insert_pos(h, id);
158
  if (pos < 0){
159 c139c4f2 CsabaKiraly
    return 0;
160
  }
161
162
  if (h->n_elements == h->size) {
163 82438fe3 Luca Abeni
    struct peer **res;
164 c139c4f2 CsabaKiraly
165 82438fe3 Luca Abeni
    res = realloc(h->elements, (h->size + DEFAULT_SIZE_INCREMENT) * sizeof(struct peer *));
166 c139c4f2 CsabaKiraly
    if (res == NULL) {
167
      return -1;
168
    }
169
    h->size += DEFAULT_SIZE_INCREMENT;
170 82438fe3 Luca Abeni
    h->elements = res;
171 c139c4f2 CsabaKiraly
  }
172 ee18ff79 Csaba Kiraly
173 391fed9c Luca Abeni
  memmove(&h->elements[pos + 1], &h->elements[pos] , ((h->n_elements++) - pos) * sizeof(struct peer *));
174 ee18ff79 Csaba Kiraly
175 82438fe3 Luca Abeni
  e = malloc(sizeof(struct peer));
176 0c6efcd5 Luca Baldesi
  h->elements[pos] = e;
177
  gettimeofday(&e->creation_timestamp, NULL);
178 fb76785c CsabaKiraly
  e->id = nodeid_dup(id);
179 b79c8e3a Luca Baldesi
  peer_init(e);
180 c139c4f2 CsabaKiraly
181
  return h->n_elements;
182
}
183
184 d1de8494 Luca Abeni
void peerset_add_peers(struct peerset *h, struct nodeID **ids, int n)
185 13c9731e CsabaKiraly
{
186
  int i;
187
188
  for (i = 0; i < n; i++) {
189 d1de8494 Luca Abeni
    peerset_add_peer(h, ids[i]);
190 13c9731e CsabaKiraly
  }
191
}
192
193 47f2affa CsabaKiraly
int peerset_size(const struct peerset *h)
194 c139c4f2 CsabaKiraly
{
195
  return h->n_elements;
196
}
197
198 82438fe3 Luca Abeni
struct peer **peerset_get_peers(const struct peerset *h)
199 c139c4f2 CsabaKiraly
{
200 47f2affa CsabaKiraly
  return h->elements;
201
}
202 c139c4f2 CsabaKiraly
203 060267cd Luca Abeni
struct peer *peerset_get_peer(const struct peerset *h, const struct nodeID *id)
204 47f2affa CsabaKiraly
{
205
  int i = peerset_check(h,id);
206 82438fe3 Luca Abeni
  return (i<0) ? NULL : h->elements[i];
207 c139c4f2 CsabaKiraly
}
208
209 91566cec Luca Baldesi
struct peer *peerset_pop_peer(struct peerset *h, const struct nodeID *id){
210
  int i = peerset_check(h,id);
211
  if (i >= 0) {
212
    struct peer *e = h->elements[i];
213
    memmove(&h->elements[i], &h->elements[i+1], ((h->n_elements--) - (i+1)) * sizeof(struct peer *));
214
215
    return e;
216
  }
217
  return NULL;
218
}
219
220 9e6eebab Csaba Kiraly
int peerset_remove_peer(struct peerset *h, const struct nodeID *id){
221
  int i = peerset_check(h,id);
222
  if (i >= 0) {
223 82438fe3 Luca Abeni
    struct peer *e = h->elements[i];
224 7c437ac6 CsabaKiraly
    nodeid_free(e->id);
225 b79c8e3a Luca Baldesi
    if (peer_deinit)
226
            peer_deinit(e);
227 f4916f84 Csaba Kiraly
    memmove(&h->elements[i], &h->elements[i+1], ((h->n_elements--) - (i+1)) * sizeof(struct peer *));
228 82438fe3 Luca Abeni
    free(e);
229
230 9e6eebab Csaba Kiraly
    return i;
231
  }
232
  return -1;
233
}
234
235 c552e22d CsabaKiraly
int peerset_check(const struct peerset *h, const struct nodeID *id)
236 c139c4f2 CsabaKiraly
{
237 391fed9c Luca Abeni
  struct peer **p;
238 c139c4f2 CsabaKiraly
239 7b60aa43 Csaba Kiraly
  p = bsearch(id, h->elements, (size_t) h->n_elements, sizeof(h->elements[0]), nodeid_peer_cmp);
240 c139c4f2 CsabaKiraly
241 7b60aa43 Csaba Kiraly
  return p ? p - h->elements : -1;
242 c139c4f2 CsabaKiraly
}
243
244 47f2affa CsabaKiraly
void peerset_clear(struct peerset *h, int size)
245 c139c4f2 CsabaKiraly
{
246 7c437ac6 CsabaKiraly
  int i;
247
248
  for (i = 0; i < h->n_elements; i++) {
249 82438fe3 Luca Abeni
    struct peer *e = h->elements[i];
250 7c437ac6 CsabaKiraly
    nodeid_free(e->id);
251 b79c8e3a Luca Baldesi
    if (peer_deinit)
252
            peer_deinit(e);
253 82438fe3 Luca Abeni
    free(e);
254 7c437ac6 CsabaKiraly
  }
255
256 c139c4f2 CsabaKiraly
  h->n_elements = 0;
257
  h->size = size;
258 10ddaca7 Luca Baldesi
  if (h->size)
259
          h->elements = realloc(h->elements, size * sizeof(struct peer *));
260
  else
261
  {
262
          free(h->elements);
263
          h->elements = NULL;
264
  }
265 c139c4f2 CsabaKiraly
  if (h->elements == NULL) {
266
    h->size = 0;
267
  }
268
}