aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-service-fs_pe.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-02-07 22:44:36 +0000
committerChristian Grothoff <christian@grothoff.org>2011-02-07 22:44:36 +0000
commit86d7f49fc64f0c766d4bec6b3f34879f108fc8a9 (patch)
treeb8472cd2eeeacc601513f36bc03149ec9151db03 /src/fs/gnunet-service-fs_pe.c
parentde952b871bfe79a7f2b79d9ab04dc37933d49bf1 (diff)
downloadgnunet-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.c191
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 */
34static 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 */
43static struct GNUNET_CONTAINER_Heap *
44get_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 */
38void 63void
39GSF_plan_add_ (struct GSF_ConnectedPeer *cp, 64GSF_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 */
53void 95void
54GSF_plan_notify_peer_disconnect_ (struct GSF_ConnectedPeer *cp) 96GSF_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 */
115struct 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 */
139static int
140find_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 */
165static int
166remove_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 */
66void 195void
67GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr) 196GSF_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 */
80struct GSF_PendingRequest * 211struct GSF_PendingRequest *
81GSF_plan_get_ (struct GSF_ConnectedPeer *cp) 212GSF_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 */
93unsigned int 230unsigned int
94GSF_plan_size_ (struct GSF_ConnectedPeer *cp) 231GSF_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 */
246void
247GSF_plan_init ()
248{
249 plans = GNUNET_CONTAINER_multihashmap_create (256);
250}
251
252
253/**
254 * Shutdown plan subsystem.
255 */
256void
257GSF_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