2006-02-23 11:12:27 +01:00
|
|
|
from Abstract import *
|
2006-02-22 23:57:32 +01:00
|
|
|
|
|
|
|
## @brief This is the abstract class a user-defined policy
|
|
|
|
# should inherit from
|
2006-02-22 22:35:26 +01:00
|
|
|
#
|
2006-02-22 23:57:32 +01:00
|
|
|
# This class also exposes the method sort, which can be
|
|
|
|
# used to easily sort the queue of ready process with a
|
|
|
|
# given compare function
|
2006-02-21 11:31:01 +01:00
|
|
|
class Policy:
|
2006-02-19 17:22:53 +01:00
|
|
|
## @var Avoid instantiation of an abstract class
|
2006-02-16 23:50:32 +01:00
|
|
|
__metaclass__ = Metaclass
|
|
|
|
|
|
|
|
configure = AbstractMethod('configure')
|
|
|
|
sort_queue = AbstractMethod('sort_queue')
|
|
|
|
is_preemptive = AbstractMethod('is_preemptive')
|
2006-02-22 16:16:08 +01:00
|
|
|
get_time_slice = AbstractMethod('get_time_slice')
|
2006-02-21 11:31:01 +01:00
|
|
|
|
2006-02-22 23:57:32 +01:00
|
|
|
## @brief this function implements a quicksort in place
|
|
|
|
# using the SchedulableQueue methods
|
|
|
|
#
|
|
|
|
# The compare parameter should be a user defined function
|
|
|
|
# name returning either True or False, defined like:
|
|
|
|
# @code
|
|
|
|
# def compare(SchedulableA,SchedulableB):
|
|
|
|
# return SchedulableA.someProperty() < SchedulableB.someProperty()
|
|
|
|
# @endcode
|
|
|
|
#
|
|
|
|
# @param queue The SchedulableQueue to be sorted in place
|
|
|
|
# @param cmpf The binary function to use to compare elements
|
|
|
|
# @returns None
|
2006-02-23 11:12:27 +01:00
|
|
|
def sort(self, queue, cmpf):
|
|
|
|
self.__recursive_qsort(queue, 0, queue.size()-1, cmpf)
|
2006-02-22 23:57:32 +01:00
|
|
|
|
|
|
|
## @brief Recursive (private) call to perform quicksort on a
|
|
|
|
# queue
|
|
|
|
#
|
|
|
|
# @param queue The queue to sort
|
|
|
|
# @param a The initial element position of the slice
|
|
|
|
# @param b The final element position of the slice
|
|
|
|
# @param cmpf The user-defined compare function to employ
|
|
|
|
# @returns None
|
2006-02-23 11:12:27 +01:00
|
|
|
def __recursive_qsort(self, queue, a, b, cmpf):
|
2006-02-22 23:57:32 +01:00
|
|
|
if(b>a):
|
2006-02-23 11:12:27 +01:00
|
|
|
pivot = self.__partition(queue, a, b, cmpf)
|
|
|
|
self.__recursive_qsort(queue, a, pivot-1, cmpf)
|
|
|
|
self.__recursive_qsort(queue, pivot+1, b, cmpf)
|
|
|
|
|
2006-02-22 23:57:32 +01:00
|
|
|
## @brief Recursive (private) call to partition a slice of the queue
|
|
|
|
#
|
|
|
|
# This private function (the name mangling should work)
|
|
|
|
# naively sorts a partition of queue in place using just
|
|
|
|
# its methods.
|
|
|
|
#
|
|
|
|
# Feel the love.
|
|
|
|
#
|
|
|
|
# @param queue The SchedulableQueue to sort
|
|
|
|
# @param a The partition starting element position in the queue
|
|
|
|
# @param b The partition ending element position in the queue
|
|
|
|
# @param cmpf The binary function to use for comparing two elements
|
|
|
|
# @return The new pivot index
|
2006-02-23 11:12:27 +01:00
|
|
|
def __partition_(self, queue, a, b, cmpf):
|
2006-02-22 23:57:32 +01:00
|
|
|
# takes pivot element:
|
|
|
|
right = queue.get_item_at(b)
|
|
|
|
i = a
|
2006-02-23 11:12:27 +01:00
|
|
|
for j in range(a,b): # goes from a to b-1
|
2006-02-22 23:57:32 +01:00
|
|
|
if cmpf(queue.get_item_at(j), right):
|
|
|
|
# the C++ code should do nothing if i == j:
|
|
|
|
queue.swap(i,j)
|
|
|
|
i = i+1
|
|
|
|
# puts pivot in place
|
|
|
|
queue.swap(i,b)
|
|
|
|
return i
|