TileIndex Channel::find_successive_tile(TileIndex root, TileIndex ti, int desired_level) const { // Move upwards until parent has a different end time while (1) { if (ti.parent().is_null()) return TileIndex::null(); if (ti.parent().end_time() != ti.end_time()) break; ti = ti.parent(); if (ti.level >= root.level) { // No more underneath the root return TileIndex::null(); } } // We are now the left child of our parent; skip to the right child ti = ti.sibling(); return find_child_overlapping_time(ti, ti.start_time(), desired_level); }
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(); } }