GNUnet  0.10.x
peer.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2006, 2008, 2009 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include "gnunet_peer_lib.h"
28 
29 #define LOG(kind, ...) GNUNET_log_from(kind, "util-peer", __VA_ARGS__)
30 
31 
32 struct PeerEntry {
36  struct GNUNET_PeerIdentity id;
37 
43 
47  unsigned int rc;
48 };
49 
50 
54 static struct PeerEntry **table;
55 
62 
66 static unsigned int size;
67 
72 static unsigned int free_list_start;
73 
74 
83 {
84  struct PeerEntry *e;
85 
86  if (NULL == pid)
87  return 0;
88  if (NULL == map)
89  return 0;
91  if (NULL == e)
92  return 0;
93  GNUNET_assert(e->rc > 0);
94  return e->pid;
95 }
96 
97 
107 {
109  struct PeerEntry *e;
110  unsigned int i;
111 
112  if (NULL == pid)
113  return 0;
114  if (NULL == map)
116  e = GNUNET_CONTAINER_multipeermap_get(map, pid);
117  if (NULL != e)
118  {
119  GNUNET_assert(e->rc > 0);
120  e->rc++;
121  return e->pid;
122  }
123  ret = free_list_start;
124  if (ret == size)
125  {
126  GNUNET_array_grow(table, size, size + 16);
127  for (i = ret; i < size; i++)
128  {
129  table[i] = GNUNET_new(struct PeerEntry);
130  table[i]->pid = i + 1;
131  }
132  }
133  if (0 == ret)
134  {
135  memset(&table[0]->id, 0, sizeof(struct GNUNET_PeerIdentity));
136  table[0]->pid = 0;
137  table[0]->rc = 1;
138  ret = 1;
139  }
140  GNUNET_assert(ret < size);
141  GNUNET_assert(0 == table[ret]->rc);
142  free_list_start = table[ret]->pid;
143  table[ret]->id = *pid;
144  table[ret]->rc = 1;
145  table[ret]->pid = ret;
148  &table[ret]->id,
149  table[ret],
151  return ret;
152 }
153 
154 
161 void
162 GNUNET_PEER_decrement_rcs(const GNUNET_PEER_Id *ids, unsigned int count)
163 {
164  int i;
166 
167  if (0 == count)
168  return;
169  for (i = count - 1; i >= 0; i--)
170  {
171  id = ids[i];
172  if (0 == id)
173  continue;
174  GNUNET_assert(id < size);
175  GNUNET_assert(table[id]->rc > 0);
176  table[id]->rc--;
177  if (0 == table[id]->rc)
178  {
181  &table[id]->id,
182  table[id]));
183  table[id]->pid = free_list_start;
185  }
186  }
187 }
188 
189 
196 void
198 {
199  if (0 == id)
200  return;
201  GNUNET_assert(id < size);
202  GNUNET_assert(table[id]->rc > 0);
203  GNUNET_assert((delta >= 0) ||
204  (table[id]->rc >= (unsigned int)(-delta)));
205  table[id]->rc += delta;
206  if (0 == table[id]->rc)
207  {
210  &table[id]->id,
211  table[id]));
212  table[id]->pid = free_list_start;
214  }
215 }
216 
217 
224 void
226 {
227  if (0 == id)
228  {
229  memset(pid, 0, sizeof(struct GNUNET_PeerIdentity));
230  return;
231  }
232  GNUNET_assert(id < size);
233  GNUNET_assert(table[id]->rc > 0);
234  *pid = table[id]->id;
235 }
236 
237 
244 const struct GNUNET_PeerIdentity *
246 {
247  GNUNET_assert(id < size);
248  GNUNET_assert(table[id]->rc > 0);
249  return &table[id]->id;
250 }
251 
252 
253 
254 /* end of peer.c */
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition: peer.c:245
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
Per-peer information.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct Experiment * e
GNUNET_PEER_Id GNUNET_PEER_search(const struct GNUNET_PeerIdentity *pid)
Search for a peer identity.
Definition: peer.c:82
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
unsigned int rc
Reference counter, 0 if this slot is not used.
Definition: peer.c:47
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
static int ret
Final status code.
Definition: gnunet-arm.c:89
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition: peer.c:225
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
unsigned int GNUNET_PEER_Id
A GNUNET_PEER_Id is simply a shorter version of a "struct GNUNET_PeerIdentifier" that can be used ins...
static struct GNUNET_CONTAINER_MultiPeerMap * ids
GNUNET_PeerIdentity -> CadetPeer.
static struct PeerEntry ** table
Table with our interned peer IDs.
Definition: peer.c:54
Internal representation of the hash map.
void GNUNET_PEER_decrement_rcs(const GNUNET_PEER_Id *ids, unsigned int count)
Decrement multiple RCs of peer identities by one.
Definition: peer.c:162
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition: peer.c:61
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static unsigned int size
Size of the "table".
Definition: peer.c:66
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
The identity of the host (wraps the signing key of the peer).
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition: peer.c:197
#define GNUNET_YES
Definition: gnunet_common.h:77
GNUNET_PEER_Id pid
Short version of the identifier; if the RC==0, then index of next free slot in table, otherwise equal to this slot in the table.
Definition: peer.c:42
struct GNUNET_PeerIdentity id
What is the identity of the peer?
static unsigned int free_list_start
Index of the beginning of the free list in the table; set to "size" if no slots are free in the table...
Definition: peer.c:72
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition: peer.c:106