int* maxSlidingWindow2(int* nums, int numsSize, int k, int* returnSize) { if (nums == NULL || numsSize == 0) return NULL; Result R; ElementType* Heap; ElementType Node; Queue Q; int i; Q = Initialize(MAX); R = InitializeResult(MAX); Heap = InitHeap(nums, k, Q); BuildHeap(Heap, k); for (i = k; i < numsSize; ++i) { AddToResult(R, Heap[1] -> Value); Node = Dequeue(Q); Node -> Value = nums[i]; Enqueue(Q, Node); AdjustRandItemInHeap(Heap, Node -> Index, k); } AddToResult(R, Heap[1] -> Value); *returnSize = R -> Size; return R -> Next; }
nsresult nsAbAutoCompleteSession::SearchPreviousResults(nsAbAutoCompleteSearchString *searchStr, nsIAutoCompleteResults *previousSearchResult, nsIAutoCompleteResults* results) { if (!previousSearchResult) return NS_ERROR_NULL_POINTER; nsXPIDLString prevSearchString; nsresult rv; rv = previousSearchResult->GetSearchString(getter_Copies(prevSearchString)); NS_ENSURE_SUCCESS(rv, rv); if (!(const PRUnichar*)prevSearchString || ((const PRUnichar*)prevSearchString)[0] == 0) return NS_ERROR_FAILURE; PRUint32 prevSearchStrLen = nsCRT::strlen(prevSearchString); if (searchStr->mFullStringLen < prevSearchStrLen || CommonPrefix(searchStr->mFullString, prevSearchString, prevSearchStrLen)) return NS_ERROR_ABORT; nsCOMPtr<nsISupportsArray> array; rv = previousSearchResult->GetItems(getter_AddRefs(array)); if (NS_SUCCEEDED(rv)) { PRUint32 nbrOfItems; PRUint32 i; PRUint32 pos; rv = array->Count(&nbrOfItems); if (NS_FAILED(rv) || nbrOfItems <= 0) return NS_ERROR_FAILURE; nsCOMPtr<nsISupports> item; nsCOMPtr<nsIAutoCompleteItem> resultItem; nsAbAutoCompleteParam *param; for (i = 0, pos = 0; i < nbrOfItems; i ++, pos ++) { rv = array->QueryElementAt(pos, NS_GET_IID(nsIAutoCompleteItem), getter_AddRefs(resultItem)); NS_ENSURE_SUCCESS(rv, rv); rv = resultItem->GetParam(getter_AddRefs(item)); NS_ENSURE_SUCCESS(rv, rv); if (!item) return NS_ERROR_FAILURE; param = (nsAbAutoCompleteParam *)(void *)item; if (CheckEntry(searchStr, param->mNickName, param->mDisplayName, param->mFirstName, param->mLastName, param->mEmailAddress)) AddToResult(param->mNickName, param->mDisplayName, param->mFirstName, param->mLastName, param->mEmailAddress, param->mNotes, param->mDirName, param->mPopularityIndex, param->mIsMailList, PR_FALSE, results); } return NS_OK; } return NS_ERROR_ABORT; }
NS_IMETHODIMP nsAbAutoCompleteSession::OnStartLookup(const PRUnichar *uSearchString, nsIAutoCompleteResults *previousSearchResult, nsIAutoCompleteListener *listener) { nsresult rv = NS_OK; if (!listener) return NS_ERROR_NULL_POINTER; PRBool enableLocalAutocomplete; PRBool enableReplicatedLDAPAutocomplete; nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); // check if using autocomplete for local address books rv = prefs->GetBoolPref("mail.enable_autocomplete", &enableLocalAutocomplete); NS_ENSURE_SUCCESS(rv,rv); rv = NeedToSearchReplicatedLDAPDirectories(prefs, &enableReplicatedLDAPAutocomplete); NS_ENSURE_SUCCESS(rv,rv); if (uSearchString[0] == 0 || (!enableLocalAutocomplete && !enableReplicatedLDAPAutocomplete)) { listener->OnAutoComplete(nsnull, nsIAutoCompleteStatus::ignored); return NS_OK; } // figure out what we're supposed to do about the comment column, and // remember it for when the results start coming back // rv = prefs->GetIntPref("mail.autoComplete.commentColumn", &mAutoCompleteCommentColumn); if (NS_FAILED(rv)) { mAutoCompleteCommentColumn = 0; } // strings with commas (commas denote multiple names) should be ignored for // autocomplete purposes PRInt32 i; for (i = nsCRT::strlen(uSearchString) - 1; i >= 0; i --) if (uSearchString[i] == ',') { listener->OnAutoComplete(nsnull, nsIAutoCompleteStatus::ignored); return NS_OK; } nsAbAutoCompleteSearchString searchStrings(uSearchString); nsCOMPtr<nsIAutoCompleteResults> results = do_CreateInstance(NS_AUTOCOMPLETERESULTS_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) if (NS_FAILED(SearchPreviousResults(&searchStrings, previousSearchResult, results))) { nsresult rv1,rv2; if (enableLocalAutocomplete) { rv1 = SearchDirectory(NS_LITERAL_CSTRING(kAllDirectoryRoot), &searchStrings, PR_TRUE, results); NS_ASSERTION(NS_SUCCEEDED(rv1), "searching all local directories failed"); } else rv1 = NS_OK; if (enableReplicatedLDAPAutocomplete) { rv2 = SearchReplicatedLDAPDirectories(prefs, &searchStrings, PR_TRUE, results); NS_ASSERTION(NS_SUCCEEDED(rv2), "searching all replicated LDAP directories failed"); } else rv2 = NS_OK; // only bail out if both failed. otherwise, we have some results we can use if (NS_FAILED(rv1) && NS_FAILED(rv2)) rv = NS_ERROR_FAILURE; else rv = NS_OK; } AutoCompleteStatus status = nsIAutoCompleteStatus::failed; if (NS_SUCCEEDED(rv) && results) { PRBool addedDefaultItem = PR_FALSE; results->SetSearchString(uSearchString); results->SetDefaultItemIndex(-1); if (mDefaultDomain[0] != 0) { PRUnichar emptyStr = 0; AddToResult(&emptyStr, uSearchString, &emptyStr, &emptyStr, &emptyStr, &emptyStr, &emptyStr, 0 /* popularity index */, PR_FALSE, PR_TRUE, results); addedDefaultItem = PR_TRUE; } nsCOMPtr<nsISupportsArray> array; rv = results->GetItems(getter_AddRefs(array)); if (NS_SUCCEEDED(rv)) { //If we have more than a match (without counting the default item), we don't //want to auto complete the user input therefore set the default item index to -1 PRUint32 nbrOfItems; rv = array->Count(&nbrOfItems); if (NS_SUCCEEDED(rv)) if (nbrOfItems == 0) status = nsIAutoCompleteStatus::noMatch; else { status = nsIAutoCompleteStatus::matchFound; if (addedDefaultItem) { // If we have at least one REAL match then make it the default item. If we don't have any matches, // just the default domain, then don't install a default item index on the widget. results->SetDefaultItemIndex(nbrOfItems > 1 ? 1 : -1); } else results->SetDefaultItemIndex(0); } } } listener->OnAutoComplete(results, status); return NS_OK; }
nsresult nsAbAutoCompleteSession::SearchCards(nsIAbDirectory* directory, nsAbAutoCompleteSearchString* searchStr, nsIAutoCompleteResults* results) { nsresult rv; nsCOMPtr<nsIEnumerator> cardsEnumerator; nsCOMPtr<nsIAbCard> card; PRInt32 i; rv = directory->GetChildCards(getter_AddRefs(cardsEnumerator)); if (NS_SUCCEEDED(rv) && cardsEnumerator) { nsCOMPtr<nsISupports> item; for (rv = cardsEnumerator->First(); NS_SUCCEEDED(rv); rv = cardsEnumerator->Next()) { rv = cardsEnumerator->CurrentItem(getter_AddRefs(item)); if (NS_SUCCEEDED(rv)) { card = do_QueryInterface(item, &rv); if (NS_SUCCEEDED(rv)) { // Skip if it's not a normal card (ie, they can't be added as members). PRBool isNormal; rv = card->GetIsANormalCard(&isNormal); if (NS_FAILED(rv) || !isNormal) continue; nsXPIDLString pEmailStr[MAX_NUMBER_OF_EMAIL_ADDRESSES]; //[0]=primary email, [1]=secondary email (no available with mailing list) nsXPIDLString pDisplayNameStr; nsXPIDLString pFirstNameStr; nsXPIDLString pLastNameStr; nsXPIDLString pNickNameStr; nsXPIDLString pNotesStr; PRUint32 popularityIndex = 0; PRBool bIsMailList; rv = card->GetIsMailList(&bIsMailList); if (NS_FAILED(rv)) continue; if (bIsMailList) { rv = card->GetNotes(getter_Copies(pNotesStr)); if (NS_FAILED(rv)) continue; } else { for (i = 0 ; i < MAX_NUMBER_OF_EMAIL_ADDRESSES; i ++) { switch (i) { case 0: rv = card->GetPrimaryEmail(getter_Copies(pEmailStr[i])); break; case 1: rv = card->GetSecondEmail(getter_Copies(pEmailStr[i])); break; default: return NS_ERROR_FAILURE; } if (NS_FAILED(rv)) continue; // Don't bother with card without an email address if (pEmailStr[i].IsEmpty()) continue; //...and does it looks like a valid address? if (pEmailStr[i].FindChar('@') <= 0) pEmailStr[i].SetLength(0); } if (pEmailStr[0].IsEmpty() && pEmailStr[1].IsEmpty()) continue; } //Now, retrive the user name and nickname rv = card->GetDisplayName(getter_Copies(pDisplayNameStr)); if (NS_FAILED(rv)) continue; rv = card->GetFirstName(getter_Copies(pFirstNameStr)); if (NS_FAILED(rv)) continue; rv = card->GetLastName(getter_Copies(pLastNameStr)); if (NS_FAILED(rv)) continue; rv = card->GetNickName(getter_Copies(pNickNameStr)); if (NS_FAILED(rv)) continue; (void) card->GetPopularityIndex(&popularityIndex); // in the address book a mailing list does not have an email address field. However, // we do "fix up" mailing lists in the UI sometimes to look like "My List <My List>" // if we are looking up an address and we are comparing it to a mailing list to see if it is a match // instead of just looking for an exact match on "My List", hijack the unused email address field // and use that to test against "My List <My List>" if (bIsMailList) mParser->MakeFullAddressWString (pDisplayNameStr, pDisplayNameStr, getter_Copies(pEmailStr[0])); for (i = 0 ; i < MAX_NUMBER_OF_EMAIL_ADDRESSES; i ++) { if (!bIsMailList && pEmailStr[i].IsEmpty()) continue; if (CheckEntry(searchStr, pNickNameStr.get(), pDisplayNameStr.get(), pFirstNameStr.get(), pLastNameStr.get(), pEmailStr[i].get())) { nsXPIDLString pDirName; if (mAutoCompleteCommentColumn == 1) { rv = directory->GetDirName(getter_Copies(pDirName)); if (NS_FAILED(rv)) continue; } AddToResult(pNickNameStr.get(), pDisplayNameStr.get(), pFirstNameStr.get(), pLastNameStr.get(), pEmailStr[i].get(), pNotesStr.get(), pDirName.get(), popularityIndex, bIsMailList, PR_FALSE, results); } } } } } } return NS_OK; }