diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-11-24 13:57:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-11-24 13:57:17 +0000 |
commit | 82f034f771b4fd8e18c61487f4bd239e0e200408 (patch) | |
tree | 29d37b77fee94a49359a462bd5adbdb460733a69 /src/set | |
parent | 3fb00702b5ebd54301d5827774fbebcd11d206c9 (diff) | |
download | gnunet-82f034f771b4fd8e18c61487f4bd239e0e200408.tar.gz gnunet-82f034f771b4fd8e18c61487f4bd239e0e200408.zip |
fixing collect_generation_garbage() complexity, doxygen, etc.
Diffstat (limited to 'src/set')
-rw-r--r-- | src/set/gnunet-service-set.c | 156 | ||||
-rw-r--r-- | src/set/gnunet-service-set.h | 246 | ||||
-rw-r--r-- | src/set/gnunet-service-set_intersection.c | 59 | ||||
-rw-r--r-- | src/set/gnunet-service-set_union.c | 18 |
4 files changed, 272 insertions, 207 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 3a3f91217..ec2bb6484 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -42,25 +42,24 @@ struct OperationState | |||
42 | struct GNUNET_PeerIdentity peer; | 42 | struct GNUNET_PeerIdentity peer; |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * Unique request id for the request from | ||
46 | * a remote peer, sent to the client, which will | ||
47 | * accept or reject the request. | ||
48 | * Set to '0' iff the request has not been | ||
49 | * suggested yet. | ||
50 | */ | ||
51 | uint32_t suggest_id; | ||
52 | |||
53 | /** | ||
54 | * Timeout task, if the incoming peer has not been accepted | 45 | * Timeout task, if the incoming peer has not been accepted |
55 | * after the timeout, it will be disconnected. | 46 | * after the timeout, it will be disconnected. |
56 | */ | 47 | */ |
57 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 48 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
49 | |||
50 | /** | ||
51 | * Unique request id for the request from a remote peer, sent to the | ||
52 | * client, which will accept or reject the request. Set to '0' iff | ||
53 | * the request has not been suggested yet. | ||
54 | */ | ||
55 | uint32_t suggest_id; | ||
56 | |||
58 | }; | 57 | }; |
59 | 58 | ||
60 | 59 | ||
61 | /** | 60 | /** |
62 | * A listener is inhabited by a client, and | 61 | * A listener is inhabited by a client, and waits for evaluation |
63 | * waits for evaluation requests from remote peers. | 62 | * requests from remote peers. |
64 | */ | 63 | */ |
65 | struct Listener | 64 | struct Listener |
66 | { | 65 | { |
@@ -86,15 +85,15 @@ struct Listener | |||
86 | struct GNUNET_MQ_Handle *client_mq; | 85 | struct GNUNET_MQ_Handle *client_mq; |
87 | 86 | ||
88 | /** | 87 | /** |
89 | * The type of the operation. | ||
90 | */ | ||
91 | enum GNUNET_SET_OperationType operation; | ||
92 | |||
93 | /** | ||
94 | * Application ID for the operation, used to distinguish | 88 | * Application ID for the operation, used to distinguish |
95 | * multiple operations of the same type with the same peer. | 89 | * multiple operations of the same type with the same peer. |
96 | */ | 90 | */ |
97 | struct GNUNET_HashCode app_id; | 91 | struct GNUNET_HashCode app_id; |
92 | |||
93 | /** | ||
94 | * The type of the operation. | ||
95 | */ | ||
96 | enum GNUNET_SET_OperationType operation; | ||
98 | }; | 97 | }; |
99 | 98 | ||
100 | 99 | ||
@@ -104,8 +103,8 @@ struct Listener | |||
104 | static const struct GNUNET_CONFIGURATION_Handle *configuration; | 103 | static const struct GNUNET_CONFIGURATION_Handle *configuration; |
105 | 104 | ||
106 | /** | 105 | /** |
107 | * Handle to the cadet service, used | 106 | * Handle to the cadet service, used to listen for and connect to |
108 | * to listen for and connect to remote peers. | 107 | * remote peers. |
109 | */ | 108 | */ |
110 | static struct GNUNET_CADET_Handle *cadet; | 109 | static struct GNUNET_CADET_Handle *cadet; |
111 | 110 | ||
@@ -130,21 +129,21 @@ static struct Listener *listeners_head; | |||
130 | static struct Listener *listeners_tail; | 129 | static struct Listener *listeners_tail; |
131 | 130 | ||
132 | /** | 131 | /** |
133 | * Incoming sockets from remote peers are | 132 | * Incoming sockets from remote peers are held in a doubly linked |
134 | * held in a doubly linked list. | 133 | * list. |
135 | */ | 134 | */ |
136 | static struct Operation *incoming_head; | 135 | static struct Operation *incoming_head; |
137 | 136 | ||
138 | /** | 137 | /** |
139 | * Incoming sockets from remote peers are | 138 | * Incoming sockets from remote peers are held in a doubly linked |
140 | * held in a doubly linked list. | 139 | * list. |
141 | */ | 140 | */ |
142 | static struct Operation *incoming_tail; | 141 | static struct Operation *incoming_tail; |
143 | 142 | ||
144 | /** | 143 | /** |
145 | * Counter for allocating unique IDs for clients, | 144 | * Counter for allocating unique IDs for clients, used to identify |
146 | * used to identify incoming operation requests from remote peers, | 145 | * incoming operation requests from remote peers, that the client can |
147 | * that the client can choose to accept or refuse. | 146 | * choose to accept or refuse. |
148 | */ | 147 | */ |
149 | static uint32_t suggest_id = 1; | 148 | static uint32_t suggest_id = 1; |
150 | 149 | ||
@@ -223,8 +222,10 @@ listener_destroy (struct Listener *listener) | |||
223 | if (NULL != listener->client) | 222 | if (NULL != listener->client) |
224 | { | 223 | { |
225 | struct GNUNET_SERVER_Client *client = listener->client; | 224 | struct GNUNET_SERVER_Client *client = listener->client; |
225 | |||
226 | listener->client = NULL; | 226 | listener->client = NULL; |
227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "disconnecting listener client\n"); | 227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
228 | "disconnecting listener client\n"); | ||
228 | GNUNET_SERVER_client_disconnect (client); | 229 | GNUNET_SERVER_client_disconnect (client); |
229 | return; | 230 | return; |
230 | } | 231 | } |
@@ -233,48 +234,95 @@ listener_destroy (struct Listener *listener) | |||
233 | GNUNET_MQ_destroy (listener->client_mq); | 234 | GNUNET_MQ_destroy (listener->client_mq); |
234 | listener->client_mq = NULL; | 235 | listener->client_mq = NULL; |
235 | } | 236 | } |
236 | GNUNET_CONTAINER_DLL_remove (listeners_head, listeners_tail, listener); | 237 | GNUNET_CONTAINER_DLL_remove (listeners_head, |
238 | listeners_tail, | ||
239 | listener); | ||
237 | GNUNET_free (listener); | 240 | GNUNET_free (listener); |
238 | } | 241 | } |
239 | 242 | ||
240 | 243 | ||
241 | /** | 244 | /** |
245 | * Context for the #garbage_collect_cb(). | ||
246 | */ | ||
247 | struct GarbageContext | ||
248 | { | ||
249 | |||
250 | /** | ||
251 | * Map for which we are garbage collecting removed elements. | ||
252 | */ | ||
253 | struct GNUNET_CONTAINER_MultiHashMap *map; | ||
254 | |||
255 | /** | ||
256 | * Lowest generation for which an operation is still pending. | ||
257 | */ | ||
258 | unsigned int min_op_generation; | ||
259 | |||
260 | /** | ||
261 | * Largest generation for which an operation is still pending. | ||
262 | */ | ||
263 | unsigned int max_op_generation; | ||
264 | |||
265 | }; | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Function invoked to check if an element can be removed from | ||
270 | * the set's history because it is no longer needed. | ||
271 | * | ||
272 | * @param cls the `struct GarbageContext *` | ||
273 | * @param key key of the element in the map | ||
274 | * @param value the `struct ElementEntry *` | ||
275 | * @return #GNUNET_OK (continue to iterate) | ||
276 | */ | ||
277 | static int | ||
278 | garbage_collect_cb (void *cls, | ||
279 | const struct GNUNET_HashCode *key, | ||
280 | void *value) | ||
281 | { | ||
282 | struct GarbageContext *gc = cls; | ||
283 | struct ElementEntry *ee = value; | ||
284 | |||
285 | if (GNUNET_YES != ee->removed) | ||
286 | return GNUNET_OK; | ||
287 | if ( (gc->max_op_generation < ee->generation_added) || | ||
288 | (ee->generation_removed > gc->min_op_generation) ) | ||
289 | { | ||
290 | GNUNET_assert (GNUNET_YES == | ||
291 | GNUNET_CONTAINER_multihashmap_remove (gc->map, | ||
292 | key, | ||
293 | ee)); | ||
294 | GNUNET_free (ee); | ||
295 | } | ||
296 | return GNUNET_OK; | ||
297 | } | ||
298 | |||
299 | |||
300 | /** | ||
242 | * Collect and destroy elements that are not needed anymore, because | 301 | * Collect and destroy elements that are not needed anymore, because |
243 | * their lifetime (as determined by their generation) does not overlap with any active | 302 | * their lifetime (as determined by their generation) does not overlap |
244 | * set operation. | 303 | * with any active set operation. |
245 | * | 304 | * |
246 | * We hereby replace the old element hashmap with a new one, instead of removing elements. | 305 | * @param set set to garbage collect |
247 | */ | 306 | */ |
248 | void | 307 | static void |
249 | collect_generation_garbage (struct Set *set) | 308 | collect_generation_garbage (struct Set *set) |
250 | { | 309 | { |
251 | struct GNUNET_CONTAINER_MultiHashMapIterator *iter; | ||
252 | struct ElementEntry *ee; | ||
253 | struct GNUNET_CONTAINER_MultiHashMap *new_elements; | ||
254 | int res; | ||
255 | struct Operation *op; | 310 | struct Operation *op; |
311 | struct GarbageContext gc; | ||
256 | 312 | ||
257 | new_elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 313 | gc.min_op_generation = UINT_MAX; |
258 | iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->elements); | 314 | gc.max_op_generation = 0; |
259 | while (GNUNET_OK == | 315 | for (op = set->ops_head; NULL != op; op = op->next) |
260 | (res = GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const void **) &ee))) | ||
261 | { | 316 | { |
262 | if (GNUNET_NO == ee->removed) | 317 | gc.min_op_generation = GNUNET_MIN (gc.min_op_generation, |
263 | goto still_needed; | 318 | op->generation_created); |
264 | for (op = set->ops_head; NULL != op; op = op->next) | 319 | gc.max_op_generation = GNUNET_MAX (gc.max_op_generation, |
265 | if ((op->generation_created >= ee->generation_added) && | 320 | op->generation_created); |
266 | (op->generation_created < ee->generation_removed)) | ||
267 | goto still_needed; | ||
268 | GNUNET_free (ee); | ||
269 | continue; | ||
270 | still_needed: | ||
271 | // we don't expect collisions, thus the replace option | ||
272 | GNUNET_CONTAINER_multihashmap_put (new_elements, &ee->element_hash, ee, | ||
273 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
274 | } | 321 | } |
275 | GNUNET_CONTAINER_multihashmap_iterator_destroy (iter); | 322 | gc.map = set->elements; |
276 | GNUNET_CONTAINER_multihashmap_destroy (set->elements); | 323 | GNUNET_CONTAINER_multihashmap_iterate (set->elements, |
277 | set->elements = new_elements; | 324 | &garbage_collect_cb, |
325 | &gc); | ||
278 | } | 326 | } |
279 | 327 | ||
280 | 328 | ||
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h index d8450e242..b92eb47ff 100644 --- a/src/set/gnunet-service-set.h +++ b/src/set/gnunet-service-set.h | |||
@@ -22,8 +22,8 @@ | |||
22 | * @file set/gnunet-service-set.h | 22 | * @file set/gnunet-service-set.h |
23 | * @brief common components for the implementation the different set operations | 23 | * @brief common components for the implementation the different set operations |
24 | * @author Florian Dold | 24 | * @author Florian Dold |
25 | * @author Christian Grothoff | ||
25 | */ | 26 | */ |
26 | |||
27 | #ifndef GNUNET_SERVICE_SET_H_PRIVATE | 27 | #ifndef GNUNET_SERVICE_SET_H_PRIVATE |
28 | #define GNUNET_SERVICE_SET_H_PRIVATE | 28 | #define GNUNET_SERVICE_SET_H_PRIVATE |
29 | 29 | ||
@@ -38,24 +38,33 @@ | |||
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Implementation-specific set state. | 41 | * Implementation-specific set state. Used as opaque pointer, and |
42 | * Used as opaque pointer, and specified further | 42 | * specified further in the respective implementation. |
43 | * in the respective implementation. | ||
44 | */ | 43 | */ |
45 | struct SetState; | 44 | struct SetState; |
46 | 45 | ||
47 | |||
48 | /** | 46 | /** |
49 | * Implementation-specific set operation. | 47 | * Implementation-specific set operation. Used as opaque pointer, and |
50 | * Used as opaque pointer, and specified further | 48 | * specified further in the respective implementation. |
51 | * in the respective implementation. | ||
52 | */ | 49 | */ |
53 | struct OperationState; | 50 | struct OperationState; |
54 | 51 | ||
55 | 52 | /** | |
56 | /* forward declarations */ | 53 | * A set that supports a specific operation with other peers. |
54 | */ | ||
57 | struct Set; | 55 | struct Set; |
56 | |||
57 | /** | ||
58 | * Information about an element element in the set. All elements are | ||
59 | * stored in a hash-table from their hash-code to their 'struct | ||
60 | * Element', so that the remove and add operations are reasonably | ||
61 | * fast. | ||
62 | */ | ||
58 | struct ElementEntry; | 63 | struct ElementEntry; |
64 | |||
65 | /** | ||
66 | * Operation context used to execute a set operation. | ||
67 | */ | ||
59 | struct Operation; | 68 | struct Operation; |
60 | 69 | ||
61 | 70 | ||
@@ -64,13 +73,9 @@ struct Operation; | |||
64 | */ | 73 | */ |
65 | struct OperationSpecification | 74 | struct OperationSpecification |
66 | { | 75 | { |
67 | /** | ||
68 | * The type of the operation. | ||
69 | */ | ||
70 | enum GNUNET_SET_OperationType operation; | ||
71 | 76 | ||
72 | /** | 77 | /** |
73 | * The remove peer we evaluate the operation with | 78 | * The remove peer we evaluate the operation with. |
74 | */ | 79 | */ |
75 | struct GNUNET_PeerIdentity peer; | 80 | struct GNUNET_PeerIdentity peer; |
76 | 81 | ||
@@ -86,6 +91,12 @@ struct OperationSpecification | |||
86 | struct GNUNET_MessageHeader *context_msg; | 91 | struct GNUNET_MessageHeader *context_msg; |
87 | 92 | ||
88 | /** | 93 | /** |
94 | * Set associated with the operation, NULL until the spec has been | ||
95 | * associated with a set. | ||
96 | */ | ||
97 | struct Set *set; | ||
98 | |||
99 | /** | ||
89 | * Salt to use for the operation. | 100 | * Salt to use for the operation. |
90 | */ | 101 | */ |
91 | uint32_t salt; | 102 | uint32_t salt; |
@@ -101,10 +112,9 @@ struct OperationSpecification | |||
101 | uint32_t client_request_id; | 112 | uint32_t client_request_id; |
102 | 113 | ||
103 | /** | 114 | /** |
104 | * Set associated with the operation, NULL until the spec has been associated | 115 | * The type of the operation. |
105 | * with a set. | ||
106 | */ | 116 | */ |
107 | struct Set *set; | 117 | enum GNUNET_SET_OperationType operation; |
108 | 118 | ||
109 | /** | 119 | /** |
110 | * When are elements sent to the client, and which elements are sent? | 120 | * When are elements sent to the client, and which elements are sent? |
@@ -113,15 +123,14 @@ struct OperationSpecification | |||
113 | }; | 123 | }; |
114 | 124 | ||
115 | 125 | ||
116 | |||
117 | |||
118 | /** | 126 | /** |
119 | * Signature of functions that create the implementation-specific | 127 | * Signature of functions that create the implementation-specific |
120 | * state for a set supporting a specific operation. | 128 | * state for a set supporting a specific operation. |
121 | * | 129 | * |
122 | * @return a set state specific to the supported operation | 130 | * @return a set state specific to the supported operation |
123 | */ | 131 | */ |
124 | typedef struct SetState *(*CreateImpl) (void); | 132 | typedef struct SetState * |
133 | (*CreateImpl) (void); | ||
125 | 134 | ||
126 | 135 | ||
127 | /** | 136 | /** |
@@ -129,18 +138,21 @@ typedef struct SetState *(*CreateImpl) (void); | |||
129 | * for a set supporting a specific operation. | 138 | * for a set supporting a specific operation. |
130 | * | 139 | * |
131 | * @param set implementation-specific set state | 140 | * @param set implementation-specific set state |
132 | * @param msg element message from the client | 141 | * @param ee element message from the client |
133 | */ | 142 | */ |
134 | typedef void (*AddRemoveImpl) (struct SetState *state, struct ElementEntry *ee); | 143 | typedef void |
144 | (*AddRemoveImpl) (struct SetState *state, | ||
145 | struct ElementEntry *ee); | ||
135 | 146 | ||
136 | 147 | ||
137 | /** | 148 | /** |
138 | * Signature of functions that handle disconnection | 149 | * Signature of functions that handle disconnection of the remote |
139 | * of the remote peer. | 150 | * peer. |
140 | * | 151 | * |
141 | * @param op the set operation, contains implementation-specific data | 152 | * @param op the set operation, contains implementation-specific data |
142 | */ | 153 | */ |
143 | typedef void (*PeerDisconnectImpl) (struct Operation *op); | 154 | typedef void |
155 | (*PeerDisconnectImpl) (struct Operation *op); | ||
144 | 156 | ||
145 | 157 | ||
146 | /** | 158 | /** |
@@ -149,16 +161,18 @@ typedef void (*PeerDisconnectImpl) (struct Operation *op); | |||
149 | * | 161 | * |
150 | * @param state the set state, contains implementation-specific data | 162 | * @param state the set state, contains implementation-specific data |
151 | */ | 163 | */ |
152 | typedef void (*DestroySetImpl) (struct SetState *state); | 164 | typedef void |
165 | (*DestroySetImpl) (struct SetState *state); | ||
153 | 166 | ||
154 | 167 | ||
155 | /** | 168 | /** |
156 | * Signature of functions that implement the creation of set operations | 169 | * Signature of functions that implement the creation of set operations |
157 | * (currently evaluate and accept). | 170 | * (currently "evaluate" and "accept"). |
158 | * | 171 | * |
159 | * @param op operation that is created, should be initialized by the implementation | 172 | * @param op operation that is created, should be initialized by the implementation |
160 | */ | 173 | */ |
161 | typedef void (*OpCreateImpl) (struct Operation *op); | 174 | typedef void |
175 | (*OpCreateImpl) (struct Operation *op); | ||
162 | 176 | ||
163 | 177 | ||
164 | /** | 178 | /** |
@@ -167,24 +181,26 @@ typedef void (*OpCreateImpl) (struct Operation *op); | |||
167 | * | 181 | * |
168 | * @param op operation state | 182 | * @param op operation state |
169 | * @param msg received message | 183 | * @param msg received message |
170 | * @return GNUNET_OK on success, GNUNET_SYSERR to | 184 | * @return #GNUNET_OK on success, #GNUNET_SYSERR to |
171 | * destroy the operation and the tunnel | 185 | * destroy the operation and the tunnel |
172 | */ | 186 | */ |
173 | typedef int (*MsgHandlerImpl) (struct Operation *op, | 187 | typedef int |
174 | const struct GNUNET_MessageHeader *msg); | 188 | (*MsgHandlerImpl) (struct Operation *op, |
189 | const struct GNUNET_MessageHeader *msg); | ||
190 | |||
175 | 191 | ||
176 | /** | 192 | /** |
177 | * Signature of functions that implement operation cancellation | 193 | * Signature of functions that implement operation cancellation |
178 | * | 194 | * |
179 | * @param op operation state | 195 | * @param op operation state |
180 | */ | 196 | */ |
181 | typedef void (*CancelImpl) (struct Operation *op); | 197 | typedef void |
198 | (*CancelImpl) (struct Operation *op); | ||
182 | 199 | ||
183 | 200 | ||
184 | /** | 201 | /** |
185 | * Dispatch table for a specific set operation. | 202 | * Dispatch table for a specific set operation. Every set operation |
186 | * Every set operation has to implement the callback | 203 | * has to implement the callback in this struct. |
187 | * in this struct. | ||
188 | */ | 204 | */ |
189 | struct SetVT | 205 | struct SetVT |
190 | { | 206 | { |
@@ -224,24 +240,21 @@ struct SetVT | |||
224 | MsgHandlerImpl msg_handler; | 240 | MsgHandlerImpl msg_handler; |
225 | 241 | ||
226 | /** | 242 | /** |
227 | * Callback for handling the remote peer's | 243 | * Callback for handling the remote peer's disconnect. |
228 | * disconnect. | ||
229 | */ | 244 | */ |
230 | PeerDisconnectImpl peer_disconnect; | 245 | PeerDisconnectImpl peer_disconnect; |
231 | 246 | ||
232 | /** | 247 | /** |
233 | * Callback for canceling an operation by | 248 | * Callback for canceling an operation by its ID. |
234 | * its ID. | ||
235 | */ | 249 | */ |
236 | CancelImpl cancel; | 250 | CancelImpl cancel; |
237 | }; | 251 | }; |
238 | 252 | ||
239 | 253 | ||
240 | /** | 254 | /** |
241 | * Information about an element element in the set. | 255 | * Information about an element element in the set. All elements are |
242 | * All elements are stored in a hash-table | 256 | * stored in a hash-table from their hash-code to their `struct |
243 | * from their hash-code to their 'struct Element', | 257 | * Element`, so that the remove and add operations are reasonably |
244 | * so that the remove and add operations are reasonably | ||
245 | * fast. | 258 | * fast. |
246 | */ | 259 | */ |
247 | struct ElementEntry | 260 | struct ElementEntry |
@@ -253,10 +266,8 @@ struct ElementEntry | |||
253 | struct GNUNET_SET_Element element; | 266 | struct GNUNET_SET_Element element; |
254 | 267 | ||
255 | /** | 268 | /** |
256 | * Hash of the element. | 269 | * Hash of the element. For set union: Will be used to derive the |
257 | * For set union: | 270 | * different IBF keys for different salts. |
258 | * Will be used to derive the different IBF keys | ||
259 | * for different salts. | ||
260 | */ | 271 | */ |
261 | struct GNUNET_HashCode element_hash; | 272 | struct GNUNET_HashCode element_hash; |
262 | 273 | ||
@@ -267,32 +278,32 @@ struct ElementEntry | |||
267 | unsigned int generation_added; | 278 | unsigned int generation_added; |
268 | 279 | ||
269 | /** | 280 | /** |
270 | * GNUNET_YES if the element has been removed in some generation. | ||
271 | */ | ||
272 | int removed; | ||
273 | |||
274 | /** | ||
275 | * Generation the element was removed by the client. | 281 | * Generation the element was removed by the client. |
276 | * Operations of later generations will not consider the element. | 282 | * Operations of later generations will not consider the element. |
277 | * Only valid if is_removed is GNUNET_YES. | 283 | * Only valid if @e removed is #GNUNET_YES. |
278 | */ | 284 | */ |
279 | unsigned int generation_removed; | 285 | unsigned int generation_removed; |
280 | 286 | ||
281 | /** | 287 | /** |
282 | * GNUNET_YES if the element is a remote element, and does not belong | 288 | * #GNUNET_YES if the element has been removed in some generation. |
289 | */ | ||
290 | int removed; | ||
291 | |||
292 | /** | ||
293 | * #GNUNET_YES if the element is a remote element, and does not belong | ||
283 | * to the operation's set. | 294 | * to the operation's set. |
284 | * | ||
285 | * //TODO: Move to Union, unless additional set-operations are implemented ever | ||
286 | */ | 295 | */ |
287 | int remote; | 296 | int remote; |
288 | }; | 297 | }; |
289 | 298 | ||
290 | 299 | ||
300 | /** | ||
301 | * Operation context used to execute a set operation. | ||
302 | */ | ||
291 | struct Operation | 303 | struct Operation |
292 | { | 304 | { |
293 | /** | 305 | /** |
294 | * V-Table for the operation belonging | 306 | * V-Table for the operation belonging to the tunnel contest. |
295 | * to the tunnel contest. | ||
296 | * | 307 | * |
297 | * Used for all operation specific operations after receiving the ops request | 308 | * Used for all operation specific operations after receiving the ops request |
298 | */ | 309 | */ |
@@ -309,21 +320,8 @@ struct Operation | |||
309 | struct GNUNET_MQ_Handle *mq; | 320 | struct GNUNET_MQ_Handle *mq; |
310 | 321 | ||
311 | /** | 322 | /** |
312 | * GNUNET_YES if this is not a "real" set operation yet, and we still | 323 | * Detail information about the set operation, including the set to |
313 | * need to wait for the other peer to give us more details. | 324 | * use. When 'spec' is NULL, the operation is not yet entirely |
314 | */ | ||
315 | int is_incoming; | ||
316 | |||
317 | /** | ||
318 | * Generation in which the operation handle | ||
319 | * was created. | ||
320 | */ | ||
321 | unsigned int generation_created; | ||
322 | |||
323 | /** | ||
324 | * Detail information about the set operation, | ||
325 | * including the set to use. | ||
326 | * When 'spec' is NULL, the operation is not yet entirely | ||
327 | * initialized. | 325 | * initialized. |
328 | */ | 326 | */ |
329 | struct OperationSpecification *spec; | 327 | struct OperationSpecification *spec; |
@@ -334,65 +332,70 @@ struct Operation | |||
334 | struct OperationState *state; | 332 | struct OperationState *state; |
335 | 333 | ||
336 | /** | 334 | /** |
337 | * Evaluate operations are held in | 335 | * Evaluate operations are held in a linked list. |
338 | * a linked list. | ||
339 | */ | 336 | */ |
340 | struct Operation *next; | 337 | struct Operation *next; |
341 | 338 | ||
342 | /** | 339 | /** |
343 | * Evaluate operations are held in | 340 | * Evaluate operations are held in a linked list. |
344 | * a linked list. | 341 | */ |
345 | */ | ||
346 | struct Operation *prev; | 342 | struct Operation *prev; |
347 | 343 | ||
348 | /** | 344 | /** |
349 | * Set to GNUNET_YES if the set service should not free | 345 | * #GNUNET_YES if this is not a "real" set operation yet, and we still |
350 | * the operation, as it is still needed (e.g. in some scheduled task). | 346 | * need to wait for the other peer to give us more details. |
347 | */ | ||
348 | int is_incoming; | ||
349 | |||
350 | /** | ||
351 | * Generation in which the operation handle | ||
352 | * was created. | ||
353 | */ | ||
354 | unsigned int generation_created; | ||
355 | |||
356 | /** | ||
357 | * Set to #GNUNET_YES if the set service should not free the | ||
358 | * operation, as it is still needed (e.g. in some scheduled task). | ||
351 | */ | 359 | */ |
352 | int keep; | 360 | int keep; |
353 | }; | 361 | }; |
354 | 362 | ||
355 | 363 | ||
356 | /** | 364 | /** |
357 | * A set that supports a specific operation | 365 | * A set that supports a specific operation with other peers. |
358 | * with other peers. | ||
359 | */ | 366 | */ |
360 | struct Set | 367 | struct Set |
361 | { | 368 | { |
362 | /** | ||
363 | * Client that owns the set. | ||
364 | * Only one client may own a set. | ||
365 | */ | ||
366 | struct GNUNET_SERVER_Client *client; | ||
367 | 369 | ||
368 | /** | 370 | /** |
369 | * Message queue for the client | 371 | * Sets are held in a doubly linked list (in `sets_head` and `sets_tail`). |
370 | */ | 372 | */ |
371 | struct GNUNET_MQ_Handle *client_mq; | 373 | struct Set *next; |
372 | 374 | ||
373 | /** | 375 | /** |
374 | * Type of operation supported for this set | 376 | * Sets are held in a doubly linked list. |
375 | */ | 377 | */ |
376 | enum GNUNET_SET_OperationType operation; | 378 | struct Set *prev; |
377 | 379 | ||
378 | /** | 380 | /** |
379 | * Virtual table for this set. | 381 | * Client that owns the set. Only one client may own a set, |
380 | * Determined by the operation type of this set. | 382 | * and there can only be one set per client. |
381 | * | ||
382 | * Used only for Add/remove of elements and when receiving an incoming | ||
383 | * operation from a remote peer. | ||
384 | */ | 383 | */ |
385 | const struct SetVT *vt; | 384 | struct GNUNET_SERVER_Client *client; |
386 | 385 | ||
387 | /** | 386 | /** |
388 | * Sets are held in a doubly linked list. | 387 | * Message queue for the client. |
389 | */ | 388 | */ |
390 | struct Set *next; | 389 | struct GNUNET_MQ_Handle *client_mq; |
391 | 390 | ||
392 | /** | 391 | /** |
393 | * Sets are held in a doubly linked list. | 392 | * Virtual table for this set. Determined by the operation type of |
393 | * this set. | ||
394 | * | ||
395 | * Used only for Add/remove of elements and when receiving an incoming | ||
396 | * operation from a remote peer. | ||
394 | */ | 397 | */ |
395 | struct Set *prev; | 398 | const struct SetVT *vt; |
396 | 399 | ||
397 | /** | 400 | /** |
398 | * Implementation-specific state. | 401 | * Implementation-specific state. |
@@ -406,34 +409,39 @@ struct Set | |||
406 | struct GNUNET_CONTAINER_MultiHashMapIterator *iter; | 409 | struct GNUNET_CONTAINER_MultiHashMapIterator *iter; |
407 | 410 | ||
408 | /** | 411 | /** |
409 | * Maps 'struct GNUNET_HashCode' to 'struct ElementEntry'. | 412 | * Maps `struct GNUNET_HashCode *` to `struct ElementEntry *`. |
410 | */ | 413 | */ |
411 | struct GNUNET_CONTAINER_MultiHashMap *elements; | 414 | struct GNUNET_CONTAINER_MultiHashMap *elements; |
412 | 415 | ||
413 | /** | 416 | /** |
414 | * Current generation, that is, number of | 417 | * Evaluate operations are held in a linked list. |
415 | * previously executed operations on this set | ||
416 | */ | 418 | */ |
417 | unsigned int current_generation; | 419 | struct Operation *ops_head; |
418 | 420 | ||
419 | /** | 421 | /** |
420 | * Evaluate operations are held in | 422 | * Evaluate operations are held in a linked list. |
421 | * a linked list. | ||
422 | */ | 423 | */ |
423 | struct Operation *ops_head; | 424 | struct Operation *ops_tail; |
424 | 425 | ||
425 | /** | 426 | /** |
426 | * Evaluate operations are held in | 427 | * Current generation, that is, number of previously executed |
427 | * a linked list. | 428 | * operations on this set |
428 | */ | 429 | */ |
429 | struct Operation *ops_tail; | 430 | unsigned int current_generation; |
431 | |||
432 | /** | ||
433 | * Type of operation supported for this set | ||
434 | */ | ||
435 | enum GNUNET_SET_OperationType operation; | ||
436 | |||
430 | }; | 437 | }; |
431 | 438 | ||
432 | 439 | ||
433 | /** | 440 | /** |
434 | * Destroy the given operation. Call the implementation-specific cancel function | 441 | * Destroy the given operation. Call the implementation-specific |
435 | * of the operation. Disconnects from the remote peer. | 442 | * cancel function of the operation. Disconnects from the remote |
436 | * Does not disconnect the client, as there may be multiple operations per set. | 443 | * peer. Does not disconnect the client, as there may be multiple |
444 | * operations per set. | ||
437 | * | 445 | * |
438 | * @param op operation to destroy | 446 | * @param op operation to destroy |
439 | */ | 447 | */ |
@@ -442,8 +450,7 @@ _GSS_operation_destroy (struct Operation *op); | |||
442 | 450 | ||
443 | 451 | ||
444 | /** | 452 | /** |
445 | * Get the table with implementing functions for | 453 | * Get the table with implementing functions for set union. |
446 | * set union. | ||
447 | * | 454 | * |
448 | * @return the operation specific VTable | 455 | * @return the operation specific VTable |
449 | */ | 456 | */ |
@@ -452,8 +459,7 @@ _GSS_union_vt (void); | |||
452 | 459 | ||
453 | 460 | ||
454 | /** | 461 | /** |
455 | * Get the table with implementing functions for | 462 | * Get the table with implementing functions for set intersection. |
456 | * set intersection. | ||
457 | * | 463 | * |
458 | * @return the operation specific VTable | 464 | * @return the operation specific VTable |
459 | */ | 465 | */ |
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c index 27110077e..20fe8682b 100644 --- a/src/set/gnunet-service-set_intersection.c +++ b/src/set/gnunet-service-set_intersection.c | |||
@@ -17,7 +17,6 @@ | |||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file set/gnunet-service-set_intersection.c | 21 | * @file set/gnunet-service-set_intersection.c |
23 | * @brief two-peer set intersection | 22 | * @brief two-peer set intersection |
@@ -86,30 +85,24 @@ struct OperationState | |||
86 | struct GNUNET_CONTAINER_BloomFilter *local_bf; | 85 | struct GNUNET_CONTAINER_BloomFilter *local_bf; |
87 | 86 | ||
88 | /** | 87 | /** |
89 | * for multipart msgs we have to store the bloomfilter-data until we fully sent it. | 88 | * Iterator for sending elements on the key to element mapping to the client. |
90 | */ | ||
91 | char * bf_data; | ||
92 | |||
93 | /** | ||
94 | * size of the bloomfilter | ||
95 | */ | 89 | */ |
96 | uint32_t bf_data_size; | 90 | struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter; |
97 | 91 | ||
98 | /** | 92 | /** |
99 | * size of the bloomfilter | 93 | * Evaluate operations are held in a linked list. |
100 | */ | 94 | */ |
101 | uint32_t bf_bits_per_element; | 95 | struct OperationState *next; |
102 | 96 | ||
103 | /** | 97 | /** |
104 | * Current state of the operation. | 98 | * Evaluate operations are held in a linked list. |
105 | */ | 99 | */ |
106 | enum IntersectionOperationPhase phase; | 100 | struct OperationState *prev; |
107 | 101 | ||
108 | /** | 102 | /** |
109 | * Generation in which the operation handle | 103 | * for multipart msgs we have to store the bloomfilter-data until we fully sent it. |
110 | * was created. | ||
111 | */ | 104 | */ |
112 | unsigned int generation_created; | 105 | char *bf_data; |
113 | 106 | ||
114 | /** | 107 | /** |
115 | * Maps element-id-hashes to 'elements in our set'. | 108 | * Maps element-id-hashes to 'elements in our set'. |
@@ -117,26 +110,30 @@ struct OperationState | |||
117 | struct GNUNET_CONTAINER_MultiHashMap *my_elements; | 110 | struct GNUNET_CONTAINER_MultiHashMap *my_elements; |
118 | 111 | ||
119 | /** | 112 | /** |
120 | * Current element count contained within contained_elements | 113 | * Current element count contained within @e my_elements |
121 | */ | 114 | */ |
122 | uint32_t my_element_count; | 115 | uint32_t my_element_count; |
123 | 116 | ||
124 | /** | 117 | /** |
125 | * Iterator for sending elements on the key to element mapping to the client. | 118 | * size of the bloomfilter in @e bf_data. |
126 | */ | 119 | */ |
127 | struct GNUNET_CONTAINER_MultiHashMapIterator *full_result_iter; | 120 | uint32_t bf_data_size; |
128 | 121 | ||
129 | /** | 122 | /** |
130 | * Evaluate operations are held in | 123 | * size of the bloomfilter |
131 | * a linked list. | ||
132 | */ | 124 | */ |
133 | struct OperationState *next; | 125 | uint32_t bf_bits_per_element; |
134 | 126 | ||
135 | /** | 127 | /** |
136 | * Evaluate operations are held in | 128 | * Current state of the operation. |
137 | * a linked list. | 129 | */ |
138 | */ | 130 | enum IntersectionOperationPhase phase; |
139 | struct OperationState *prev; | 131 | |
132 | /** | ||
133 | * Generation in which the operation handle | ||
134 | * was created. | ||
135 | */ | ||
136 | unsigned int generation_created; | ||
140 | 137 | ||
141 | /** | 138 | /** |
142 | * Did we send the client that we are done? | 139 | * Did we send the client that we are done? |
@@ -237,6 +234,7 @@ iterator_initialization_by_alice (void *cls, | |||
237 | return GNUNET_YES; | 234 | return GNUNET_YES; |
238 | } | 235 | } |
239 | 236 | ||
237 | |||
240 | /** | 238 | /** |
241 | * fills the contained-elements hashmap with all relevant | 239 | * fills the contained-elements hashmap with all relevant |
242 | * elements and adds their mutated hashes to our local bloomfilter | 240 | * elements and adds their mutated hashes to our local bloomfilter |
@@ -1093,9 +1091,16 @@ intersection_op_cancel (struct Operation *op) | |||
1093 | }*/ | 1091 | }*/ |
1094 | GNUNET_free (op->state); | 1092 | GNUNET_free (op->state); |
1095 | op->state = NULL; | 1093 | op->state = NULL; |
1096 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying intersection op done\n"); | 1094 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1095 | "destroying intersection op done\n"); | ||
1097 | } | 1096 | } |
1098 | 1097 | ||
1098 | |||
1099 | /** | ||
1100 | * Get the table with implementing functions for set intersection. | ||
1101 | * | ||
1102 | * @return the operation specific VTable | ||
1103 | */ | ||
1099 | const struct SetVT * | 1104 | const struct SetVT * |
1100 | _GSS_intersection_vt () | 1105 | _GSS_intersection_vt () |
1101 | { | 1106 | { |
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index f7f94cb21..10579779b 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c | |||
@@ -478,7 +478,8 @@ op_has_element (struct Operation *op, const struct GNUNET_HashCode *element_hash | |||
478 | * @param ee the element entry | 478 | * @param ee the element entry |
479 | */ | 479 | */ |
480 | static void | 480 | static void |
481 | op_register_element (struct Operation *op, struct ElementEntry *ee) | 481 | op_register_element (struct Operation *op, |
482 | struct ElementEntry *ee) | ||
482 | { | 483 | { |
483 | int ret; | 484 | int ret; |
484 | struct IBF_Key ibf_key; | 485 | struct IBF_Key ibf_key; |
@@ -1089,7 +1090,8 @@ handle_p2p_elements (void *cls, const struct GNUNET_MessageHeader *mh) | |||
1089 | struct ElementEntry *ee; | 1090 | struct ElementEntry *ee; |
1090 | uint16_t element_size; | 1091 | uint16_t element_size; |
1091 | 1092 | ||
1092 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got element from peer\n"); | 1093 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1094 | "got element from peer\n"); | ||
1093 | 1095 | ||
1094 | if ( (op->state->phase != PHASE_EXPECT_ELEMENTS) && | 1096 | if ( (op->state->phase != PHASE_EXPECT_ELEMENTS) && |
1095 | (op->state->phase != PHASE_EXPECT_ELEMENTS_AND_REQUESTS) ) | 1097 | (op->state->phase != PHASE_EXPECT_ELEMENTS_AND_REQUESTS) ) |
@@ -1099,16 +1101,19 @@ handle_p2p_elements (void *cls, const struct GNUNET_MessageHeader *mh) | |||
1099 | return; | 1101 | return; |
1100 | } | 1102 | } |
1101 | element_size = ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader); | 1103 | element_size = ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader); |
1102 | ee = GNUNET_malloc (sizeof *ee + element_size); | 1104 | ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size); |
1103 | memcpy (&ee[1], &mh[1], element_size); | 1105 | memcpy (&ee[1], &mh[1], element_size); |
1104 | ee->element.size = element_size; | 1106 | ee->element.size = element_size; |
1105 | ee->element.data = &ee[1]; | 1107 | ee->element.data = &ee[1]; |
1106 | ee->remote = GNUNET_YES; | 1108 | ee->remote = GNUNET_YES; |
1107 | GNUNET_CRYPTO_hash (ee->element.data, ee->element.size, &ee->element_hash); | 1109 | GNUNET_CRYPTO_hash (ee->element.data, |
1110 | ee->element.size, | ||
1111 | &ee->element_hash); | ||
1108 | 1112 | ||
1109 | if (GNUNET_YES == op_has_element (op, &ee->element_hash)) | 1113 | if (GNUNET_YES == op_has_element (op, &ee->element_hash)) |
1110 | { | 1114 | { |
1111 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got existing element from peer\n"); | 1115 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1116 | "got existing element from peer\n"); | ||
1112 | GNUNET_free (ee); | 1117 | GNUNET_free (ee); |
1113 | return; | 1118 | return; |
1114 | } | 1119 | } |
@@ -1127,7 +1132,8 @@ handle_p2p_elements (void *cls, const struct GNUNET_MessageHeader *mh) | |||
1127 | * @param mh the message | 1132 | * @param mh the message |
1128 | */ | 1133 | */ |
1129 | static void | 1134 | static void |
1130 | handle_p2p_element_requests (void *cls, const struct GNUNET_MessageHeader *mh) | 1135 | handle_p2p_element_requests (void *cls, |
1136 | const struct GNUNET_MessageHeader *mh) | ||
1131 | { | 1137 | { |
1132 | struct Operation *op = cls; | 1138 | struct Operation *op = cls; |
1133 | struct IBF_Key *ibf_key; | 1139 | struct IBF_Key *ibf_key; |