From f29b7f51a90b728d81291fe64698a31f56408373 Mon Sep 17 00:00:00 2001
From: Pradyumna Kaushik <pkaushi1@binghamton.edu>
Date: Wed, 23 Aug 2017 19:35:19 -0400
Subject: [PATCH] Added a generic task sorter utility. This allows for an array
 of tasks to be sorted based on any resource. The possible resources by which
 an array of tasks can be sorted currently are listed in
 def/sortingCriteria.go. One can add more to this if required.

---
 def/sortingCriteria.go | 29 +++++++++++++++++++++++++++++
 def/taskUtils.go       | 15 +++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 def/sortingCriteria.go

diff --git a/def/sortingCriteria.go b/def/sortingCriteria.go
new file mode 100644
index 0000000..fadf562
--- /dev/null
+++ b/def/sortingCriteria.go
@@ -0,0 +1,29 @@
+package def
+
+// Creating an enumeration of the resources in def.Task.
+var TaskResourceNames []string
+
+type SortCriteria int
+
+// Map a task's resource name to the sorting criteria (an integer corresponding to the enumeration).
+func resourceToSortCriteria(resourceName string) SortCriteria {
+	// Appending resourceName to TaskResourceNames.
+	TaskResourceNames = append(TaskResourceNames, resourceName)
+
+	// Considering index of resource in TaskResourceNames to be the int mapping.
+	return SortCriteria(len(TaskResourceNames) - 1)
+}
+
+func (sc SortCriteria) String() string {
+	return TaskResourceNames[int(sc)]
+}
+
+// Possible Sorting Criteria
+// Note: the value of the string passed as argument to resourceToSortCriteria() should be the same (case-sensitive)
+// 	as the name of the of the corresponding resource in the struct.
+var (
+	CPU = resourceToSortCriteria("CPU")
+	RAM = resourceToSortCriteria("RAM")
+	Watts = resourceToSortCriteria("Watts")
+	Instances = resourceToSortCriteria("Instances")
+)
diff --git a/def/taskUtils.go b/def/taskUtils.go
index 2b56be3..5dbeb4a 100644
--- a/def/taskUtils.go
+++ b/def/taskUtils.go
@@ -4,6 +4,7 @@ import (
 	"github.com/mdesenfants/gokmeans"
 	"sort"
 	"log"
+	"reflect"
 )
 
 // Information about a cluster of tasks
@@ -114,3 +115,17 @@ func labelAndOrder(clusters map[int][]Task, numberOfClusters int, taskObservatio
 	})
 	return sizedClusters
 }
+
+// Generic Task Sorter.
+// Be able to sort an array of tasks based on any of the tasks' resources.
+
+// Retrieve a sorter (same signature as 'Less' function in sort.Interface) for the given sorting criteria.
+func TaskSorter(sc SortCriteria, tasks []Task) func (i, j int) bool {
+	return func (i, j int) bool {
+		taskIFields := reflect.Indirect(reflect.ValueOf(tasks[i]))
+		tasksJFields := reflect.Indirect(reflect.ValueOf(tasks[j]))
+		resourceI := taskIFields.FieldByName(sc.String()).Float()
+		resourceJ := tasksJFields.FieldByName(sc.String()).Float()
+		return resourceI <= resourceJ
+	}
+}