diff options
author | Julius Bünger <buenger@mytum.de> | 2018-10-01 20:05:40 +0200 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2018-10-01 23:15:31 +0200 |
commit | 3823c7a71aa1b16df6c34ef3def45875289a6b3d (patch) | |
tree | 14fa9b007663823983fad8194202e8441a4588c0 /src/rps/gnunet-service-rps_view.c | |
parent | b3aad5bef2e78487251ef7fc766a510f9fc731c9 (diff) | |
download | gnunet-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.c | 160 |
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 | ||
29 | struct 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 | */ |
33 | static struct GNUNET_PeerIdentity *array; | 39 | uint32_t length; |
34 | |||
35 | /** | ||
36 | * (Maximum) length of the view | ||
37 | */ | ||
38 | static uint32_t length; | ||
39 | 40 | ||
40 | /** | 41 | /** |
41 | * Multipeermap containing the peers | 42 | * Multipeermap containing the peers |
42 | */ | 43 | */ |
43 | static 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 | */ |
51 | void | 54 | struct View * |
52 | View_create (uint32_t len) | 55 | View_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 | */ |
67 | void | 77 | void |
68 | View_change_len (uint32_t len) | 78 | View_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 | */ |
106 | const struct GNUNET_PeerIdentity * | 119 | const struct GNUNET_PeerIdentity * |
107 | View_get_as_array () | 120 | View_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 | */ |
117 | unsigned int | 132 | unsigned int |
118 | View_size () | 133 | View_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 | */ |
131 | int | 148 | int |
132 | View_put (const struct GNUNET_PeerIdentity *peer) | 149 | View_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 | */ |
160 | int | 180 | int |
161 | View_contains_peer (const struct GNUNET_PeerIdentity *peer) | 181 | View_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 | */ |
174 | int | 197 | int |
175 | View_remove_peer (const struct GNUNET_PeerIdentity *peer) | 198 | View_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 | */ |
209 | const struct GNUNET_PeerIdentity * | 237 | const struct GNUNET_PeerIdentity * |
210 | View_get_peer_by_index (uint32_t index) | 238 | View_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 | */ |
229 | void | 257 | void |
230 | View_clear () | 258 | View_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 | */ |
252 | void | 280 | void |
253 | View_destroy () | 281 | View_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 */ |