aboutsummaryrefslogtreecommitdiff
path: root/src/rps/gnunet-service-rps_view.c
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2018-10-01 20:05:40 +0200
committerJulius Bünger <buenger@mytum.de>2018-10-01 23:15:31 +0200
commit3823c7a71aa1b16df6c34ef3def45875289a6b3d (patch)
tree14fa9b007663823983fad8194202e8441a4588c0 /src/rps/gnunet-service-rps_view.c
parentb3aad5bef2e78487251ef7fc766a510f9fc731c9 (diff)
downloadgnunet-3823c7a71aa1b16df6c34ef3def45875289a6b3d.tar.gz
gnunet-3823c7a71aa1b16df6c34ef3def45875289a6b3d.zip
Restructure implementation of view (towards subsampling)
Diffstat (limited to 'src/rps/gnunet-service-rps_view.c')
-rw-r--r--src/rps/gnunet-service-rps_view.c160
1 files changed, 94 insertions, 66 deletions
diff --git a/src/rps/gnunet-service-rps_view.c b/src/rps/gnunet-service-rps_view.c
index 26a0b22bc..3af858e60 100644
--- a/src/rps/gnunet-service-rps_view.c
+++ b/src/rps/gnunet-service-rps_view.c
@@ -26,192 +26,221 @@
26#include "gnunet-service-rps_view.h" 26#include "gnunet-service-rps_view.h"
27#include <inttypes.h> 27#include <inttypes.h>
28 28
29struct View
30{
31 /**
32 * Array containing the peers
33 */
34 struct GNUNET_PeerIdentity *array;
29 35
30/** 36 /**
31 * Array containing the peers 37 * (Maximum) length of the view
32 */ 38 */
33static struct GNUNET_PeerIdentity *array; 39 uint32_t length;
34
35/**
36 * (Maximum) length of the view
37 */
38static uint32_t length;
39 40
40/** 41 /**
41 * Multipeermap containing the peers 42 * Multipeermap containing the peers
42 */ 43 */
43static struct GNUNET_CONTAINER_MultiPeerMap *mpm; 44 struct GNUNET_CONTAINER_MultiPeerMap *mpm;
45};
44 46
45 47
46/** 48/**
47 * Create an empty view. 49 * Create an empty view.
48 * 50 *
49 * @param len the maximum length for the view 51 * @param len the maximum length for the view
52 * @return The newly created view
50 */ 53 */
51void 54struct View *
52View_create (uint32_t len) 55View_create (uint32_t len)
53{ 56{
54 length = len; 57 struct View *view;
55 array = GNUNET_new_array (len, struct GNUNET_PeerIdentity); 58
56 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be 59 view = GNUNET_new (struct View);
57 * set to _YES */ 60 view->length = len;
61 view->array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
62 view->mpm =
63 GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
64 * set to _YES */
65 return view;
58} 66}
59 67
68
60/** 69/**
61 * Change length of view 70 * Change length of view
62 * 71 *
63 * If size is decreased, peers with higher indices are removed. 72 * If size is decreased, peers with higher indices are removed.
64 * 73 *
74 * @param view The view that is changed
65 * @param len the (maximum) length for the view 75 * @param len the (maximum) length for the view
66 */ 76 */
67void 77void
68View_change_len (uint32_t len) 78View_change_len (struct View *view,
79 uint32_t len)
69{ 80{
70 uint32_t i; 81 uint32_t i;
71 uint32_t *index; 82 uint32_t *index;
72 83
73 if (GNUNET_CONTAINER_multipeermap_size (mpm) < len) 84 if (GNUNET_CONTAINER_multipeermap_size (view->mpm) < len)
74 { /* Simply shrink */ 85 { /* Simply shrink */
75 /* We might simply clear and free the left over space */ 86 /* We might simply clear and free the left over space */
76 GNUNET_array_grow (array, length, len); 87 GNUNET_array_grow (view->array, view->length, len);
77 } 88 }
78 else /* We have to remove elements */ 89 else /* We have to remove elements */
79 { 90 {
80 /* TODO find a way to preserve indices */ 91 /* TODO find a way to preserve indices */
81 for (i = 0; i < len; i++) 92 for (i = 0; i < len; i++)
82 { 93 {
83 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); 94 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
84 GNUNET_assert (NULL != index); 95 GNUNET_assert (NULL != index);
85 GNUNET_free (index); 96 GNUNET_free (index);
86 } 97 }
87 GNUNET_array_grow (array, length, len); 98 GNUNET_array_grow (view->array, view->length, len);
88 GNUNET_CONTAINER_multipeermap_destroy (mpm); 99 GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
89 mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); 100 view->mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO);
90 for (i = 0; i < len; i++) 101 for (i = 0; i < len; i++)
91 { 102 {
92 index = GNUNET_new (uint32_t); 103 index = GNUNET_new (uint32_t);
93 *index = i; 104 *index = i;
94 GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index, 105 GNUNET_CONTAINER_multipeermap_put (view->mpm, &view->array[i], index,
95 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 106 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
96 } 107 }
97 } 108 }
98 GNUNET_assert (length == len); 109 GNUNET_assert (view->length == len);
99} 110}
100 111
112
101/** 113/**
102 * Get the view as an array 114 * Get the view as an array
103 * 115 *
116 * @param view The view of which the array representation is of interest
104 * @return the view in array representation 117 * @return the view in array representation
105 */ 118 */
106const struct GNUNET_PeerIdentity * 119const struct GNUNET_PeerIdentity *
107View_get_as_array () 120View_get_as_array (const struct View *view)
108{ 121{
109 return array; 122 return view->array;
110} 123}
111 124
125
112/** 126/**
113 * Get the size of the view 127 * Get the size of the view
114 * 128 *
129 * @param view The view of which the size should be returned
115 * @return current number of actually contained peers 130 * @return current number of actually contained peers
116 */ 131 */
117unsigned int 132unsigned int
118View_size () 133View_size (const struct View *view)
119{ 134{
120 return GNUNET_CONTAINER_multipeermap_size (mpm); 135 return GNUNET_CONTAINER_multipeermap_size (view->mpm);
121} 136}
122 137
138
123/** 139/**
124 * Insert peer into the view 140 * Insert peer into the view
125 * 141 *
142 * @param view The view to put the peer into
126 * @param peer the peer to insert 143 * @param peer the peer to insert
127 * 144 *
128 * @return GNUNET_OK if peer was actually inserted 145 * @return GNUNET_OK if peer was actually inserted
129 * GNUNET_NO if peer was not inserted 146 * GNUNET_NO if peer was not inserted
130 */ 147 */
131int 148int
132View_put (const struct GNUNET_PeerIdentity *peer) 149View_put (struct View *view,
150 const struct GNUNET_PeerIdentity *peer)
133{ 151{
134 uint32_t *index; 152 uint32_t *index;
135 153
136 if ((length <= View_size ()) || /* If array is 'full' */ 154 if ((view->length <= View_size (view)) || /* If array is 'full' */
137 (GNUNET_YES == View_contains_peer (peer))) 155 (GNUNET_YES == View_contains_peer (view, peer)))
138 { 156 {
139 return GNUNET_NO; 157 return GNUNET_NO;
140 } 158 }
141 else 159 else
142 { 160 {
143 index = GNUNET_new (uint32_t); 161 index = GNUNET_new (uint32_t);
144 *index = (uint32_t) View_size (); 162 *index = (uint32_t) View_size (view);
145 array[*index] = *peer; 163 view->array[*index] = *peer;
146 GNUNET_CONTAINER_multipeermap_put (mpm, peer, index, 164 GNUNET_CONTAINER_multipeermap_put (view->mpm, peer, index,
147 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 165 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
148 return GNUNET_OK; 166 return GNUNET_OK;
149 } 167 }
150} 168}
151 169
170
152/** 171/**
153 * Check whether view contains a peer 172 * Check whether view contains a peer
154 * 173 *
174 * @param view The which is checked for a peer
155 * @param peer the peer to check for 175 * @param peer the peer to check for
156 * 176 *
157 * @return GNUNET_OK if view contains peer 177 * @return GNUNET_OK if view contains peer
158 * GNUNET_NO otherwise 178 * GNUNET_NO otherwise
159 */ 179 */
160int 180int
161View_contains_peer (const struct GNUNET_PeerIdentity *peer) 181View_contains_peer (const struct View *view,
182 const struct GNUNET_PeerIdentity *peer)
162{ 183{
163 return GNUNET_CONTAINER_multipeermap_contains (mpm, peer); 184 return GNUNET_CONTAINER_multipeermap_contains (view->mpm, peer);
164} 185}
165 186
187
166/** 188/**
167 * Remove peer from view 189 * Remove peer from view
168 * 190 *
191 * @param view The view of which to remove the peer
169 * @param peer the peer to remove 192 * @param peer the peer to remove
170 * 193 *
171 * @return GNUNET_OK if view contained peer and removed it successfully 194 * @return GNUNET_OK if view contained peer and removed it successfully
172 * GNUNET_NO if view does not contain peer 195 * GNUNET_NO if view does not contain peer
173 */ 196 */
174int 197int
175View_remove_peer (const struct GNUNET_PeerIdentity *peer) 198View_remove_peer (struct View *view,
199 const struct GNUNET_PeerIdentity *peer)
176{ 200{
177 uint32_t *index; 201 uint32_t *index;
178 uint32_t *swap_index; 202 uint32_t *swap_index;
179 uint32_t last_index; 203 uint32_t last_index;
180 204
181 if (GNUNET_NO == View_contains_peer (peer)) 205 if (GNUNET_NO == View_contains_peer (view, peer))
182 { 206 {
183 return GNUNET_NO; 207 return GNUNET_NO;
184 } 208 }
185 index = GNUNET_CONTAINER_multipeermap_get (mpm, peer); 209 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, peer);
186 GNUNET_assert (NULL != index); 210 GNUNET_assert (NULL != index);
187 last_index = View_size () - 1; 211 last_index = View_size (view) - 1;
188 if (*index < last_index) 212 if (*index < last_index)
189 { /* Fill the 'gap' in the array with the last peer */ 213 { /* Fill the 'gap' in the array with the last peer */
190 array[*index] = array[last_index]; 214 view->array[*index] = view->array[last_index];
191 GNUNET_assert (GNUNET_YES == View_contains_peer (&array[last_index])); 215 GNUNET_assert (GNUNET_YES == View_contains_peer (view,
192 swap_index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[last_index]); 216 &view->array[last_index]));
217 swap_index = GNUNET_CONTAINER_multipeermap_get (view->mpm,
218 &view->array[last_index]);
193 GNUNET_assert (NULL != swap_index); 219 GNUNET_assert (NULL != swap_index);
194 *swap_index = *index; 220 *swap_index = *index;
195 GNUNET_free (index); 221 GNUNET_free (index);
196 } 222 }
197 GNUNET_CONTAINER_multipeermap_remove_all (mpm, peer); 223 GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, peer);
198 return GNUNET_OK; 224 return GNUNET_OK;
199} 225}
200 226
227
201/** 228/**
202 * Get a peer by index 229 * Get a peer by index
203 * 230 *
231 * @param view the view of which to get the peer
204 * @param index the index of the peer to get 232 * @param index the index of the peer to get
205 * 233 *
206 * @return peer to the corresponding index. 234 * @return peer to the corresponding index.
207 * NULL if this index is not known 235 * NULL if this index is not known
208 */ 236 */
209const struct GNUNET_PeerIdentity * 237const struct GNUNET_PeerIdentity *
210View_get_peer_by_index (uint32_t index) 238View_get_peer_by_index (const struct View *view,
239 uint32_t index)
211{ 240{
212 if (index < GNUNET_CONTAINER_multipeermap_size (mpm)) 241 if (index < GNUNET_CONTAINER_multipeermap_size (view->mpm))
213 { 242 {
214 return &array[index]; 243 return &view->array[index];
215 } 244 }
216 else 245 else
217 { 246 {
@@ -219,42 +248,41 @@ View_get_peer_by_index (uint32_t index)
219 } 248 }
220} 249}
221 250
251
222/** 252/**
223 * Clear the custom peer map 253 * Clear the view
224 *
225 * @param c_peer_map the custom peer map to look in
226 * 254 *
227 * @return size of the map 255 * @param view The view to clear
228 */ 256 */
229void 257void
230View_clear () 258View_clear (struct View *view)
231{ 259{
232 for (uint32_t i = 0; 0 < View_size (); i++) 260 for (uint32_t i = 0; 0 < View_size (view); i++)
233 { /* Need to free indices stored at peers */ 261 { /* Need to free indices stored at peers */
234 uint32_t *index; 262 uint32_t *index;
235 263
236 GNUNET_assert (GNUNET_YES == 264 GNUNET_assert (GNUNET_YES ==
237 GNUNET_CONTAINER_multipeermap_contains (mpm, &array[i])); 265 GNUNET_CONTAINER_multipeermap_contains (view->mpm, &view->array[i]));
238 index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); 266 index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
239 GNUNET_assert (NULL != index); 267 GNUNET_assert (NULL != index);
240 GNUNET_free (index); 268 GNUNET_free (index);
241 GNUNET_CONTAINER_multipeermap_remove_all (mpm, &array[i]); 269 GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, &view->array[i]);
242 } 270 }
243 GNUNET_assert (0 == View_size ()); 271 GNUNET_assert (0 == View_size (view));
244} 272}
245 273
246 274
247/** 275/**
248 * Destroy peermap. 276 * Destroy view.
249 * 277 *
250 * @param c_peer_map the map to destroy 278 * @param view the view to destroy
251 */ 279 */
252void 280void
253View_destroy () 281View_destroy (struct View *view)
254{ 282{
255 View_clear (); 283 View_clear (view);
256 GNUNET_free (array); 284 GNUNET_free (view->array);
257 GNUNET_CONTAINER_multipeermap_destroy (mpm); 285 GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
258} 286}
259 287
260/* end of gnunet-service-rps_view.c */ 288/* end of gnunet-service-rps_view.c */