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 {
36 
40  uint32_t length;
41 
46 };
47 
48 
55 struct View *
56 View_create(uint32_t len)
57 {
58  struct View *view;
59 
60  view = GNUNET_new(struct View);
61  view->length = len;
62  view->array = GNUNET_new_array(len, struct GNUNET_PeerIdentity);
63  view->mpm =
64  GNUNET_CONTAINER_multipeermap_create(len, GNUNET_NO); /* might even be
65  * set to _YES */
66  return view;
67 }
68 
69 
78 void
79 View_change_len(struct View *view,
80  uint32_t len)
81 {
82  uint32_t i;
83  uint32_t *index;
84 
85  if (GNUNET_CONTAINER_multipeermap_size(view->mpm) < len)
86  { /* Simply shrink */
87  /* We might simply clear and free the left over space */
88  GNUNET_array_grow(view->array, view->length, len);
89  }
90  else /* We have to remove elements */
91  {
92  /* TODO find a way to preserve indices */
93  for (i = 0; i < len; i++)
94  {
95  index = GNUNET_CONTAINER_multipeermap_get(view->mpm, &view->array[i]);
96  GNUNET_assert(NULL != index);
97  GNUNET_free(index);
98  }
99  GNUNET_array_grow(view->array, view->length, len);
102  for (i = 0; i < len; i++)
103  {
104  index = GNUNET_new(uint32_t);
105  *index = i;
106  GNUNET_CONTAINER_multipeermap_put(view->mpm, &view->array[i], index,
108  }
109  }
110  GNUNET_assert(view->length == len);
111 }
112 
113 
120 const struct GNUNET_PeerIdentity *
121 View_get_as_array(const struct View *view)
122 {
123  return view->array;
124 }
125 
126 
133 unsigned int
134 View_size(const struct View *view)
135 {
137 }
138 
139 
149 int
150 View_put(struct View *view,
151  const struct GNUNET_PeerIdentity *peer)
152 {
153  uint32_t *index;
154 
155  if ((view->length <= View_size(view)) || /* If array is 'full' */
156  (GNUNET_YES == View_contains_peer(view, peer)))
157  {
158  return GNUNET_NO;
159  }
160  else
161  {
162  index = GNUNET_new(uint32_t);
163  *index = (uint32_t)View_size(view);
164  view->array[*index] = *peer;
165  GNUNET_CONTAINER_multipeermap_put(view->mpm, peer, index,
167  return GNUNET_OK;
168  }
169 }
170 
171 
181 int
182 View_contains_peer(const struct View *view,
183  const struct GNUNET_PeerIdentity *peer)
184 {
185  return GNUNET_CONTAINER_multipeermap_contains(view->mpm, peer);
186 }
187 
188 
198 int
199 View_remove_peer(struct View *view,
200  const struct GNUNET_PeerIdentity *peer)
201 {
202  uint32_t *index;
203  uint32_t *swap_index;
204  uint32_t last_index;
205 
206  if (GNUNET_NO == View_contains_peer(view, peer))
207  {
208  return GNUNET_NO;
209  }
210  index = GNUNET_CONTAINER_multipeermap_get(view->mpm, peer);
211  GNUNET_assert(NULL != index);
212  last_index = View_size(view) - 1;
213  if (*index < last_index)
214  { /* Fill the 'gap' in the array with the last peer */
215  view->array[*index] = view->array[last_index];
217  &view->array[last_index]));
218  swap_index = GNUNET_CONTAINER_multipeermap_get(view->mpm,
219  &view->array[last_index]);
220  GNUNET_assert(NULL != swap_index);
221  *swap_index = *index;
222  GNUNET_free(index);
223  }
225  return GNUNET_OK;
226 }
227 
228 
238 const struct GNUNET_PeerIdentity *
239 View_get_peer_by_index(const struct View *view,
240  uint32_t index)
241 {
242  if (index < GNUNET_CONTAINER_multipeermap_size(view->mpm))
243  {
244  return &view->array[index];
245  }
246  else
247  {
248  return NULL;
249  }
250 }
251 
252 
258 void
259 View_clear(struct View *view)
260 {
261  for (uint32_t i = 0; 0 < View_size(view); i++)
262  { /* Need to free indices stored at peers */
263  uint32_t *index;
264 
267  index = GNUNET_CONTAINER_multipeermap_get(view->mpm, &view->array[i]);
268  GNUNET_assert(NULL != index);
269  GNUNET_free(index);
271  }
272  GNUNET_assert(0 == View_size(view));
273 }
274 
275 
281 void
282 View_destroy(struct View *view)
283 {
284  View_clear(view);
285  GNUNET_free(view->array);
286  view->array = NULL;
288  GNUNET_free(view);
289 }
290 
291 /* 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:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:77
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...