TileIndex Channel::split_tile_if_needed(TileIndex ti, Tile &tile) { TileIndex new_root_index = TileIndex::null(); if (tile.binary_length() <= m_max_tile_size) return new_root_index; Tile children[2]; TileIndex child_indexes[2]; if (verbosity) log_f("split_tile_if_needed: splitting tile %s", ti.to_string().c_str()); // If we're splitting an "all" tile, it means that until now the channel has only had one tile's worth of // data, and that a proper root tile location couldn't be selected. Select a new root tile now. if (ti.is_nonnegative_all()) { // TODO: this breaks if all samples are at one time ti = new_root_index = TileIndex::index_containing(Range(tile.first_sample_time(), tile.last_sample_time())); if (verbosity) log_f("split_tile_if_needed: Moving root tile to %s", ti.to_string().c_str()); } child_indexes[0]= ti.left_child(); child_indexes[1]= ti.right_child(); double split_time = ti.right_child().start_time(); split_samples(tile.double_samples, split_time, children[0], children[1]); split_samples(tile.string_samples, split_time, children[0], children[1]); for (int i = 0; i < 2; i++) { assert(!has_tile(child_indexes[i])); assert(split_tile_if_needed(child_indexes[i], children[i]) == TileIndex::null()); write_tile(child_indexes[i], children[i]); } create_parent_tile_from_children(ti, tile, children); return new_root_index; }
void read_tile_samples(KVS &store, int uid, std::string full_channel_name, TileIndex requested_index, TileIndex client_tile_index, std::vector<DataSample<T> > &samples, bool &binned) { Channel ch(store, uid, full_channel_name); Tile tile; TileIndex actual_index; bool success = ch.read_tile_or_closest_ancestor(requested_index, actual_index, tile); if (!success) { log_f("gettile: no tile found for %s", requested_index.to_string().c_str()); } else { log_f("gettile: requested %s: found %s", requested_index.to_string().c_str(), actual_index.to_string().c_str()); for (unsigned i = 0; i < tile.get_samples<T>().size(); i++) { DataSample<T> &sample=tile.get_samples<T>()[i]; if (client_tile_index.contains_time(sample.time)) samples.push_back(sample); } } if (samples.size() <= 512) { binned = false; } else { // Bin binned = true; std::vector<DataAccumulator<T> > bins(512); for (unsigned i = 0; i < samples.size(); i++) { DataSample<T> &sample=samples[i]; bins[(int)floor(client_tile_index.position(sample.time)*512)] += sample; } samples.clear(); for (unsigned i = 0; i < bins.size(); i++) { if (bins[i].weight > 0) samples.push_back(bins[i].get_sample()); } } }
void Channel::write_tile(TileIndex ti, const Tile &tile) { std::string binary; tile.to_binary(binary); //assert(binary.size() <= m_max_tile_size); m_kvs.set(tile_key(ti), binary); total_tiles_written++; if (verbosity) log_f("Channel: write_tile %s %s: %s", descriptor().c_str(), ti.to_string().c_str(), tile.summary().c_str()); }
bool Channel::read_tile(TileIndex ti, Tile &tile) const { std::string binary; if (!m_kvs.get(tile_key(ti), binary)) return false; total_tiles_read++; tile.from_binary(binary); if (verbosity) log_f("Channel: read_tile %s %s: %s", descriptor().c_str(), ti.to_string().c_str(), tile.summary().c_str()); return true; }
void Channel::create_parent_tile_from_children(TileIndex parent_index, Tile &parent, Tile children[]) { // Subsample the children to create the parent // when do we want to show original values? // when do we want to do a real low-pass filter? // do we need to filter more than just the child tiles? e.g. gaussian beyond the tile border if (verbosity) log_f("Channel: creating parent %s from children %s, %s", parent_index.to_string().c_str(), parent_index.left_child().to_string().c_str(), parent_index.right_child().to_string().c_str()); combine_samples(BT_CHANNEL_DOUBLE_SAMPLES, parent_index, parent.double_samples, children[0].double_samples, children[1].double_samples); if (children[0].double_samples.size() + children[1].double_samples.size()) assert(parent.double_samples.size()); combine_samples(BT_CHANNEL_STRING_SAMPLES, parent_index, parent.string_samples, children[0].string_samples, children[1].string_samples); if (children[0].string_samples.size() + children[1].string_samples.size()) assert(parent.string_samples.size()); parent.ranges = children[0].ranges; parent.ranges.add(children[1].ranges); }
bool Channel::delete_tile(TileIndex ti) { return m_kvs.del(tile_key(ti)); if (verbosity) log_f("Channel: delete_tile %s %s", descriptor().c_str(), ti.to_string().c_str()); }