TEST(Type, CanRunDtor) { TypeSet types = allTypes(); auto expectTrue = [&](Type t) { EXPECT_TRUE(t.canRunDtor()) << t.toString() << ".canRunDtor() == true"; types.erase(t); }; expectTrue(Type::Arr); expectTrue(Type::CountedArr); expectTrue(Type::Obj); expectTrue(Type::Res); expectTrue(Type::Counted); expectTrue(Type::BoxedArr); expectTrue(Type::BoxedCountedArr); expectTrue(Type::BoxedObj); expectTrue(Type::BoxedRes); expectTrue(Type::BoxedCell); expectTrue(Type::Cell); expectTrue(Type::Gen); expectTrue(Type::Ctx); expectTrue(Type::Obj | Type::Func); expectTrue(Type::Init); expectTrue(Type::Top); expectTrue(Type::StackElem); expectTrue(Type::AnyObj); expectTrue(Type::AnyRes); expectTrue(Type::AnyArr); expectTrue(Type::AnyCountedArr); expectTrue(Type::AnyCell); for (Type t : types) { EXPECT_FALSE(t.canRunDtor()) << t.toString() << ".canRunDtor == false"; } }
bool TypeInferenceOracle::canEnterInlinedFunction(HandleScript caller, jsbytecode *pc, JSFunction *target) { AssertCanGC(); RootedScript targetScript(cx, target->nonLazyScript()); if (!targetScript->hasAnalysis() || !targetScript->analysis()->ranInference()) return false; if (!targetScript->analysis()->ionInlineable()) return false; if (targetScript->analysis()->usesScopeChain()) return false; if (target->getType(cx)->unknownProperties()) return false; JSOp op = JSOp(*pc); TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript); TypeSet *callReturn = getCallReturn(caller, pc); if (op == JSOP_NEW) { if (!returnTypes->isSubsetIgnorePrimitives(callReturn)) return false; } else { if (!returnTypes->isSubset(callReturn)) return false; } // TI calls ObjectStateChange to trigger invalidation of the caller. HeapTypeSet::WatchObjectStateChange(cx, target->getType(cx)); return true; }
void StyleConfig::GetAreaTypesWithMag(double mag, TypeSet& types) const { types.Reset(areaMag.size()); for (size_t i=0; i<areaMag.size(); i++) { if (mag>=areaMag[i]) { types.SetType(i); } } }
TypeSet getGreatestCommonSubtypes(const TypeSet& set) { // handle the empty set if (set.empty()) return set; // handle the all set => empty set (since no common sub-type) if (set.isAll()) return TypeSet(); TypeSet res; auto it = set.begin(); res.insert(*it); ++it; // refine sub-set step by step for(;it != set.end(); ++it) { TypeSet tmp; for(const Type& cur : res) { tmp.insert(getGreatestCommonSubtypes(cur, *it)); } res = tmp; } // done return res; }
bool TypeInferenceOracle::canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction target) { RootedScript targetScript(cx, target->nonLazyScript()); // Make sure empty script has type information, to allow inlining in more cases. if (targetScript->length == 1) { if (!targetScript->ensureRanInference(cx)) return false; } if (!targetScript->hasAnalysis() || !targetScript->analysis()->ranInference() || !targetScript->analysis()->ranSSA()) { return false; } if (!targetScript->analysis()->ionInlineable()) return false; if (targetScript->needsArgsObj()) return false; if (!targetScript->compileAndGo) return false; if (targetScript->analysis()->usesScopeChain()) return false; types::TypeObject *targetType = target->getType(cx); if (!targetType || targetType->unknownProperties()) return false; JSOp op = JSOp(*pc); TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript); TypeSet *callReturn = getCallReturn(caller, pc); if (op == JSOP_NEW) { if (!returnTypes->isSubsetIgnorePrimitives(callReturn)) return false; } else { if (!returnTypes->isSubset(callReturn)) return false; } // TI calls ObjectStateChange to trigger invalidation of the caller. HeapTypeSet::WatchObjectStateChange(cx, targetType); return true; }
void visit(const Type& type) const { if (isSubtypeOf(type, b)) { res.insert(type); } else { TypeVisitor<void>::visit(type); } }
bool TypeInferenceOracle::callReturnTypeSetMatches(RawScript callerScript, jsbytecode *callerPc, RawFunction callee) { RootedScript targetScript(cx, callee->nonLazyScript()); JSOp op = JSOp(*callerPc); TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript); TypeSet *callReturn = getCallReturn(callerScript, callerPc); if (op == JSOP_NEW) { if (!returnTypes->isSubsetIgnorePrimitives(callReturn)) return false; } else { if (!returnTypes->isSubset(callReturn)) return false; } return true; }
/******************************************************************* * Function: ArrayIndexAnalysis::getTypeInfo * Purpose : Get an array dimensions' information * Initial : Nurudeen A. Lameed on July 21, 2009 ******************************************************************** Revisions and bug fixes: */ inline TypeInfo ArrayIndexAnalysis::getTypeInfo(const IIRNode* node, const SymbolExpr* symbol) const { // retrieve the type set TypeInfoMap post = typeInferenceInfo->postTypeMap; TypeSet tSet = (post[node])[symbol]; // look for one with bounds information // if none has the info, return an empty type info. for (TypeSet::const_iterator it = tSet.begin(), iEnd = tSet.end(); it != iEnd; ++it) { TypeInfo typ = *it; if ( typ.getSizeKnown() ) { return *it; } } return TypeInfo(); // return an empty type info }
void IConnectionLoader::addConnection( VertexMap& vertices, SystemTypeGetter* info, int from, int to, TypeSet tags) { TypeSet toType, fromType; toType.insert(info->getType(to)); toType.insert(tags.begin(), tags.end()); fromType.insert(info->getType(from)); fromType.insert(tags.begin(), tags.end()); //Add vertices if they dont exists already //this will fail if it already exists vertices.insert(std::make_pair(from, Vertex(from))); vertices.insert(std::make_pair(to, Vertex(to))); //Add edges to the vertices vertices.find(from)->second.addEdge(to, toType); vertices.find(to)->second.addEdge(from, fromType); }
/** * Move all single impl in a single impl method signature to next pass. * We make a single optimization per pass over any given single impl so * I1, I2 and void I1.m(I2) * the first optimization (I1 or I2) moves the other interface to next pass. * That is not the case for methods on non optimizable classes, so for * I1, I2 and void C.m(I1, I2) * then m is changed in a single pass for both I1 and I2. */ void OptimizationImpl::drop_single_impl_collision(DexType* intf, SingleImplData& data, DexMethod* method) { auto check_type = [&](DexType* type) { if (type != intf && single_impls->is_single_impl(type) && !single_impls->is_escaped(type)) { single_impls->escape_interface(type, NEXT_PASS); assert(optimized.find(type) == optimized.end()); } }; auto owner = method->get_class(); if (!single_impls->is_single_impl(owner)) return; check_type(owner); auto proto = method->get_proto(); check_type(proto->get_rtype()); auto args_list = proto->get_args(); for (auto arg : args_list->get_type_list()) { check_type(arg); } }
TypeSet getLeastCommonSupertypes(const Type& a, const Type& b) { // make sure they are in the same type environment assert(a.getTypeEnvironment().isType(a) && a.getTypeEnvironment().isType(b)); // if they are equal it is easy if (a == b) { return TypeSet(a); } // equally simple - check whether one is a sub-type of the other if (isSubtypeOf(a,b)) { return TypeSet(b); } if (isSubtypeOf(b,a)) { return TypeSet(a); } // harder: no obvious relation => hard way TypeSet superTypes; TypeSet all = a.getTypeEnvironment().getAllTypes(); for(const Type& cur : all) { if (isSubtypeOf(a, cur) && isSubtypeOf(b, cur)) { superTypes.insert(cur); } } // filter out non-least super types TypeSet res; for(const Type& cur : superTypes) { bool least = !any_of(superTypes, [&](const Type& t) { return t != cur && isSubtypeOf(t, cur); }); if (least) res.insert(cur); } return res; }
void RenameClassesPass::run_pass(DexStoresVector& stores, ConfigFiles& cfg, PassManager& mgr) { const JsonWrapper& json_cfg = cfg.get_json_config(); if (json_cfg.get("emit_name_based_locators", false)) { // TODO: Purge the old RenameClassesPass entirely everywhere. fprintf(stderr, "[RenameClassesPass] error: Configuration option " "emit_locator_strings is not compatible with RenameClassesPass. " "Upgrade to RenameClassesPassV2 instead.\n"); exit(EXIT_FAILURE); } auto scope = build_class_scope(stores); ClassHierarchy ch = build_type_hierarchy(scope); std::unordered_set<const DexType*> untouchables; for (const auto& base : m_untouchable_hierarchies) { auto base_type = DexType::get_type(base.c_str()); if (base_type != nullptr) { untouchables.insert(base_type); TypeSet children; get_all_children(ch, base_type, children); untouchables.insert(children.begin(), children.end()); } } mgr.incr_metric(METRIC_CLASSES_IN_SCOPE, scope.size()); rename_classes( scope, m_pre_filter_whitelist, m_post_filter_whitelist, untouchables, m_rename_annotations, mgr); TRACE(RENAME, 1, "renamed classes: %d anon classes, %d from single char patterns, " "%d from multi char patterns\n", match_inner, match_short, match_long); TRACE(RENAME, 1, "String savings, at least %d bytes \n", base_strings_size - ren_strings_size); }
/** * Run an optimization step. */ size_t OptimizationImpl::optimize(Scope& scope) { TypeList to_optimize; single_impls->get_interfaces(to_optimize); for (auto intf : to_optimize) { auto& intf_data = single_impls->get_single_impl_data(intf); TRACE(INTF, 3, "(OPT) %s => %s\n", SHOW(intf), SHOW(intf_data.cls)); if (intf_data.is_escaped()) continue; auto escape = can_optimize(intf, intf_data); if (escape != EscapeReason::NO_ESCAPE) { single_impls->escape_interface(intf, escape); continue; } do_optimize(intf, intf_data); optimized.insert(intf); } // make a new scope deleting all single impl interfaces Scope new_scope; for (auto cls : scope) { if (optimized.find(cls->get_type()) != optimized.end()) continue; new_scope.push_back(cls); } scope.swap(new_scope); return optimized.size(); }
TypeSet getGreatestCommonSubtypes(const Type& a, const Type& b) { // make sure they are in the same type environment assert(a.getTypeEnvironment().isType(a) && a.getTypeEnvironment().isType(b)); // if they are equal it is easy if (a == b) { return TypeSet(a); } // equally simple - check whether one is a sub-type of the other if (isSubtypeOf(a,b)) { return TypeSet(a); } if (isSubtypeOf(b,a)) { return TypeSet(b); } // last option: if both are unions with common sub-types TypeSet res; if (isUnion(a) && isUnion(b)) { // collect common sub-types of union types struct collector : public TypeVisitor<void> { const Type& b; TypeSet& res; collector(const Type& b, TypeSet& res) : b(b), res(res) {} void visit(const Type& type) const { if (isSubtypeOf(type, b)) { res.insert(type); } else { TypeVisitor<void>::visit(type); } } void visitUnionType(const UnionType& type) const { for(const auto& cur : type.getElementTypes()) visit(*cur); } }; // collect all common sub-types collector(b,res).visit(a); } // otherwise there is no common super type return res; }
void RemoveInterfacePass::remove_interfaces_for_root( const Scope& scope, const DexStoresVector& stores, const DexType* root, const TypeSystem& type_system) { TRACE(RM_INTF, 5, "Processing root %s\n", SHOW(root)); TypeSet interfaces; type_system.get_all_interface_children(root, interfaces); include_parent_interfaces(root, interfaces); m_total_num_interface += interfaces.size(); m_num_interface_excluded += exclude_unremovables( scope, stores, type_system, m_skip_multiple_targets_roots, m_include_primary_dex, interfaces); TRACE(RM_INTF, 5, "removable interfaces %ld\n", interfaces.size()); TypeSet removed = remove_leaf_interfaces(scope, root, interfaces, type_system); while (removed.size() > 0) { for (const auto intf : removed) { interfaces.erase(intf); m_removed_interfaces.insert(intf); } TRACE(RM_INTF, 5, "non-leaf removable interfaces %ld\n", interfaces.size()); removed = remove_leaf_interfaces(scope, root, interfaces, type_system); } // Update type reference to removed interfaces all at once. remove_interface_references(scope, type_system, root, m_removed_interfaces); if (traceEnabled(RM_INTF, 9)) { TypeSystem updated_ts(scope); for (const auto intf : interfaces) { TRACE(RM_INTF, 9, "unremoved interface %s\n", SHOW(intf)); TypeSet children; updated_ts.get_all_interface_children(intf, children); for (const auto cintf : children) { TRACE(RM_INTF, 9, " child %s\n", SHOW(cintf)); } } } }
TypeSet getGreatestCommonSubtypes(const TypeSet& a, const TypeSet& b) { // special cases if (a.empty()) return a; if (b.empty()) return b; if (a.isAll()) return b; if (b.isAll()) return a; // compute pairwise greatest common sub types TypeSet res; for(const Type& x : a) { for(const Type& y : b) { res.insert(getGreatestCommonSubtypes(x,y)); } } return res; }
bool AreaAreaIndex::GetOffsets(const TypeConfigRef& typeConfig, double minlon, double minlat, double maxlon, double maxlat, size_t maxLevel, const TypeSet& types, size_t maxCount, std::vector<FileOffset>& offsets) const { std::vector<CellRef> cellRefs; // cells to scan in this level std::vector<CellRef> nextCellRefs; // cells to scan for the next level std::vector<FileOffset> newOffsets; // offsets collected in the current level minlon+=180; maxlon+=180; minlat+=90; maxlat+=90; // Clear result datastructures offsets.clear(); // Make the vector preallocate memory for the expected data size // This should void reallocation offsets.reserve(std::min(100000u,(uint32_t)maxCount)); newOffsets.reserve(std::min(100000u,(uint32_t)maxCount)); cellRefs.reserve(1000); nextCellRefs.reserve(1000); cellRefs.push_back(CellRef(topLevelOffset,0,0)); // For all levels: // * Take the tiles and offsets of the last level // * Calculate the new tiles and offsets that still interfere with given area // * Add the new offsets to the list of offsets and finish if we have // reached maxLevel or maxAreaCount. // * copy no, ntx, nty to ctx, cty, co and go to next iteration bool stopArea=false; for (uint32_t level=0; !stopArea && level<=this->maxLevel && level<=maxLevel && !cellRefs.empty(); level++) { nextCellRefs.clear(); newOffsets.clear(); for (size_t i=0; !stopArea && i<cellRefs.size(); i++) { size_t cx; size_t cy; IndexCache::CacheRef cell; if (!GetIndexCell(*typeConfig, level, cellRefs[i].offset, cell)) { log.Error() << "Cannot find offset " << cellRefs[i].offset << " in level " << level << " in file '" << scanner.GetFilename() << "'"; return false; } if (offsets.size()+ newOffsets.size()+ cell->value.areas.size()>=maxCount) { stopArea=true; continue; } for (const auto entry : cell->value.areas) { if (types.IsTypeSet(entry.type)) { newOffsets.push_back(entry.offset); } } cx=cellRefs[i].x*2; cy=cellRefs[i].y*2; if (cell->value.children[0]!=0) { // top left double x=cx*cellWidth[level+1]; double y=(cy+1)*cellHeight[level+1]; if (!(x>maxlon+cellWidth[level+1]/2 || y>maxlat+cellHeight[level+1]/2 || x+cellWidth[level+1]<minlon-cellWidth[level+1]/2 || y+cellHeight[level+1]<minlat-cellHeight[level+1]/2)) { nextCellRefs.push_back(CellRef(cell->value.children[0],cx,cy+1)); } } if (cell->value.children[1]!=0) { // top right double x=(cx+1)*cellWidth[level+1]; double y=(cy+1)*cellHeight[level+1]; if (!(x>maxlon+cellWidth[level+1]/2 || y>maxlat+cellHeight[level+1]/2 || x+cellWidth[level+1]<minlon-cellWidth[level+1]/2 || y+cellHeight[level+1]<minlat-cellHeight[level+1]/2)) { nextCellRefs.push_back(CellRef(cell->value.children[1],cx+1,cy+1)); } } if (cell->value.children[2]!=0) { // bottom left double x=cx*cellWidth[level+1]; double y=cy*cellHeight[level+1]; if (!(x>maxlon+cellWidth[level+1]/2 || y>maxlat+cellHeight[level+1]/2 || x+cellWidth[level+1]<minlon-cellWidth[level+1]/2 || y+cellHeight[level+1]<minlat-cellHeight[level+1]/2)) { nextCellRefs.push_back(CellRef(cell->value.children[2],cx,cy)); } } if (cell->value.children[3]!=0) { // bottom right double x=(cx+1)*cellWidth[level+1]; double y=cy*cellHeight[level+1]; if (!(x>maxlon+cellWidth[level+1]/2 || y>maxlat+cellHeight[level+1]/2 || x+cellWidth[level+1]<minlon-cellWidth[level+1]/2 || y+cellHeight[level+1]<minlat-cellHeight[level+1]/2)) { nextCellRefs.push_back(CellRef(cell->value.children[3],cx+1,cy)); } } } if (!stopArea) { offsets.insert(offsets.end(),newOffsets.begin(),newOffsets.end()); } std::swap(cellRefs,nextCellRefs); } return true; }
TypeSet TypeEnvironment::getAllTypes() const { TypeSet res; for(const auto& cur : types) res.insert(*cur.second); return res; }
bool isRecordType(const TypeSet& s) { return !s.empty() && !s.isAll() && all_of(s, (bool(*)(const Type&))&isRecordType); }
bool CalculateAmplitudes::process() { //_ui.btnOK->setEnabled(false); _processors.clear(); _ui.table->setRowCount(0); Core::TimeWindow acTimeWindow; if ( !_origin || (_recomputeAmplitudes && !_thread) ) return false; if ( _amplitudeTypes.empty() ) return false; _timeWindow = Core::TimeWindow(); /* TypeSet wantedAmpTypes; wantedAmpTypes.insert("MLv"); wantedAmpTypes.insert("mb"); wantedAmpTypes.insert("mB"); wantedAmpTypes.insert("Mwp"); try { vector<string> amps = SCApp->configGetStrings("amplitudes"); wantedAmpTypes.clear(); wantedAmpTypes.insert(amps.begin(), amps.end()); } catch (...) {} */ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); if ( _thread ) _thread->connect(); typedef pair<PickCPtr, double> PickStreamEntry; // Typedef a pickmap that maps a streamcode to a pick typedef map<string, PickStreamEntry> PickStreamMap; // This map is needed to find the earliest P pick of // a certain stream PickStreamMap pickStreamMap; for ( size_t i = 0; i < _origin->arrivalCount(); ++i ) { Arrival *ar = _origin->arrival(i); double weight = 1.; try { weight = ar->weight(); } catch (Seiscomp::Core::ValueException) {} if ( Util::getShortPhaseName(ar->phase().code()) != 'P' || weight < 0.5 ) { continue; } Pick *pick = Pick::Find(ar->pickID()); if ( !pick ) { // cerr << " - Skipping arrival " << i << " -> no pick found" << endl; continue; } double dist = -1; try { dist = ar->distance(); } catch ( Core::ValueError &e ) { try { Client::StationLocation loc; double azi1, azi2; loc = Client::Inventory::Instance()->stationLocation(pick->waveformID().networkCode(), pick->waveformID().stationCode(), pick->time().value()); Math::Geo::delazi(loc.latitude, loc.longitude, _origin->latitude(), _origin->longitude(), &dist, &azi1, &azi2); } catch ( Core::GeneralException &e ) {} } DataModel::WaveformStreamID wfid = pick->waveformID(); // Strip the component code because every AmplitudeProcessor // will use its own component to pick the amplitude on wfid.setChannelCode(wfid.channelCode().substr(0,2)); string streamID = waveformIDToStdString(wfid); PickStreamEntry &e = pickStreamMap[streamID]; // When there is already a pick registered for this stream which has // been picked earlier, ignore the current pick if ( e.first && e.first->time().value() < pick->time().value() ) continue; e.first = pick; e.second = dist; } for ( PickStreamMap::iterator it = pickStreamMap.begin(); it != pickStreamMap.end(); ++it ) { PickCPtr pick = it->second.first; double dist = it->second.second; _ui.comboFilterType->clear(); _ui.comboFilterType->addItem("- Any -"); for ( TypeSet::iterator ita = _amplitudeTypes.begin(); ita != _amplitudeTypes.end(); ++ita ) _ui.comboFilterType->addItem(ita->c_str()); if ( _recomputeAmplitudes ) { for ( TypeSet::iterator ita = _amplitudeTypes.begin(); ita != _amplitudeTypes.end(); ++ita ) addProcessor(*ita, pick.get(), dist); } else { string streamID = waveformIDToStdString(pick->waveformID()); TypeSet usedTypes; if ( !_amplitudes.empty() ) { iterator_range itp; itp = _amplitudes.equal_range(pick->publicID()); for ( iterator it = itp.first; it != itp.second; ) { AmplitudePtr amp = it->second.first; // The amplitude type is not one of the wanted types if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) { ++it; continue; } // Already has an amplitude of this type processed if ( usedTypes.find(amp->type()) != usedTypes.end() ) { ++it; continue; } usedTypes.insert(amp->type()); int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type()); setMessage(row, "read from cache"); setValue(row, amp->amplitude().value()); ++it; } } bool foundAmplitudes = false; if ( _externalAmplitudeCache ) { iterator_range itp; itp = _externalAmplitudeCache->equal_range(pick->publicID()); for ( iterator ita = itp.first; ita != itp.second; ++ita ) { AmplitudePtr amp = ita->second.first; // The amplitude type is not one of the wanted types if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) continue; // Already has an amplitude of this type processed if ( usedTypes.find(amp->type()) != usedTypes.end() ) { checkPriority(ita->second); continue; } usedTypes.insert(amp->type()); int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type()); setMessage(row, "read from cache"); setValue(row, amp->amplitude().value()); _amplitudes.insert(PickAmplitudeMap::value_type(ita->first, ita->second)); } } if ( _query && !foundAmplitudes ) { DatabaseIterator it = _query->getAmplitudesForPick(pick->publicID()); for ( ; *it; ++it ) { AmplitudePtr amp = Amplitude::Cast(*it); if ( !amp ) continue; foundAmplitudes = true; // The amplitude type is not one of the wanted types if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) continue; // Already has an amplitude of this type processed if ( usedTypes.find(amp->type()) != usedTypes.end() ) { checkPriority(AmplitudeEntry(amp, false)); continue; } usedTypes.insert(amp->type()); int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type()); setMessage(row, "read from database"); setValue(row, amp->amplitude().value()); _amplitudes.insert(PickAmplitudeMap::value_type(pick->publicID(), AmplitudeEntry(amp, false))); } } if ( !foundAmplitudes ) { EventParameters *ep = EventParameters::Cast(PublicObject::Find("EventParameters")); if ( ep ) { for ( size_t i = 0; i < ep->amplitudeCount(); ++i ) { Amplitude *amp = ep->amplitude(i); if ( amp->pickID() != pick->publicID() ) continue; // The amplitude type is not one of the wanted types if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) continue; // Already has an amplitude of this type processed if ( usedTypes.find(amp->type()) != usedTypes.end() ) { checkPriority(AmplitudeEntry(amp, false)); continue; } usedTypes.insert(amp->type()); int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type()); setMessage(row, "read from memory"); setValue(row, amp->amplitude().value()); _amplitudes.insert(PickAmplitudeMap::value_type(pick->publicID(), AmplitudeEntry(amp, false))); } } } TypeSet remainingTypes; set_difference(_amplitudeTypes.begin(), _amplitudeTypes.end(), usedTypes.begin(), usedTypes.end(), inserter(remainingTypes, remainingTypes.begin())); for ( TypeSet::iterator ita = remainingTypes.begin(); ita != remainingTypes.end(); ++ita ) { if ( _thread ) addProcessor(*ita, pick.get(), dist); else { int row = addProcessingRow(streamID, *ita); setError(row, "missing"); } } } } _ui.table->resizeColumnsToContents(); _ui.table->resizeRowsToContents(); if ( _thread && _timeWindow ) { _thread->setTimeWindow(_timeWindow); _thread->start(); } //else // _ui.btnOK->setEnabled(true); QApplication::restoreOverrideCursor(); return true; }