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