TileIndex Channel::find_child_overlapping_time(TileIndex ti, double t, int desired_level) const { assert(!ti.is_null()); // Start at root tile and move downwards while (ti.level > desired_level) { // Select correct child TileIndex child = t < ti.left_child().end_time() ? ti.left_child() : ti.right_child(); if (child.is_null() || !tile_exists(child)) break; ti = child; } return ti; }
void Channel::read_bottommost_tiles_in_range(Range times, bool (*callback)(const Tile &t, Range times)) const { ChannelInfo info; bool success = read_info(info); if (!success) return; if (!info.times.intersects(times)) return; double time = times.min; TileIndex ti = TileIndex::null(); while (time < times.max) { if (ti.is_null()) { ti = find_lowest_child_overlapping_time(info.nonnegative_root_tile_index, times.min); } else { ti = find_lowest_successive_tile(info.nonnegative_root_tile_index, ti); } if (ti.is_null() || ti.start_time() >= times.max) break; Tile t; assert(read_tile(ti, t)); if (!(*callback)(t, times)) break; } }
void Channel::read_data(std::vector<DataSample<double> > &data, double begin, double end) const { double time = begin; data.clear(); Locker lock(*this); // Lock self and hold lock until exiting this method ChannelInfo info; bool success = read_info(info); if (!success) { // Channel doesn't yet exist; no data if (verbosity) log_f("read_data: can't read info"); return; } bool first_tile = true; while (time < end) { TileIndex ti = find_lowest_child_overlapping_time(info.nonnegative_root_tile_index, time); if (ti.is_null()) { // No tiles; no more data if (verbosity) log_f("read_data: can't read tile"); return; } Tile tile; assert(read_tile(ti, tile)); unsigned i = 0; if (first_tile) { // Skip any samples before requested time for (; i < tile.double_samples.size() && tile.double_samples[i].time < begin; i++); } for (; i < tile.double_samples.size() && tile.double_samples[i].time < end; i++) { data.push_back(tile.double_samples[i]); } time = ti.end_time(); } }