1.1 --- a/imiptools/period.py Sat May 14 00:56:54 2016 +0200
1.2 +++ b/imiptools/period.py Sat May 14 18:46:04 2016 +0200
1.3 @@ -665,7 +665,7 @@
1.4 is set to a true value.
1.5 """
1.6
1.7 - overlapping = self.get_overlapping(period)
1.8 + overlapping = self.get_overlapping([period])
1.9
1.10 if get_periods:
1.11 return overlapping
1.12 @@ -1006,35 +1006,14 @@
1.13 last = bisect_right(self.periods, Period(period.get_end(), period.get_end(), period.get_tzid()))
1.14 return self.periods[:last]
1.15
1.16 - def get_overlapping(self, period):
1.17 + def get_overlapping(self, periods):
1.18
1.19 """
1.20 Return the entries in the collection providing periods overlapping with
1.21 - 'period'.
1.22 + the given sorted collection of 'periods'.
1.23 """
1.24
1.25 - # Find the range of periods potentially overlapping the period in the
1.26 - # free/busy collection.
1.27 -
1.28 - startpoints = self.periods_until(period)
1.29 -
1.30 - # Find the range of periods potentially overlapping the period in a version
1.31 - # of the free/busy collection sorted according to end datetimes.
1.32 -
1.33 - endpoints = [(Period(fb.get_end_point(), fb.get_end_point()), fb) for fb in startpoints]
1.34 - endpoints.sort()
1.35 - first = bisect_left(endpoints, (Period(period.get_start_point(), period.get_start_point()),))
1.36 - endpoints = endpoints[first:]
1.37 -
1.38 - overlapping = set()
1.39 -
1.40 - for p, fb in endpoints:
1.41 - if fb.overlaps(period):
1.42 - overlapping.add(fb)
1.43 -
1.44 - overlapping = list(overlapping)
1.45 - overlapping.sort()
1.46 - return overlapping
1.47 + return get_overlapping(self.periods, periods)
1.48
1.49 def remove_overlapping(self, period):
1.50
1.51 @@ -1042,7 +1021,7 @@
1.52
1.53 self._check_mutable()
1.54
1.55 - overlapping = self.get_overlapping(period)
1.56 + overlapping = self.get_overlapping([period])
1.57
1.58 if overlapping:
1.59 for fb in overlapping:
1.60 @@ -1329,25 +1308,32 @@
1.61
1.62 return map(lambda t: self.make_period(t), self.cursor.fetchall())
1.63
1.64 - def get_overlapping(self, period):
1.65 + def get_overlapping(self, periods):
1.66
1.67 """
1.68 Return the entries in the collection providing periods overlapping with
1.69 - 'period'.
1.70 + the given sorted collection of 'periods'.
1.71 """
1.72
1.73 - columns, values = self._get_period_values(period)
1.74 + overlapping = set()
1.75 +
1.76 + for period in periods:
1.77 + columns, values = self._get_period_values(period)
1.78
1.79 - query, values = self.get_query(
1.80 - "select %(columns)s from %(table)s :condition" % {
1.81 - "columns" : self.columnlist(self.period_columns),
1.82 - "table" : self.table_name
1.83 - },
1.84 - columns, values)
1.85 + query, values = self.get_query(
1.86 + "select %(columns)s from %(table)s :condition" % {
1.87 + "columns" : self.columnlist(self.period_columns),
1.88 + "table" : self.table_name
1.89 + },
1.90 + columns, values)
1.91
1.92 - self.cursor.execute(query, values)
1.93 + self.cursor.execute(query, values)
1.94 +
1.95 + overlapping.update(map(lambda t: self.make_period(t), self.cursor.fetchall()))
1.96
1.97 - return map(lambda t: self.make_period(t), self.cursor.fetchall())
1.98 + overlapping = list(overlapping)
1.99 + overlapping.sort()
1.100 + return overlapping
1.101
1.102 def remove_overlapping(self, period):
1.103
1.104 @@ -1437,6 +1423,37 @@
1.105
1.106 pass
1.107
1.108 +def get_overlapping(first, second):
1.109 +
1.110 + """
1.111 + Return the entries in the sorted 'first' collection that are overlapping
1.112 + with the given sorted 'second' collection.
1.113 + """
1.114 +
1.115 + if not first or not second:
1.116 + return []
1.117 +
1.118 + # Examine each period in the second collection, attempting to match periods
1.119 + # in the first collection.
1.120 +
1.121 + overlapping = set()
1.122 +
1.123 + for p2 in second:
1.124 + last_point = p2.get_end_point()
1.125 +
1.126 + # Examine the first collection up to the point where no matches will
1.127 + # occur.
1.128 +
1.129 + for p1 in first:
1.130 + if p1.get_start_point() > last_point:
1.131 + break
1.132 + elif p1.overlaps(p2):
1.133 + overlapping.add(p1)
1.134 +
1.135 + overlapping = list(overlapping)
1.136 + overlapping.sort()
1.137 + return overlapping
1.138 +
1.139 # Period layout.
1.140
1.141 def get_scale(periods, tzid, view_period=None):