/*求字符串最长的最共前缀*/ void maxPrefix(std::string& prefix) { maxPrefix(root,prefix); std::string word(prefix); int size = word.size(); for(int i=0;i<size;++i) prefix[i] = word[size-1-i]; prefix.erase(size-1); }
bool findTree(Node *node, char *s, int size, bool exact){ if(node == NULL)return false; if(size == 0 && (!exact || node->numberOfWord != NO_END_OF_WORD)) return true; int maxPref = maxPrefix(s, size, node->text, node->size); if(maxPref == size && (!exact || node->size == size)) return !exact || node->numberOfWord != NO_END_OF_WORD; if(maxPref < node->size) return false; if(node->sons[cToI(s[maxPref])] == NULL) return false; return findTree(node->sons[cToI(s[maxPref])], s + maxPref, size - maxPref, exact); }
void maxPrefix(node_type& cur,std::string& prefix) { std::string word; int length =0 ; int k = 0; for(int i=0;i<Size;++i) { if(cur.child[i] != 0) { maxPrefix(*cur.child[i],word); if(word.size() > length) { length = word.size(); prefix.swap(word); k = i; } } } if(length > 0 || cur.node >1 || cur.freq >0 && cur.node>0) //cur.node >1 处理"abcde"与"abcdf"这种情况;cur.freq>0 && cur.node>0处理"abcde"与"abcdef"这种情况 { prefix.push_back(k + 'a'); } }
void ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus, bool aInCacheAndEqual, const nsAString& aNewCacheName, const nsACString& aMaxScope, nsLoadFlags aLoadFlags) { AssertIsOnMainThread(); RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); if (NS_WARN_IF(Canceled() || !swm)) { FailUpdateJob(NS_ERROR_DOM_ABORT_ERR); return; } // Handle failure of the download or comparison. This is part of Update // step 5 as "If the algorithm asynchronously completes with null, then:". if (NS_WARN_IF(NS_FAILED(aStatus))) { FailUpdateJob(aStatus); return; } // The spec validates the response before performing the byte-for-byte check. // Here we perform the comparison in another module and then validate the // script URL and scope. Make sure to do this validation before accepting // an byte-for-byte match since the service-worker-allowed header might have // changed since the last time it was installed. // This is step 2 the "validate response" section of Update algorithm step 5. // Step 1 is performed in the serviceWorkerScriptCache code. nsCOMPtr<nsIURI> scriptURI; nsresult rv = NS_NewURI(getter_AddRefs(scriptURI), mScriptSpec); if (NS_WARN_IF(NS_FAILED(rv))) { FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR); return; } nsCOMPtr<nsIURI> maxScopeURI; if (!aMaxScope.IsEmpty()) { rv = NS_NewURI(getter_AddRefs(maxScopeURI), aMaxScope, nullptr, scriptURI); if (NS_WARN_IF(NS_FAILED(rv))) { FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR); return; } } mLoadFlags = aLoadFlags; nsAutoCString defaultAllowedPrefix; rv = GetRequiredScopeStringPrefix(scriptURI, defaultAllowedPrefix, eUseDirectory); if (NS_WARN_IF(NS_FAILED(rv))) { FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR); return; } nsAutoCString maxPrefix(defaultAllowedPrefix); if (maxScopeURI) { rv = GetRequiredScopeStringPrefix(maxScopeURI, maxPrefix, eUsePath); if (NS_WARN_IF(NS_FAILED(rv))) { FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR); return; } } if (!StringBeginsWith(mRegistration->mScope, maxPrefix)) { nsAutoString message; NS_ConvertUTF8toUTF16 reportScope(mRegistration->mScope); NS_ConvertUTF8toUTF16 reportMaxPrefix(maxPrefix); const char16_t* params[] = { reportScope.get(), reportMaxPrefix.get() }; rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES, "ServiceWorkerScopePathMismatch", params, message); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to format localized string"); swm->ReportToAllClients(mScope, message, EmptyString(), EmptyString(), 0, 0, nsIScriptError::errorFlag); FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR); return; } // The response has been validated, so now we can consider if its a // byte-for-byte match. This is step 6 of the Update algorithm. if (aInCacheAndEqual) { Finish(NS_OK); return; } Telemetry::Accumulate(Telemetry::SERVICE_WORKER_UPDATED, 1); // Begin step 7 of the Update algorithm to evaluate the new script. RefPtr<ServiceWorkerInfo> sw = new ServiceWorkerInfo(mRegistration->mPrincipal, mRegistration->mScope, mScriptSpec, aNewCacheName, mLoadFlags); mRegistration->SetEvaluating(sw); nsMainThreadPtrHandle<ServiceWorkerUpdateJob> handle( new nsMainThreadPtrHolder<ServiceWorkerUpdateJob>( "ServiceWorkerUpdateJob", this)); RefPtr<LifeCycleEventCallback> callback = new ContinueUpdateRunnable(handle); ServiceWorkerPrivate* workerPrivate = sw->WorkerPrivate(); MOZ_ASSERT(workerPrivate); rv = workerPrivate->CheckScriptEvaluation(callback); if (NS_WARN_IF(NS_FAILED(rv))) { FailUpdateJob(NS_ERROR_DOM_ABORT_ERR); return; } }
//dodaje wyraz do node'a void addWordToNode(Node *node, char *text, int size, int number){ //liczymy długość najdłuższedo wspólnego prefiksu int maxPref = maxPrefix(text, size, node->text, node->size); if(maxPref == node->size){ //czyli wyraz w nodzie jest prefiksem text if(maxPref == size){ //czyli znaleźliśmy już dobry wierzchołek node->numberOfWord = number; endOfWord[number] = node; } else{ //czyli text w nodzie jest właściwym prefiksem Node *son = node->sons[cToI(text[maxPref])]; //jeżeli z node'a nie wychodzi krawędź z pierwszą literą //po wspólnym prefiksie to może stworzyć odpowiedni node if(son == NULL){ node->numberOfSons++; son = makeLeaf(text + maxPref, size - maxPref, number, node); node->sons[cToI(text[maxPref])] = son; node->sons[cToI(text[maxPref])]->numberOfWord = number; endOfWord[number] = son; } //w p.p. dodajemy rekurencyjnie do syna else addWordToNode(node->sons[cToI(text[maxPref])], text + maxPref, size - maxPref, number); } } else{ //czyli wyraz w nodzie nie jest prefiksem text Node *split = makeLeaf(node->text + maxPref, node->size - maxPref, node->numberOfWord, node); split->numberOfSons = node->numberOfSons; for(int i = 0;i < ALPHABET_SIZE;i++){ split->sons[i] = node->sons[i]; if(split->sons[i] != NULL) split->sons[i]->father = split; node->sons[i] = NULL; } node->size = maxPref; node->sons[cToI(node->text[maxPref])] = split; node->numberOfSons = 1; if(node->numberOfWord != NO_END_OF_WORD) endOfWord[node->numberOfWord] = split; node->numberOfWord = NO_END_OF_WORD; if(maxPref < size){ ///jeżeli w nodzie znajdował się niepusty różniący się sufiks //to rozdzielamy node'a na konfigurację //node --> split // \--> split2 node->sons[cToI(text[maxPref])]= makeLeaf(text + maxPref, size - maxPref, number, node); Node *split2 = node->sons[cToI(text[maxPref])]; node->numberOfSons++; endOfWord[number] = split2; split2->numberOfWord = number; } else{ //w p.p. rozdzielamy node'a na node --> split //zasadniczo kod powyżej to już zrobił node->numberOfWord = number; endOfWord[number] = node; } } }