Author: sandervanderburg
Date: Mon Dec  6 14:04:20 2010
New Revision: 25002
URL: https://svn.nixos.org/websvn/nix/?rev=25002&sc=1

Log:
- Added minsetcover approximation algorithm, for cost efficient deployment
- Separated inverse mapping into a separate library (because minsetcover also 
needs it)

Added:
   disnix/dydisnix/trunk/src/libinvmapping/
   disnix/dydisnix/trunk/src/libinvmapping/Makefile.am
   disnix/dydisnix/trunk/src/libinvmapping/targetmapping.c
   disnix/dydisnix/trunk/src/libinvmapping/targetmapping.h
   disnix/dydisnix/trunk/src/minsetcover/
   disnix/dydisnix/trunk/src/minsetcover/Makefile.am
   disnix/dydisnix/trunk/src/minsetcover/main.c
   disnix/dydisnix/trunk/src/minsetcover/minsetcover.c
   disnix/dydisnix/trunk/src/minsetcover/minsetcover.h
Deleted:
   disnix/dydisnix/trunk/src/multiwaycut/targetmapping.c
   disnix/dydisnix/trunk/src/multiwaycut/targetmapping.h
Modified:
   disnix/dydisnix/trunk/configure.ac
   disnix/dydisnix/trunk/data/extfilters.nix.in
   disnix/dydisnix/trunk/src/Makefile.am
   disnix/dydisnix/trunk/src/multiwaycut/Makefile.am

Modified: disnix/dydisnix/trunk/configure.ac
==============================================================================
--- disnix/dydisnix/trunk/configure.ac  Mon Dec  6 13:45:07 2010        (r25001)
+++ disnix/dydisnix/trunk/configure.ac  Mon Dec  6 14:04:20 2010        (r25002)
@@ -59,7 +59,9 @@
 src/filter-buildable/Makefile
 src/divide/Makefile
 src/multiwaycut/Makefile
+src/minsetcover/Makefile
 src/libmapping/Makefile
+src/libinvmapping/Makefile
 src/libservices/Makefile
 src/libinfproperties/Makefile
 data/extfilters.nix

Modified: disnix/dydisnix/trunk/data/extfilters.nix.in
==============================================================================
--- disnix/dydisnix/trunk/data/extfilters.nix.in        Mon Dec  6 13:45:07 
2010        (r25001)
+++ disnix/dydisnix/trunk/data/extfilters.nix.in        Mon Dec  6 14:04:20 
2010        (r25002)
@@ -78,4 +78,19 @@
         dydisnix-multiwaycut ${generateDistributionXML distribution} > $out
       '';
     })}";
+
+  minsetcover = {services, infrastructure, distribution, targetProperty}:
+    import "${(pkgs.stdenv.mkDerivation {
+      name = "distribution.nix";
+      buildInputs = [ @prefix@ ];
+      buildCommand =
+      ''
+        dydisnix-minsetcover \
+         --services-xml ${generateServicesXML services} \
+         --infrastructure-xml ${generateInfrastructureXML infrastructure} \
+         --distribution-xml ${generateDistributionXML distribution} \
+         --target-property ${targetProperty} \
+         > $out
+      '';
+    })}";
 }

Modified: disnix/dydisnix/trunk/src/Makefile.am
==============================================================================
--- disnix/dydisnix/trunk/src/Makefile.am       Mon Dec  6 13:45:07 2010        
(r25001)
+++ disnix/dydisnix/trunk/src/Makefile.am       Mon Dec  6 14:04:20 2010        
(r25002)
@@ -1 +1 @@
-SUBDIRS = libservices libinfproperties libmapping filter-buildable divide 
multiwaycut
+SUBDIRS = libservices libinfproperties libmapping libinvmapping 
filter-buildable divide multiwaycut minsetcover

Added: disnix/dydisnix/trunk/src/libinvmapping/Makefile.am
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/libinvmapping/Makefile.am Mon Dec  6 14:04:20 
2010        (r25002)
@@ -0,0 +1,8 @@
+AM_CPPFLAGS=-ggdb
+
+pkglib_LTLIBRARIES = libinvmapping.la
+pkginclude_HEADERS = targetmapping.h
+
+libinvmapping_la_SOURCES = targetmapping.c
+libinvmapping_la_CFLAGS = $(LIBXML2_CFLAGS) $(GLIB_CFLAGS) -I../libmapping 
$(DISNIX_CFLAGS)
+libinvmapping_la_LIBADD = $(DISNIX_LIBS) ../libmapping/libmapping.la -lxmlutil

Added: disnix/dydisnix/trunk/src/libinvmapping/targetmapping.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/libinvmapping/targetmapping.c     Mon Dec  6 
14:04:20 2010        (r25002)
@@ -0,0 +1,128 @@
+#include "targetmapping.h"
+#include <candidatetargetmapping.h>
+
+gint compare_target_mapping_item(const TargetMappingItem **l, const 
TargetMappingItem **r)
+{
+    const TargetMappingItem *left = *l;
+    const TargetMappingItem *right = *r;
+    
+    return g_strcmp0(left->target, right->target);
+}
+
+gint target_mapping_index(GArray *target_mapping_array, gchar *target)
+{
+    gint left = 0;
+    gint right = target_mapping_array->len - 1;
+    
+    TargetMappingItem compare_mapping;
+    TargetMappingItem *compare_mapping_ptr = &compare_mapping;
+    
+    compare_mapping.target = target;
+    
+    while(left <= right)
+    {
+       gint mid = (left + right) / 2;
+       TargetMappingItem *mid_target_mapping_item = 
g_array_index(target_mapping_array, TargetMappingItem*, mid);
+        gint status = compare_target_mapping_item((const TargetMappingItem**) 
&mid_target_mapping_item, (const TargetMappingItem**) &compare_mapping_ptr);
+       
+       if(status == 0)
+            return mid; /* Return index of the found target mapping */
+       else if(status > 0)
+           right = mid - 1;
+       else if(status < 0)
+           left = mid + 1;
+    }
+    
+    return -1; /* Target mapping not found */
+}
+
+GArray *create_target_mapping_array(GArray *candidate_target_array)
+{
+    GArray *target_mapping_array = g_array_new(FALSE, FALSE, 
sizeof(TargetMappingItem*));
+    unsigned int i;
+    
+    for(i = 0; i < candidate_target_array->len; i++)
+    {
+       DistributionItem *distribution_item = 
g_array_index(candidate_target_array, DistributionItem*, i);
+       GArray *targets = distribution_item->targets;
+       unsigned int j;
+       
+       for(j = 0; j < targets->len; j++)
+       {
+           gchar *target = g_array_index(targets, gchar*, j);
+           int target_index = target_mapping_index(target_mapping_array, 
target);
+           TargetMappingItem *mapping;
+           
+           if(target_index == -1)
+           {
+               mapping = 
(TargetMappingItem*)g_malloc(sizeof(TargetMappingItem));
+               mapping->target = target;
+               mapping->services = g_array_new(FALSE, FALSE, sizeof(gchar*));
+               
+               g_array_append_val(target_mapping_array, mapping);
+               g_array_sort(target_mapping_array, 
(GCompareFunc)compare_target_mapping_item);
+           }
+           else
+               mapping = g_array_index(target_mapping_array, 
TargetMappingItem*, target_index);
+       
+           g_array_append_val(mapping->services, distribution_item->service);
+       }
+    }
+    
+    return target_mapping_array;
+}
+
+void delete_target_mapping_array(GArray *target_mapping_array)
+{
+    unsigned int i;
+    
+    for(i = 0; i < target_mapping_array->len; i++)
+    {
+       TargetMappingItem *item = g_array_index(target_mapping_array, 
TargetMappingItem*, i);
+       g_array_free(item->services, TRUE);
+       g_free(item);
+    }
+    
+    g_array_free(target_mapping_array, TRUE);
+}
+
+void print_target_mapping_array(GArray *target_mapping_array)
+{
+    unsigned int i;
+    
+    for(i = 0; i < target_mapping_array->len; i++)
+    {
+       unsigned int j;
+       TargetMappingItem *item = g_array_index(target_mapping_array, 
TargetMappingItem*, i);
+       
+       g_print("target: %s\n", item->target);
+       
+       for(j = 0; j < item->services->len; j++)
+       {
+           gchar *service = g_array_index(item->services, gchar*, j);
+           g_print("  service: %s\n", service);
+       }
+    }
+}
+
+int service_name_index(TargetMappingItem *item, gchar *service)
+{
+    gint left = 0;
+    gint right = item->services->len - 1;
+    
+    while(left <= right)
+    {
+       gint mid = (left + right) / 2;
+       gchar *mid_service = g_array_index(item->services, gchar*, mid);
+        gint status = g_strcmp0(mid_service, service);
+       
+       if(status == 0)
+            return mid; /* Return index of the found service */
+       else if(status > 0)
+           right = mid - 1;
+       else if(status < 0)
+           left = mid + 1;
+    }
+    
+    return -1; /* service not found */
+}

Added: disnix/dydisnix/trunk/src/libinvmapping/targetmapping.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/libinvmapping/targetmapping.h     Mon Dec  6 
14:04:20 2010        (r25002)
@@ -0,0 +1,23 @@
+#ifndef __SERVICE_MAPPING_H
+#define __SERVICE_MAPPING_H
+#include <glib.h>
+
+typedef struct
+{
+    gchar *target;
+    
+    GArray *services;
+}
+TargetMappingItem;
+
+GArray *create_target_mapping_array(GArray *candidate_target_array);
+
+void delete_target_mapping_array(GArray *target_mapping_array);
+
+void print_target_mapping_array(GArray *target_mapping_array);
+
+int service_name_index(TargetMappingItem *item, gchar *service);
+
+gint compare_target_mapping_item(const TargetMappingItem **l, const 
TargetMappingItem **r);
+
+#endif

Added: disnix/dydisnix/trunk/src/minsetcover/Makefile.am
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/minsetcover/Makefile.am   Mon Dec  6 14:04:20 
2010        (r25002)
@@ -0,0 +1,7 @@
+AM_CPPFLAGS = -ggdb
+
+bin_PROGRAMS = dydisnix-minsetcover
+
+dydisnix_minsetcover_SOURCES = minsetcover.c main.c
+dydisnix_minsetcover_LDADD = ../libservices/libservices.la 
../libinfproperties/libinfproperties.la ../libmapping/libmapping.la 
../libinvmapping/libinvmapping.la
+dydisnix_minsetcover_CFLAGS = -I../libservices -I../libinfproperties 
-I../libmapping -I../libinvmapping $(GLIB_CFLAGS)

Added: disnix/dydisnix/trunk/src/minsetcover/main.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/minsetcover/main.c        Mon Dec  6 14:04:20 
2010        (r25002)
@@ -0,0 +1,84 @@
+#include "minsetcover.h"
+#include <stdio.h>
+#include <getopt.h>
+#define _GNU_SOURCE
+#include <string.h>
+
+static void print_usage(char *command)
+{
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr, "%s --services-xml services.xml --infrastructure-xml 
infrastructure.xml --distribution-xml distribution.xml --target-property 
targetProperty\n", command);
+    fprintf(stderr, "%s {-h | --help}\n", command);
+}
+
+int main(int argc, char *argv[])
+{
+    /* Declarations */
+    int c, option_index = 0;
+    struct option long_options[] =
+    {
+        {"services-xml", required_argument, 0, 's'},
+       {"infrastructure-xml", required_argument, 0, 'i'},
+       {"distribution-xml", required_argument, 0, 'd'},
+       {"target-property", required_argument, 0, 'T'},
+       {"help", no_argument, 0, 'h'},
+       {0, 0, 0, 0}
+    };
+    char *services_xml = NULL;
+    char *infrastructure_xml = NULL;
+    char *distribution_xml = NULL;
+    char *target_property = NULL;
+    
+    /* Parse command-line options */
+    while((c = getopt_long(argc, argv, "h", long_options, &option_index)) != 
-1)
+    {
+       switch(c)
+       {
+           case 's':
+               services_xml = optarg;
+               break;
+           case 'i':
+               infrastructure_xml = optarg;
+               break;
+           case 'd':
+               distribution_xml = optarg;
+               break;
+           case 'T':
+               target_property = optarg;
+               break;
+           case 'h':
+               print_usage(argv[0]);
+               return 0;
+       }
+    }
+    
+    /* Validate options */
+    
+    if(services_xml == NULL)
+    {
+       fprintf(stderr, "A services XML file must be specified!\n");
+       return 1;
+    }
+    
+    if(infrastructure_xml == NULL)
+    {
+       fprintf(stderr, "An infrastructure XML file must be specified!\n");
+       return 1;
+    }
+    
+    if(distribution_xml == NULL)
+    {
+       fprintf(stderr, "A distribution XML file must be specified!\n");
+       return 1;
+    }
+    
+    if(target_property == NULL)
+    {
+       fprintf(stderr, "An target property must be specified!\n");
+       return 1;
+    }
+    
+    /* Execute operation */
+    minsetcover(services_xml, infrastructure_xml, distribution_xml, 
target_property);
+    return 0;
+}

Added: disnix/dydisnix/trunk/src/minsetcover/minsetcover.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/minsetcover/minsetcover.c Mon Dec  6 14:04:20 
2010        (r25002)
@@ -0,0 +1,95 @@
+#include "serviceproperties.h"
+#include "infrastructureproperties.h"
+#include "candidatetargetmapping.h"
+#include "targetmapping.h"
+#include <stdlib.h>
+
+void minsetcover(gchar *services_xml, gchar *infrastructure_xml, gchar 
*distribution_xml, gchar *target_property)
+{
+    GArray *service_property_array = 
create_service_property_array(services_xml);
+    GArray *infrastructure_property_array = 
create_infrastructure_property_array(infrastructure_xml);
+    GArray *candidate_target_array = 
create_candidate_target_array(distribution_xml);    
+    GHashTable *covered_services_table = g_hash_table_new(g_str_hash, 
g_str_equal);
+    GArray *target_mapping_array = 
create_target_mapping_array(candidate_target_array);
+    GArray *result = g_array_new(FALSE, FALSE, sizeof(DistributionItem*));
+    unsigned int i;
+    
+    for(i = 0; i < candidate_target_array->len; i++)
+    {
+       DistributionItem *item = g_array_index(candidate_target_array, 
DistributionItem*, i);
+       
+       DistributionItem *result_item = 
(DistributionItem*)g_malloc(sizeof(DistributionItem));
+       result_item->service = item->service;
+       result_item->targets = g_array_new(FALSE, FALSE, sizeof(gchar*));
+       
+       g_array_append_val(result, result_item);
+    }
+    
+    while(g_hash_table_size(covered_services_table) < 
service_property_array->len)
+    {
+       unsigned int i;
+       double min_cost = -1;
+       int min_cost_index = -1;
+       TargetMappingItem *min_cost_target_mapping;
+       
+       for(i = 0; i < target_mapping_array->len; i++)
+       {
+           TargetMappingItem *target_mapping = 
g_array_index(target_mapping_array, TargetMappingItem*, i);
+           int target_index = 
infrastructure_index(infrastructure_property_array, target_mapping->target);
+           Target *target = g_array_index(infrastructure_property_array, 
Target*, target_index);
+           int infrastructure_prop_index = 
infrastructure_property_index(target, target_property);
+           InfrastructureProperty *infrastructure_prop = 
g_array_index(target->property, InfrastructureProperty*, 
infrastructure_prop_index);
+           int count = 0;
+           double cost;
+           unsigned int j;
+           
+           for(j = 0; j < target_mapping->services->len; j++)
+           {
+               gchar *service_name = g_array_index(target_mapping->services, 
gchar*, j);
+               
+               if(g_hash_table_lookup(covered_services_table, service_name) == 
NULL)
+                   count++;
+           }
+           
+           cost = atoi(infrastructure_prop->value) / (double)count;
+           
+           if(min_cost == -1 || cost < min_cost)
+           {
+               min_cost = cost;
+               min_cost_index = i;
+           }
+       }
+       
+       min_cost_target_mapping = g_array_index(target_mapping_array, 
TargetMappingItem*, min_cost_index);
+       
+       for(i = 0; i < min_cost_target_mapping->services->len; i++)
+       {
+           gchar *service = g_array_index(min_cost_target_mapping->services, 
gchar*, i);
+           int index = distribution_item_index(result, service);
+           DistributionItem *item = g_array_index(result, DistributionItem*, 
index);
+           
+           g_hash_table_insert(covered_services_table, service, service);
+           
+           g_array_append_val(item->targets, min_cost_target_mapping->target);
+       }
+    }
+    
+    print_expr_of_candidate_target_array(result);
+    
+    /* Cleanup */
+    
+    for(i = 0; i < result->len; i++)
+    {
+       DistributionItem *item = g_array_index(result, DistributionItem*, i);
+       g_array_free(item->targets, TRUE);
+       g_free(item);
+    }
+    
+    g_array_free(result, TRUE);
+    
+    delete_target_mapping_array(target_mapping_array);
+    g_hash_table_destroy(covered_services_table);
+    delete_candidate_target_array(candidate_target_array);
+    delete_infrastructure_property_array(infrastructure_property_array);
+    delete_service_property_array(service_property_array);
+}

Added: disnix/dydisnix/trunk/src/minsetcover/minsetcover.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ disnix/dydisnix/trunk/src/minsetcover/minsetcover.h Mon Dec  6 14:04:20 
2010        (r25002)
@@ -0,0 +1,7 @@
+#ifndef __MINSETCOVER_H
+#define __MINSETCOVER_H
+#include <glib.h>
+
+void minsetcover(gchar *services_xml, gchar *infrastructure_xml, gchar 
*distribution_xml, gchar *target_property);
+
+#endif

Modified: disnix/dydisnix/trunk/src/multiwaycut/Makefile.am
==============================================================================
--- disnix/dydisnix/trunk/src/multiwaycut/Makefile.am   Mon Dec  6 13:45:07 
2010        (r25001)
+++ disnix/dydisnix/trunk/src/multiwaycut/Makefile.am   Mon Dec  6 14:04:20 
2010        (r25002)
@@ -2,6 +2,6 @@
 
 bin_PROGRAMS = dydisnix-multiwaycut
 
-dydisnix_multiwaycut_SOURCES = targetmapping.c multiwaycut.c main.c
-dydisnix_multiwaycut_LDADD = ../libmapping/libmapping.la
-dydisnix_multiwaycut_CFLAGS = -I../libmapping $(GLIB_CFLAGS)
+dydisnix_multiwaycut_SOURCES = multiwaycut.c main.c
+dydisnix_multiwaycut_LDADD = ../libmapping/libmapping.la 
../libinvmapping/libinvmapping.la
+dydisnix_multiwaycut_CFLAGS = -I../libmapping -I../libinvmapping $(GLIB_CFLAGS)
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits

Reply via email to