diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-02-07 22:44:36 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-02-07 22:44:36 +0000 |
commit | 86d7f49fc64f0c766d4bec6b3f34879f108fc8a9 (patch) | |
tree | b8472cd2eeeacc601513f36bc03149ec9151db03 /src/fs/gnunet-service-fs_pe.c | |
parent | de952b871bfe79a7f2b79d9ab04dc37933d49bf1 (diff) | |
download | gnunet-86d7f49fc64f0c766d4bec6b3f34879f108fc8a9.tar.gz gnunet-86d7f49fc64f0c766d4bec6b3f34879f108fc8a9.zip |
stuff
Diffstat (limited to 'src/fs/gnunet-service-fs_pe.c')
-rw-r--r-- | src/fs/gnunet-service-fs_pe.c | 191 |
1 files changed, 178 insertions, 13 deletions
diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c index ec6f315ff..6797a13fb 100644 --- a/src/fs/gnunet-service-fs_pe.c +++ b/src/fs/gnunet-service-fs_pe.c | |||
@@ -24,8 +24,33 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet-service-fs_cp.h" | ||
27 | #include "gnunet-service-fs_pe.h" | 28 | #include "gnunet-service-fs_pe.h" |
28 | 29 | ||
30 | /** | ||
31 | * Hash map from peer identities to GNUNET_CONTAINER_Heap's with | ||
32 | * pending requests as entries. | ||
33 | */ | ||
34 | static struct GNUNET_CONTAINER_MultiHashMap *plans; | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Get the size of the request queue for the given peer. | ||
39 | * | ||
40 | * @param cp connected peer to query | ||
41 | * @return number of entries in this peer's request queue | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_Heap * | ||
44 | get_heap (const struct GSF_ConnectedPeer *cp) | ||
45 | { | ||
46 | struct GNUNET_CONTAINER_Heap *h; | ||
47 | struct GNUNET_PeerIdentity id; | ||
48 | |||
49 | GSF_connected_peer_get_identity_ (cp, &id); | ||
50 | return GNUNET_CONTAINER_multihashmap_get (plans, | ||
51 | &id.hashPubKey); | ||
52 | } | ||
53 | |||
29 | 54 | ||
30 | /** | 55 | /** |
31 | * Create a new query plan entry. | 56 | * Create a new query plan entry. |
@@ -36,11 +61,28 @@ | |||
36 | * lower weights are earlier in the queue | 61 | * lower weights are earlier in the queue |
37 | */ | 62 | */ |
38 | void | 63 | void |
39 | GSF_plan_add_ (struct GSF_ConnectedPeer *cp, | 64 | GSF_plan_add_ (const struct GSF_ConnectedPeer *cp, |
40 | struct GSF_PendingRequest *pr, | 65 | struct GSF_PendingRequest *pr, |
41 | double weight) | 66 | GNUNET_CONTAINER_HeapCostType weight) |
42 | { | 67 | { |
43 | // FIXME | 68 | struct GNUNET_PeerIdentity id; |
69 | struct GNUNET_CONTAINER_Heap *h; | ||
70 | struct GSF_PendingRequest *pr; | ||
71 | |||
72 | GSF_connected_peer_get_identity_ (cp, &id); | ||
73 | h = GNUNET_CONTAINER_multihashmap_get (plans, | ||
74 | &id.hashPubKey); | ||
75 | if (NULL == h) | ||
76 | { | ||
77 | h = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
78 | GNUNET_CONTAINER_multihashmap_put (plans, | ||
79 | &id.hashPubKey, | ||
80 | h, | ||
81 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
82 | } | ||
83 | GNUNET_CONTAINER_heap_insert (h, | ||
84 | pr, | ||
85 | weight); | ||
44 | } | 86 | } |
45 | 87 | ||
46 | 88 | ||
@@ -51,22 +93,111 @@ GSF_plan_add_ (struct GSF_ConnectedPeer *cp, | |||
51 | * @param cp connected peer | 93 | * @param cp connected peer |
52 | */ | 94 | */ |
53 | void | 95 | void |
54 | GSF_plan_notify_peer_disconnect_ (struct GSF_ConnectedPeer *cp) | 96 | GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp) |
55 | { | 97 | { |
56 | // FIXME | 98 | struct GNUNET_PeerIdentity id; |
99 | struct GNUNET_CONTAINER_Heap *h; | ||
100 | struct GSF_PendingRequest *pr; | ||
101 | |||
102 | GSF_connected_peer_get_identity_ (cp, &id); | ||
103 | h = GNUNET_CONTAINER_multihashmap_get (plans, | ||
104 | &id.hashPubKey); | ||
105 | GNUNET_CONTAINER_multihashmap_remove (plans, | ||
106 | &id.hashPubKey, | ||
107 | h); | ||
108 | GNUNET_CONTAINER_heap_destroy (h); | ||
57 | } | 109 | } |
58 | 110 | ||
59 | 111 | ||
60 | /** | 112 | /** |
61 | * Notify the plan about a request being done; | 113 | * Closure for 'find_request'. |
62 | * destroy all entries associated with this request. | 114 | */ |
115 | struct FindRequestClosure | ||
116 | { | ||
117 | /** | ||
118 | * Place to store the node that was found (NULL for none). | ||
119 | */ | ||
120 | struct GNUNET_CONTAINER_HeapNode *node; | ||
121 | |||
122 | /** | ||
123 | * Value we're looking for | ||
124 | */ | ||
125 | const struct GSF_PendingRequest *pr; | ||
126 | }; | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Find a heap node where the value matches the | ||
131 | * pending request given in the closure. | ||
132 | * | ||
133 | * @param cls the 'struct FindRequestClosure' | ||
134 | * @param node heap structure we're looking for on a match | ||
135 | * @param element the pending request stored in the heap | ||
136 | * @param cost weight of the request | ||
137 | * @return GNUNET_YES to continue looking | ||
138 | */ | ||
139 | static int | ||
140 | find_request (void *cls, | ||
141 | struct GNUNET_CONTAINER_HeapNode *node, | ||
142 | void *element, | ||
143 | GNUNET_CONTAINER_HeapCostType cost) | ||
144 | { | ||
145 | struct FindRequestClosure *frc = cls; | ||
146 | struct GSF_PendingRequest *pr = element; | ||
147 | |||
148 | if (pr == frc->pr) | ||
149 | { | ||
150 | frc->node = node; | ||
151 | return GNUNET_NO; | ||
152 | } | ||
153 | return GNUNET_YES; | ||
154 | } | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Remove the given request from all heaps. * | ||
159 | * | ||
160 | * @param cls 'struct GSF_PendingRequest' to purge | ||
161 | * @param key identity of the peer we're currently looking at (unused) | ||
162 | * @param value request heap for the given peer to search for the 'cls' | ||
163 | * @return GNUNET_OK (continue iteration) | ||
164 | */ | ||
165 | static int | ||
166 | remove_request (void *cls, | ||
167 | const GNUNET_HashCode *key, | ||
168 | void *value) | ||
169 | { | ||
170 | const struct GSF_PendingRequest *pr = cls; | ||
171 | struct GNUNET_CONTAINER_Heap *h = value; | ||
172 | struct FindRequestClosure frc; | ||
173 | |||
174 | frc.pr = pr; | ||
175 | do | ||
176 | { | ||
177 | frc.node = NULL; | ||
178 | GNUNET_CONTAINER_heap_iterate (h, &find_request, &frc); | ||
179 | if (frc.node != NULL) | ||
180 | GNUNET_CONTAINER_heap_remove_node (h, frc.node); | ||
181 | } | ||
182 | while (NULL != frc.node); | ||
183 | return GNUNET_OK; | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Notify the plan about a request being done; destroy all entries | ||
189 | * associated with this request. Note that this implementation is | ||
190 | * currently terribly inefficient (O(n)) and could instead be done in | ||
191 | * O(1). But for now, I first want to see it work correctly... | ||
63 | * | 192 | * |
64 | * @param pr request that is done | 193 | * @param pr request that is done |
65 | */ | 194 | */ |
66 | void | 195 | void |
67 | GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr) | 196 | GSF_plan_notify_request_done_ (const struct GSF_PendingRequest *pr) |
68 | { | 197 | { |
69 | // FIXME | 198 | GNUNET_CONTAINER_multihashmap_iterate (plans, |
199 | &remove_request, | ||
200 | (void*) pr); | ||
70 | } | 201 | } |
71 | 202 | ||
72 | 203 | ||
@@ -78,9 +209,15 @@ GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr) | |||
78 | * @return NULL if the queue for this peer is empty | 209 | * @return NULL if the queue for this peer is empty |
79 | */ | 210 | */ |
80 | struct GSF_PendingRequest * | 211 | struct GSF_PendingRequest * |
81 | GSF_plan_get_ (struct GSF_ConnectedPeer *cp) | 212 | GSF_plan_get_ (const struct GSF_ConnectedPeer *cp) |
82 | { | 213 | { |
83 | return NULL; // FIXME | 214 | struct GNUNET_CONTAINER_Heap *h; |
215 | struct GSF_PendingRequest *pr; | ||
216 | |||
217 | h = get_heap (cp); | ||
218 | if (NULL == h) | ||
219 | return NULL; | ||
220 | return GNUNET_CONTAINER_heap_remove_root (h); | ||
84 | } | 221 | } |
85 | 222 | ||
86 | 223 | ||
@@ -91,9 +228,37 @@ GSF_plan_get_ (struct GSF_ConnectedPeer *cp) | |||
91 | * @return number of entries in this peer's request queue | 228 | * @return number of entries in this peer's request queue |
92 | */ | 229 | */ |
93 | unsigned int | 230 | unsigned int |
94 | GSF_plan_size_ (struct GSF_ConnectedPeer *cp) | 231 | GSF_plan_size_ (const struct GSF_ConnectedPeer *cp) |
232 | { | ||
233 | struct GNUNET_CONTAINER_Heap *h; | ||
234 | |||
235 | h = get_heap (cp); | ||
236 | if (NULL == h) | ||
237 | return 0; | ||
238 | return GNUNET_CONTAINER_heap_get_size (h); | ||
239 | } | ||
240 | |||
241 | |||
242 | |||
243 | /** | ||
244 | * Initialize plan subsystem. | ||
245 | */ | ||
246 | void | ||
247 | GSF_plan_init () | ||
248 | { | ||
249 | plans = GNUNET_CONTAINER_multihashmap_create (256); | ||
250 | } | ||
251 | |||
252 | |||
253 | /** | ||
254 | * Shutdown plan subsystem. | ||
255 | */ | ||
256 | void | ||
257 | GSF_plan_done () | ||
95 | { | 258 | { |
96 | return 0; // FIXME | 259 | GNUNET_assert (0 == |
260 | GNUNET_CONTAINER_multihashmap_get_size (plans)); | ||
261 | GNUNET_CONTAINER_multihashmap_destroy (plans); | ||
97 | } | 262 | } |
98 | 263 | ||
99 | 264 | ||