Clarify the get_full_periods() method
The get_full_periods() method is complex and poorly named. This commit renames it to get_reserved_periods() and adds a docstring explaining its purpose. Existing code using get_full_periods() is adapted to use the new name. Change-Id: I8f75e6ba7b85700ca0b1a80c881048031981843f
This commit is contained in:
parent
51702ab808
commit
60f27853e6
|
@ -72,14 +72,14 @@ def get_reservations_by_host_id(host_id, start_date, end_date):
|
|||
|
||||
def get_free_periods(resource_id, start_date, end_date, duration):
|
||||
"""Returns a list of free periods."""
|
||||
full_periods = get_full_periods(resource_id,
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
reserved_periods = get_reserved_periods(resource_id,
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
free_periods = []
|
||||
previous = (start_date, start_date)
|
||||
if len(full_periods) >= 1:
|
||||
for period in full_periods:
|
||||
if len(reserved_periods) >= 1:
|
||||
for period in reserved_periods:
|
||||
free_periods.append((previous[1], period[0]))
|
||||
previous = period
|
||||
free_periods.append((previous[1], end_date))
|
||||
|
@ -115,56 +115,70 @@ def _get_events(host_id, start_date, end_date):
|
|||
return events
|
||||
|
||||
|
||||
def _find_full_periods(events, quantity, capacity):
|
||||
"""Find the full periods."""
|
||||
full_periods = []
|
||||
def _find_reserved_periods(events, quantity, capacity):
|
||||
"""Find the reserved periods."""
|
||||
reserved_periods = []
|
||||
used = 0
|
||||
full_start = None
|
||||
reserved_start = None
|
||||
for event_date in sorted(events):
|
||||
used += events[event_date]['quantity']
|
||||
if not full_start and used + quantity > capacity:
|
||||
full_start = event_date
|
||||
elif full_start and used + quantity <= capacity:
|
||||
full_periods.append((full_start, event_date))
|
||||
full_start = None
|
||||
return full_periods
|
||||
if not reserved_start and used + quantity > capacity:
|
||||
reserved_start = event_date
|
||||
elif reserved_start and used + quantity <= capacity:
|
||||
reserved_periods.append((reserved_start, event_date))
|
||||
reserved_start = None
|
||||
return reserved_periods
|
||||
|
||||
|
||||
def _merge_periods(full_periods, start_date, end_date, duration):
|
||||
def _merge_periods(reserved_periods, start_date, end_date, duration):
|
||||
"""Merge periods if the interval is too narrow."""
|
||||
full_start = None
|
||||
full_end = None
|
||||
reserved_start = None
|
||||
reserved_end = None
|
||||
previous = None
|
||||
merged_full_periods = []
|
||||
for period in full_periods:
|
||||
if not full_start:
|
||||
full_start = period[0]
|
||||
# Enough time between the two full periods
|
||||
merged_reserved_periods = []
|
||||
for period in reserved_periods:
|
||||
if not reserved_start:
|
||||
reserved_start = period[0]
|
||||
# Enough time between the two reserved periods
|
||||
if previous and period[0] - previous[1] >= duration:
|
||||
full_end = previous[1]
|
||||
merged_full_periods.append((full_start, full_end))
|
||||
full_start = period[0]
|
||||
full_end = period[1]
|
||||
reserved_end = previous[1]
|
||||
merged_reserved_periods.append((reserved_start, reserved_end))
|
||||
reserved_start = period[0]
|
||||
reserved_end = period[1]
|
||||
previous = period
|
||||
if previous and end_date - previous[1] < duration:
|
||||
merged_full_periods.append((full_start, end_date))
|
||||
merged_reserved_periods.append((reserved_start, end_date))
|
||||
elif previous:
|
||||
merged_full_periods.append((full_start, previous[1]))
|
||||
if (len(merged_full_periods) >= 1 and
|
||||
merged_full_periods[0][0] - start_date < duration):
|
||||
merged_full_periods[0] = (start_date, merged_full_periods[0][1])
|
||||
return merged_full_periods
|
||||
merged_reserved_periods.append((reserved_start, previous[1]))
|
||||
if (len(merged_reserved_periods) >= 1 and
|
||||
merged_reserved_periods[0][0] - start_date < duration):
|
||||
merged_reserved_periods[0] = (start_date,
|
||||
merged_reserved_periods[0][1])
|
||||
return merged_reserved_periods
|
||||
|
||||
|
||||
def get_full_periods(host_id, start_date, end_date, duration):
|
||||
"""Returns a list of full periods."""
|
||||
capacity = 1 # The resource status is binary (empty or full)
|
||||
def get_reserved_periods(host_id, start_date, end_date, duration):
|
||||
"""Returns a list of reserved periods for a host.
|
||||
|
||||
The get_reserved_periods function returns a list of periods during which
|
||||
the host passed as parameter is reserved. The duration parameter allows to
|
||||
choose the minimum length of time for a period to be considered free.
|
||||
|
||||
:param host_id: the host to consider
|
||||
:param start_date: start datetime of the entire period to consider
|
||||
:param end_date: end datetime of the entire period to consider
|
||||
:param duration: minimum length of time for a period to be considered free
|
||||
:returns: the list of reserved periods for the host, expressed as a list of
|
||||
two-element tuples, where the first element is the start datetime
|
||||
of the reserved period and the second is the end datetime
|
||||
"""
|
||||
capacity = 1 # The resource status is binary (free or reserved)
|
||||
quantity = 1 # One reservation per host at the same time
|
||||
if end_date - start_date < duration:
|
||||
return [(start_date, end_date)]
|
||||
events = _get_events(host_id, start_date, end_date)
|
||||
full_periods = _find_full_periods(events, quantity, capacity)
|
||||
return _merge_periods(full_periods, start_date, end_date, duration)
|
||||
reserved_periods = _find_reserved_periods(events, quantity, capacity)
|
||||
return _merge_periods(reserved_periods, start_date, end_date, duration)
|
||||
|
||||
|
||||
def reservation_ratio(host_id, start_date, end_date):
|
||||
|
|
|
@ -112,9 +112,10 @@ def get_free_periods(resource_id, start_date, end_date, duration):
|
|||
return IMPL.get_free_periods(resource_id, start_date, end_date, duration)
|
||||
|
||||
|
||||
def get_full_periods(resource_id, start_date, end_date, duration):
|
||||
"""Returns a list of full periods."""
|
||||
return IMPL.get_full_periods(resource_id, start_date, end_date, duration)
|
||||
def get_reserved_periods(resource_id, start_date, end_date, duration):
|
||||
"""Returns a list of reserved periods."""
|
||||
return IMPL.get_reserved_periods(resource_id, start_date, end_date,
|
||||
duration)
|
||||
|
||||
|
||||
def reservation_ratio(resource_id, start_date, end_date):
|
||||
|
|
|
@ -469,7 +469,7 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
|
|||
continue
|
||||
if (dates_before['start_date'] > dates_after['start_date'] or
|
||||
dates_before['end_date'] < dates_after['end_date']):
|
||||
full_periods = db_utils.get_full_periods(
|
||||
reserved_periods = db_utils.get_reserved_periods(
|
||||
alloc['compute_host_id'],
|
||||
dates_after['start_date'],
|
||||
dates_after['end_date'],
|
||||
|
@ -480,10 +480,10 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
|
|||
min_end = min(dates_before['end_date'],
|
||||
dates_after['end_date'])
|
||||
|
||||
if not (len(full_periods) == 0 or
|
||||
(len(full_periods) == 1 and
|
||||
full_periods[0][0] == max_start and
|
||||
full_periods[0][1] == min_end)):
|
||||
if not (len(reserved_periods) == 0 or
|
||||
(len(reserved_periods) == 1 and
|
||||
reserved_periods[0][0] == max_start and
|
||||
reserved_periods[0][1] == min_end)):
|
||||
allocs_to_remove.append(alloc)
|
||||
continue
|
||||
|
||||
|
|
|
@ -158,36 +158,36 @@ class SQLAlchemyDBUtilsTestCase(tests.DBTestCase):
|
|||
self.assertEqual(free_periods[1][1].strftime('%Y-%m-%d %H:%M'),
|
||||
'2099-01-01 00:00')
|
||||
|
||||
def test_get_full_periods(self):
|
||||
"""Find the full periods."""
|
||||
def test_get_reserved_periods(self):
|
||||
"""Find the reserved periods."""
|
||||
self._setup_leases()
|
||||
start_date = datetime.datetime.strptime('2028-01-01 08:00',
|
||||
'%Y-%m-%d %H:%M')
|
||||
end_date = datetime.datetime.strptime('2099-01-01 00:00',
|
||||
'%Y-%m-%d %H:%M')
|
||||
duration = datetime.timedelta(hours=1)
|
||||
full_periods = db_utils.get_full_periods('r1',
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
self.assertEqual(len(full_periods), 2)
|
||||
self.assertEqual(full_periods[0][0].strftime('%Y-%m-%d %H:%M'),
|
||||
reserved_periods = db_utils.get_reserved_periods('r1',
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
self.assertEqual(len(reserved_periods), 2)
|
||||
self.assertEqual(reserved_periods[0][0].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 09:00')
|
||||
self.assertEqual(full_periods[0][1].strftime('%Y-%m-%d %H:%M'),
|
||||
self.assertEqual(reserved_periods[0][1].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 10:30')
|
||||
self.assertEqual(full_periods[1][0].strftime('%Y-%m-%d %H:%M'),
|
||||
self.assertEqual(reserved_periods[1][0].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 13:00')
|
||||
self.assertEqual(full_periods[1][1].strftime('%Y-%m-%d %H:%M'),
|
||||
self.assertEqual(reserved_periods[1][1].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 14:00')
|
||||
duration = datetime.timedelta(hours=3)
|
||||
full_periods = db_utils.get_full_periods('r1',
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
self.assertEqual(len(full_periods), 1)
|
||||
self.assertEqual(full_periods[0][0].strftime('%Y-%m-%d %H:%M'),
|
||||
reserved_periods = db_utils.get_reserved_periods('r1',
|
||||
start_date,
|
||||
end_date,
|
||||
duration)
|
||||
self.assertEqual(len(reserved_periods), 1)
|
||||
self.assertEqual(reserved_periods[0][0].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 09:00')
|
||||
self.assertEqual(full_periods[0][1].strftime('%Y-%m-%d %H:%M'),
|
||||
self.assertEqual(reserved_periods[0][1].strftime('%Y-%m-%d %H:%M'),
|
||||
'2030-01-01 14:00')
|
||||
|
||||
def test_availability_time(self):
|
||||
|
|
|
@ -529,8 +529,9 @@ class PhysicalHostPluginTestCase(tests.TestCase):
|
|||
host_get_all_by_queries = self.patch(self.db_api,
|
||||
'host_get_all_by_queries')
|
||||
host_get_all_by_queries.return_value = [{'id': 'host1'}]
|
||||
get_full_periods = self.patch(self.db_utils, 'get_full_periods')
|
||||
get_full_periods.return_value = [
|
||||
get_reserved_periods = self.patch(self.db_utils,
|
||||
'get_reserved_periods')
|
||||
get_reserved_periods.return_value = [
|
||||
(datetime.datetime(2013, 12, 19, 20, 00),
|
||||
datetime.datetime(2013, 12, 19, 21, 00))
|
||||
]
|
||||
|
@ -583,8 +584,9 @@ class PhysicalHostPluginTestCase(tests.TestCase):
|
|||
host_get_all_by_queries = self.patch(self.db_api,
|
||||
'host_get_all_by_queries')
|
||||
host_get_all_by_queries.return_value = [{'id': 'host1'}]
|
||||
get_full_periods = self.patch(self.db_utils, 'get_full_periods')
|
||||
get_full_periods.return_value = [
|
||||
get_reserved_periods = self.patch(self.db_utils,
|
||||
'get_reserved_periods')
|
||||
get_reserved_periods.return_value = [
|
||||
(datetime.datetime(2013, 12, 20, 20, 30),
|
||||
datetime.datetime(2013, 12, 20, 21, 00))
|
||||
]
|
||||
|
@ -636,8 +638,9 @@ class PhysicalHostPluginTestCase(tests.TestCase):
|
|||
host_get_all_by_queries = self.patch(self.db_api,
|
||||
'host_get_all_by_queries')
|
||||
host_get_all_by_queries.return_value = [{'id': 'host1'}]
|
||||
get_full_periods = self.patch(self.db_utils, 'get_full_periods')
|
||||
get_full_periods.return_value = [
|
||||
get_reserved_periods = self.patch(self.db_utils,
|
||||
'get_reserved_periods')
|
||||
get_reserved_periods.return_value = [
|
||||
(datetime.datetime(2013, 12, 19, 20, 30),
|
||||
datetime.datetime(2013, 12, 19, 21, 00))
|
||||
]
|
||||
|
@ -698,8 +701,9 @@ class PhysicalHostPluginTestCase(tests.TestCase):
|
|||
host_allocation_destroy = self.patch(
|
||||
self.db_api,
|
||||
'host_allocation_destroy')
|
||||
get_full_periods = self.patch(self.db_utils, 'get_full_periods')
|
||||
get_full_periods.return_value = [
|
||||
get_reserved_periods = self.patch(self.db_utils,
|
||||
'get_reserved_periods')
|
||||
get_reserved_periods.return_value = [
|
||||
(datetime.datetime(2013, 12, 20, 20, 30),
|
||||
datetime.datetime(2013, 12, 20, 21, 00))
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue