getTracked does not need to read in entire database

Related to issue #245.
This commit is contained in:
Shaun Ruffell 2019-12-02 21:52:19 -06:00 committed by lauft
parent e9f860d8ce
commit 86bb1465e8

View file

@ -24,6 +24,9 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <deque>
#include <cassert>
#include <cmake.h> #include <cmake.h>
#include <shared.h> #include <shared.h>
#include <format.h> #include <format.h>
@ -321,6 +324,19 @@ std::vector <Interval> getAllInclusions (Database& database)
return all; return all;
} }
////////////////////////////////////////////////////////////////////////////////
std::vector <Interval> subset (
const Interval& filter,
const std::deque <Interval>& intervals)
{
std::vector <Interval> all;
for (auto& interval : intervals)
if (matchesFilter (interval, filter))
all.push_back (interval);
return all;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <Interval> subset ( std::vector <Interval> subset (
const Interval& filter, const Interval& filter,
@ -573,8 +589,6 @@ std::vector <Interval> getTracked (
const Rules& rules, const Rules& rules,
Interval& filter) Interval& filter)
{ {
auto inclusions = getAllInclusions (database);
// Exclusions are only usable within a range, so if no filter range exists, // Exclusions are only usable within a range, so if no filter range exists,
// determine the infinite range starting at the first inclusion, i.e.: // determine the infinite range starting at the first inclusion, i.e.:
// //
@ -583,9 +597,12 @@ std::vector <Interval> getTracked (
// Avoid assigning a zero-width range - leave it unstarted instead. // Avoid assigning a zero-width range - leave it unstarted instead.
if (! filter.is_started ()) if (! filter.is_started ())
{ {
auto outer = outerRange (inclusions); auto begin = database.begin ();
if (outer.total ()) auto end = database.end ();
filter.setRange (outer); if (begin != end)
{
filter.start = IntervalFactory::fromSerialization (*begin).start;
}
// Use an infinite range instead of the last end date; this prevents // Use an infinite range instead of the last end date; this prevents
// issues when there is an empty range [q, q) at the end of a filter // issues when there is an empty range [q, q) at the end of a filter
@ -593,11 +610,35 @@ std::vector <Interval> getTracked (
filter.end = 0; filter.end = 0;
} }
std::vector <Interval> intervals = inclusions; int id_skip = 0;
std::deque <Interval> intervals;
auto it = database.rbegin ();
auto end = database.rend ();
for (; it != end; ++it)
{
Interval interval = IntervalFactory::fromSerialization(*it);
// Since we are moving backwards, and the intervals are in sorted order,
// if the filter is after the interval, we know there will be no more
// matches
if (matchesFilter (interval, filter))
{
intervals.push_front (interval);
}
else if (interval.start.toEpoch () >= filter.start.toEpoch ())
{
++id_skip;
}
else
{
break;
}
}
if (! intervals.empty ()) if (! intervals.empty ())
{ {
auto latest = inclusions.back (); auto latest = intervals.back ();
if (latest.is_open ()) if (latest.is_open ())
{ {
@ -625,7 +666,7 @@ std::vector <Interval> getTracked (
// Assign an ID to each interval. // Assign an ID to each interval.
for (unsigned int i = 0; i < intervals.size (); ++i) for (unsigned int i = 0; i < intervals.size (); ++i)
intervals[i].id = intervals.size () - i; intervals[i].id = intervals.size () - i + id_skip;
debug (format ("Loaded {1} tracked intervals", intervals.size ())); debug (format ("Loaded {1} tracked intervals", intervals.size ()));
return subset (filter, intervals); return subset (filter, intervals);