- fixing channel functions
[oweals/gnunet.git] / src / ats / libgnunet_plugin_ats_mlp.h
1 /*
2  (C) 2011 Christian Grothoff (and other contributing authors)
3
4  GNUnet is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published
6  by the Free Software Foundation; either version 3, or (at your
7  option) any later version.
8
9  GNUnet is distributed in the hope that it will be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  General Public License for more details.
13
14  You should have received a copy of the GNU General Public License
15  along with GNUnet; see the file COPYING.  If not, write to the
16  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * @file ats/gnunet-service-ats-solver_mlp.h
22  * @brief ats MLP problem solver
23  * @author Matthias Wachs
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_ats_service.h"
29 #include "gnunet_ats_plugin.h"
30 #include "gnunet-service-ats_addresses.h"
31 #include "gnunet_statistics_service.h"
32 #if HAVE_LIBGLPK
33 #include "glpk.h"
34 #endif
35
36 #ifndef GNUNET_SERVICE_ATS_ADDRESSES_MLP_H
37 #define GNUNET_SERVICE_ATS_ADDRESSES_MLP_H
38
39 #define BIG_M_VALUE (UINT32_MAX) /10
40 #define BIG_M_STRING "unlimited"
41
42 #define MLP_AVERAGING_QUEUE_LENGTH 3
43
44 #define MLP_MAX_EXEC_DURATION   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10)
45 #define MLP_MAX_ITERATIONS      4096
46
47 #define DEFAULT_D 1.0
48 #define DEFAULT_R 1.0
49 #define DEFAULT_U 1.0
50 #define DEFAULT_QUALITY 1.0
51 #define DEFAULT_MIN_CONNECTIONS 4
52 #define DEFAULT_PEER_PREFERENCE 1.0
53
54 #define MLP_NaN -1
55 #define MLP_UNDEFINED 0
56 #define GLP_YES 1.0
57 #define GLP_NO  0.0
58
59 struct MLP_Solution
60 {
61   struct GNUNET_TIME_Relative build_dur;
62   struct GNUNET_TIME_Relative lp_dur;
63   struct GNUNET_TIME_Relative mip_dur;
64
65   int lp_res;
66   int lp_presolv;
67   int mip_res;
68   int mip_presolv;
69
70   int p_elements;
71   int p_cols;
72   int p_rows;
73
74   int n_peers;
75   int n_addresses;
76
77 };
78
79 struct ATS_Peer
80 {
81   struct GNUNET_PeerIdentity id;
82
83   /* Was this peer already added to the current problem? */
84   int processed;
85
86   /* constraint 2: 1 address per peer*/
87   unsigned int r_c2;
88
89   /* constraint 9: relativity */
90   unsigned int r_c9;
91
92   /* Legacy preference value */
93   double f;
94 };
95
96 struct MLP_Problem
97 {
98   /**
99    * GLPK (MLP) problem object
100    */
101 #if HAVE_LIBGLPK
102   glp_prob *prob;
103 #else
104   void *prob;
105 #endif
106
107   /* Number of addresses in problem */
108   unsigned int num_addresses;
109   /* Number of peers in problem */
110   unsigned int num_peers;
111   /* Number of elements in problem matrix */
112   unsigned int num_elements;
113
114   /* Row index constraint 2: */
115   unsigned int r_c2;
116   /* Row index constraint 4: minimum connections */
117   unsigned int r_c4;
118   /* Row index constraint 6: maximize diversity */
119   unsigned int r_c6;
120   /* Row index constraint 8: utilization*/
121   unsigned int r_c8;
122   /* Row index constraint 9: relativity*/
123   unsigned int r_c9;
124   /* Row indices quality metrics  */
125   int r_q[GNUNET_ATS_QualityPropertiesCount];
126   /* Row indices ATS network quotas */
127   int r_quota[GNUNET_ATS_NetworkTypeCount];
128
129   /* Column index Diversity (D) column */
130   int c_d;
131   /* Column index Utilization (U) column */
132   int c_u;
133   /* Column index Proportionality (R) column */
134   int c_r;
135   /* Column index quality metrics  */
136   int c_q[GNUNET_ATS_QualityPropertiesCount];
137
138   /* Problem matrix */
139   /* Current index */
140   unsigned int ci;
141   /* Row index array */
142   int *ia;
143   /* Column index array */
144   int *ja;
145   /* Column index value */
146   double *ar;
147
148 };
149
150 struct MLP_Variables
151 {
152   /* Big M value for bandwidth capping */
153   double BIG_M;
154
155   /* ATS Quality metrics
156    *
157    * Array with GNUNET_ATS_QualityPropertiesCount elements
158    * contains mapping to GNUNET_ATS_Property*/
159   int q[GNUNET_ATS_QualityPropertiesCount];
160
161   /* Number of quality metrics */
162   int m_q;
163
164   /* Number of quality metrics */
165   int m_rc;
166
167   /* Quality metric coefficients*/
168   double co_Q[GNUNET_ATS_QualityPropertiesCount];
169
170   /* Ressource costs coefficients*/
171   double co_RC[GNUNET_ATS_QualityPropertiesCount];
172
173   /* Diversity coefficient */
174   double co_D;
175
176   /* Utility coefficient */
177   double co_U;
178
179   /* Relativity coefficient */
180   double co_R;
181
182   /* Minimum bandwidth assigned to an address */
183   unsigned int b_min;
184
185   /* Minimum number of addresses with bandwidth assigned */
186   unsigned int n_min;
187
188   /* Quotas */
189   /* Array mapping array index to ATS network */
190   int quota_index[GNUNET_ATS_NetworkTypeCount];
191   /* Outbound quotas */
192   unsigned long long quota_out[GNUNET_ATS_NetworkTypeCount];
193   /* Inbound quotas */
194
195   unsigned long long quota_in[GNUNET_ATS_NetworkTypeCount];
196
197   /* ATS ressource costs
198    * array with GNUNET_ATS_QualityPropertiesCount elements
199    * contains mapping to GNUNET_ATS_Property
200    * */
201   int rc[GNUNET_ATS_QualityPropertiesCount];
202
203 };
204
205 /**
206  * MLP Handle
207  */
208 struct GAS_MLP_Handle
209 {
210   struct GNUNET_ATS_PluginEnvironment *env;
211
212   /**
213    * Statistics handle
214    */
215   struct GNUNET_STATISTICS_Handle *stats;
216
217   /**
218    * Address hashmap for lookups
219    */
220   const struct GNUNET_CONTAINER_MultiPeerMap *addresses;
221
222   /**
223    * Addresses' bandwidth changed callback
224    */
225   GAS_bandwidth_changed_cb bw_changed_cb;
226
227   /**
228    * Addresses' bandwidth changed callback closure
229    */
230   void *bw_changed_cb_cls;
231
232   /**
233    * ATS function to get preferences
234    */
235   GAS_get_preferences get_preferences;
236
237   /**
238    * Closure for ATS function to get preferences
239    */
240   void *get_preferences_cls;
241
242   /**
243    * ATS function to get properties
244    */
245   GAS_get_properties get_properties;
246
247   /**
248    * Closure for ATS function to get properties
249    */
250   void *get_properties_cls;
251
252   /**
253    * Exclude peer from next result propagation
254    */
255   const struct GNUNET_PeerIdentity *exclude_peer;
256
257   /**
258    * Encapsulation for the MLP problem
259    */
260   struct MLP_Problem p;
261
262   /**
263    * Encapsulation for the MLP problem variables
264    */
265   struct MLP_Variables pv;
266
267   /**
268    * Encapsulation for the MLP solution
269    */
270   struct MLP_Solution ps;
271
272   /**
273    * Bulk lock
274    */
275
276   int bulk_lock;
277
278   /**
279    * Number of changes while solver was locked
280    */
281   int bulk_request;
282
283   /**
284    * GLPK LP control parameter
285    */
286 #if HAVE_LIBGLPK
287   glp_smcp control_param_lp;
288 #else
289   void *control_param_lp;
290 #endif
291
292   /**
293    * GLPK LP control parameter
294    */
295 #if HAVE_LIBGLPK
296   glp_iocp control_param_mlp;
297 #else
298   void *control_param_mlp;
299 #endif
300
301   /**
302    * Peers with pending address requests
303    */
304   struct GNUNET_CONTAINER_MultiPeerMap *requested_peers;
305
306   /**
307    * Was the problem updated since last solution
308    */
309   int mlp_prob_updated;
310
311   /**
312    * Has the problem size changed since last solution
313    */
314   int mlp_prob_changed;
315
316   /**
317    * Solve the problem automatically when updates occur?
318    * Default: GNUNET_YES
319    * Can be disabled for test and measurements
320    */
321   int mlp_auto_solve;
322
323   /**
324    * Write MILP problem to a MPS file
325    */
326   int write_mip_mps;
327
328   /**
329    * Write MILP problem to a MPS file
330    */
331   int write_mip_sol;
332
333 };
334
335 /**
336  * Address specific MLP information
337  */
338 struct MLP_information
339 {
340
341   /* Bandwidth assigned */
342   struct GNUNET_BANDWIDTH_Value32NBO b_out;
343   struct GNUNET_BANDWIDTH_Value32NBO b_in;
344
345   /* Address selected */
346   int n;
347
348   /* bandwidth column index */
349   signed int c_b;
350
351   /* address usage column */
352   signed int c_n;
353
354   /* row indexes */
355
356   /* constraint 1: bandwidth capping */
357   unsigned int r_c1;
358
359   /* constraint 3: minimum bandwidth */
360   unsigned int r_c3;
361 };
362
363
364 /**
365  * Solves the MLP problem
366  *
367  * @param solver the MLP Handle
368  * @return #GNUNET_OK if could be solved, GNUNET_SYSERR on failure
369  */
370 int
371 GAS_mlp_solve_problem (void *solver);
372
373
374 /**
375  * Init the MLP problem solving component
376  *
377  * @param cfg the GNUNET_CONFIGURATION_Handle handle
378  * @param stats the GNUNET_STATISTICS handle
379  * @param network array of GNUNET_ATS_NetworkType with length dest_length
380  * @param out_dest array of outbound quotas
381  * @param in_dest array of outbound quota
382  * @param dest_length array length for quota arrays
383  * @param bw_changed_cb callback for changed bandwidth amounts
384  * @param bw_changed_cb_cls cls for callback
385  * @param get_preference callback to get relative preferences for a peer
386  * @param get_preference callback to get relative preferences for a peer
387  * @param get_properties_cls for callback to get relative properties
388  * @param get_properties_cls cls for callback to get relative properties
389  * @return struct GAS_MLP_Handle on success, NULL on fail
390  */
391 void *
392 GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
393               const struct GNUNET_STATISTICS_Handle *stats,
394     const struct GNUNET_CONTAINER_MultiPeerMap *addresses, int *network,
395     unsigned long long *out_dest, unsigned long long *in_dest, int dest_length,
396     GAS_bandwidth_changed_cb bw_changed_cb, void *bw_changed_cb_cls,
397     GAS_get_preferences get_preference, void *get_preference_cls,
398     GAS_get_properties get_properties, void *get_properties_cls);
399
400
401 /**
402  * Add a single address within a network to the solver
403  *
404  * @param solver the solver Handle
405  * @param address the address to add
406  * @param network network type of this address
407  */
408 void
409 GAS_mlp_address_add (void *solver, struct ATS_Address *address,
410     uint32_t network);
411
412
413 /**
414  * Transport properties for this address have changed
415  *
416  * @param solver solver handle
417  * @param address the address
418  * @param type the ATSI type in HBO
419  * @param abs_value the absolute value of the property
420  * @param rel_value the normalized value
421  */
422 void
423 GAS_mlp_address_property_changed (void *solver, struct ATS_Address *address,
424     uint32_t type, uint32_t abs_value, double rel_value);
425
426
427 /**
428  * Transport session for this address has changed
429  *
430  * NOTE: values in addresses are already updated
431  *
432  * @param solver solver handle
433  * @param address the address
434  * @param cur_session the current session
435  * @param new_session the new session
436  */
437 void
438 GAS_mlp_address_session_changed (void *solver, struct ATS_Address *address,
439                                  uint32_t cur_session, uint32_t new_session);
440
441
442 /**
443  * Usage for this address has changed
444  *
445  * NOTE: values in addresses are already updated
446  *
447  * @param solver solver handle
448  * @param address the address
449  * @param in_use usage state
450  */
451 void
452 GAS_mlp_address_inuse_changed (void *solver, struct ATS_Address *address,
453     int in_use);
454
455 /**
456  * Network scope for this address has changed
457  *
458  * NOTE: values in addresses are already updated
459  *
460  * @param solver solver handle
461  * @param address the address
462  * @param current_network the current network
463  * @param new_network the new network
464  */
465 void
466 GAS_mlp_address_change_network (void *solver, struct ATS_Address *address,
467     uint32_t current_network, uint32_t new_network);
468
469 /**
470  * Deletes a single address in the MLP problem
471  *
472  * The MLP problem has to be recreated and the problem has to be resolved
473  *
474  * @param solver the MLP Handle
475  * @param address the address to delete
476  * @param session_only delete only session not whole address
477  */
478 void
479 GAS_mlp_address_delete (void *solver, struct ATS_Address *address,
480     int session_only);
481
482 /**
483  * Changes the preferences for a peer in the MLP problem
484  *
485  * @param solver the MLP Handle
486  * @param peer the peer
487  * @param kind the kind to change the preference
488  * @param pref_rel the relative score
489  */
490 void
491 GAS_mlp_address_change_preference (void *solver,
492     const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind,
493     double pref_rel);
494
495 /**
496  * Get application feedback for a peer
497  *
498  * @param solver the solver handle
499  * @param application the application
500  * @param peer the peer to change the preference for
501  * @param scope the time interval for this feedback: [now - scope .. now]
502  * @param kind the kind to change the preference
503  * @param score the score
504  */
505 void
506 GAS_mlp_address_preference_feedback (void *solver, void *application,
507     const struct GNUNET_PeerIdentity *peer,
508     const struct GNUNET_TIME_Relative scope,
509     enum GNUNET_ATS_PreferenceKind kind, double score);
510
511 /**
512  * Start a bulk operation
513  *
514  * @param solver the solver
515  */
516 void
517 GAS_mlp_bulk_start (void *solver);
518
519 /**
520  * Bulk operation done
521  */
522 void
523 GAS_mlp_bulk_stop (void *solver);
524
525 /**
526  * Get the preferred address for a specific peer until
527  * GAS_mlp_stop_get_preferred_address is called
528  *
529  * @param solver the MLP Handle
530  * @param peer the peer
531  * @return suggested address
532  */
533 const struct ATS_Address *
534 GAS_mlp_get_preferred_address (void *solver,
535     const struct GNUNET_PeerIdentity *peer);
536
537 /**
538  * Stop notifying about address and bandwidth changes for this peer
539  *
540  * @param solver the MLP handle
541  * @param peer the peer
542  */
543 void
544 GAS_mlp_stop_get_preferred_address (void *solver,
545     const struct GNUNET_PeerIdentity *peer);
546
547 /**
548  * Shutdown the MLP problem solving component
549  *
550  * @param solver the solver handle
551  */
552 void
553 GAS_mlp_done (void *solver);
554
555 #endif
556 /* end of gnunet-service-ats_addresses_mlp.h */