GNUnet  0.10.x
gnunet-service-rps_view.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C)
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_util_lib.h"
29 #include <inttypes.h>
30 
31 struct View
32 {
37 
41  uint32_t length;
42 
47 };
48 
49 
56 struct View *
57 View_create (uint32_t len)
58 {
59  struct View *view;
60 
61  view = GNUNET_new (struct View);
62  view->length = len;
63  view->array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
64  view->mpm =
65  GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
66  * set to _YES */
67  return view;
68 }
69 
70 
79 void
80 View_change_len (struct View *view,
81  uint32_t len)
82 {
83  uint32_t i;
84  uint32_t *index;
85 
86  if (GNUNET_CONTAINER_multipeermap_size (view->mpm) < len)
87  { /* Simply shrink */
88  /* We might simply clear and free the left over space */
89  GNUNET_array_grow (view->array, view->length, len);
90  }
91  else /* We have to remove elements */
92  {
93  /* TODO find a way to preserve indices */
94  for (i = 0; i < len; i++)
95  {
96  index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
97  GNUNET_assert (NULL != index);
98  GNUNET_free (index);
99  }
100  GNUNET_array_grow (view->array, view->length, len);
103  for (i = 0; i < len; i++)
104  {
105  index = GNUNET_new (uint32_t);
106  *index = i;
107  GNUNET_CONTAINER_multipeermap_put (view->mpm, &view->array[i], index,
109  }
110  }
111  GNUNET_assert (view->length == len);
112 }
113 
114 
121 const struct GNUNET_PeerIdentity *
122 View_get_as_array (const struct View *view)
123 {
124  return view->array;
125 }
126 
127 
134 unsigned int
135 View_size (const struct View *view)
136 {
138 }
139 
140 
150 int
151 View_put (struct View *view,
152  const struct GNUNET_PeerIdentity *peer)
153 {
154  uint32_t *index;
155 
156  if ((view->length <= View_size (view)) || /* If array is 'full' */
157  (GNUNET_YES == View_contains_peer (view, peer)))
158  {
159  return GNUNET_NO;
160  }
161  else
162  {
163  index = GNUNET_new (uint32_t);
164  *index = (uint32_t) View_size (view);
165  view->array[*index] = *peer;
166  GNUNET_CONTAINER_multipeermap_put (view->mpm, peer, index,
168  return GNUNET_OK;
169  }
170 }
171 
172 
182 int
183 View_contains_peer (const struct View *view,
184  const struct GNUNET_PeerIdentity *peer)
185 {
186  return GNUNET_CONTAINER_multipeermap_contains (view->mpm, peer);
187 }
188 
189 
199 int
200 View_remove_peer (struct View *view,
201  const struct GNUNET_PeerIdentity *peer)
202 {
203  uint32_t *index;
204  uint32_t *swap_index;
205  uint32_t last_index;
206 
207  if (GNUNET_NO == View_contains_peer (view, peer))
208  {
209  return GNUNET_NO;
210  }
211  index = GNUNET_CONTAINER_multipeermap_get (view->mpm, peer);
212  GNUNET_assert (NULL != index);
213  last_index = View_size (view) - 1;
214  if (*index < last_index)
215  { /* Fill the 'gap' in the array with the last peer */
216  view->array[*index] = view->array[last_index];
218  &view->array[last_index]));
219  swap_index = GNUNET_CONTAINER_multipeermap_get (view->mpm,
220  &view->array[last_index]);
221  GNUNET_assert (NULL != swap_index);
222  *swap_index = *index;
223  GNUNET_free (index);
224  }
226  return GNUNET_OK;
227 }
228 
229 
239 const struct GNUNET_PeerIdentity *
240 View_get_peer_by_index (const struct View *view,
241  uint32_t index)
242 {
243  if (index < GNUNET_CONTAINER_multipeermap_size (view->mpm))
244  {
245  return &view->array[index];
246  }
247  else
248  {
249  return NULL;
250  }
251 }
252 
253 
259 void
260 View_clear (struct View *view)
261 {
262  for (uint32_t i = 0; 0 < View_size (view); i++)
263  { /* Need to free indices stored at peers */
264  uint32_t *index;
265 
268  index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
269  GNUNET_assert (NULL != index);
270  GNUNET_free (index);
272  }
273  GNUNET_assert (0 == View_size (view));
274 }
275 
276 
282 void
283 View_destroy (struct View *view)
284 {
285  View_clear (view);
286  GNUNET_free (view->array);
287  view->array = NULL;
289  GNUNET_free (view);
290 }
291 
292 /* end of gnunet-service-rps_view.c */
struct GNUNET_CONTAINER_MultiPeerMap * mpm
Multipeermap containing the peers.
int GNUNET_CONTAINER_multipeermap_remove_all(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Remove all entries for the given key from the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void View_change_len(struct View *view, uint32_t len)
Change length of view.
int View_contains_peer(const struct View *view, const struct GNUNET_PeerIdentity *peer)
Check whether view contains a peer.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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).
const struct GNUNET_PeerIdentity * View_get_as_array(const struct View *view)
Get the view as an array.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int View_put(struct View *view, const struct GNUNET_PeerIdentity *peer)
Insert peer into the view.
const struct GNUNET_PeerIdentity * View_get_peer_by_index(const struct View *view, uint32_t index)
Get a peer by index.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
wrapper around the "local view"
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
struct View * View_create(uint32_t len)
Create an empty view.
Internal representation of the hash map.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
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 View_destroy(struct View *view)
Destroy view.
unsigned int View_size(const struct View *view)
Get the size of the view.
void View_clear(struct View *view)
Clear the view.
#define GNUNET_YES
Definition: gnunet_common.h:80
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int View_remove_peer(struct View *view, const struct GNUNET_PeerIdentity *peer)
Remove peer from view.
struct GNUNET_PeerIdentity * array
Array containing the peers.
int GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL)...
uint32_t length
(Maximum) length of the view
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...