add threading to single folder virtual folders, views, and quick searches, sr=mscott 263180

This commit is contained in:
bienvenu%nventure.com 2005-10-05 18:22:51 +00:00
Родитель 002c9cc505
Коммит 5079273bb8
10 изменённых файлов: 272 добавлений и 59 удалений

Просмотреть файл

@ -852,6 +852,7 @@ function FolderPaneSelectionChange()
var dbFolderInfo = msgDatabase.dBFolderInfo;
sortType = dbFolderInfo.sortType;
sortOrder = dbFolderInfo.sortOrder;
viewFlags = dbFolderInfo.viewFlags;
if (folderFlags & MSG_FOLDER_FLAG_VIRTUAL)
{
viewType = nsMsgViewType.eShowQuickSearchResults;

Просмотреть файл

@ -189,7 +189,7 @@ function createQuickSearchView()
var saveViewSearchListener = gDBView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
gSearchSession.unregisterListener(saveViewSearchListener);
}
CreateDBView(gDBView.msgFolder, (gXFVirtualFolderTerms) ? nsMsgViewType.eShowVirtualFolderResults : nsMsgViewType.eShowQuickSearchResults, nsMsgViewFlagsType.kNone, gDBView.sortType, gDBView.sortOrder);
CreateDBView(gDBView.msgFolder, (gXFVirtualFolderTerms) ? nsMsgViewType.eShowVirtualFolderResults : nsMsgViewType.eShowQuickSearchResults, gDBView.viewFlags, gDBView.sortType, gDBView.sortOrder);
}
}

Просмотреть файл

@ -3706,22 +3706,22 @@ void nsMsgDBView::FreeAll(nsVoidArray *ptrs)
nsMsgViewIndex nsMsgDBView::GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread *threadHdr)
{
nsMsgViewIndex retIndex = nsMsgViewIndex_None;
PRUint32 childIndex = 0;
// We could speed up the unreadOnly view by starting our search with the first
// unread message in the thread. Sometimes, that will be wrong, however, so
// let's skip it until we're sure it's necessary.
// (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly)
// ? threadHdr->GetFirstUnreadKey(m_db) : threadHdr->GetChildAt(0);
nsMsgViewIndex retIndex = nsMsgViewIndex_None;
PRUint32 childIndex = 0;
// We could speed up the unreadOnly view by starting our search with the first
// unread message in the thread. Sometimes, that will be wrong, however, so
// let's skip it until we're sure it's necessary.
// (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly)
// ? threadHdr->GetFirstUnreadKey(m_db) : threadHdr->GetChildAt(0);
PRUint32 numThreadChildren;
threadHdr->GetNumChildren(&numThreadChildren);
while (retIndex == nsMsgViewIndex_None && childIndex < numThreadChildren)
{
nsMsgKey childKey;
while (retIndex == nsMsgViewIndex_None && childIndex < numThreadChildren)
{
nsMsgKey childKey;
threadHdr->GetChildKeyAt(childIndex++, &childKey);
retIndex = FindViewIndex(childKey);
}
return retIndex;
retIndex = FindViewIndex(childKey);
}
return retIndex;
}
nsresult nsMsgDBView::GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result)
@ -4245,12 +4245,10 @@ nsMsgViewIndex nsMsgDBView::GetInsertIndexHelper(nsIMsgDBHdr *msgHdr, nsMsgKeyAr
comparisonContext = m_db.get();
break;
case kU32:
if (sortType == nsMsgViewSortType::byId) {
if (sortType == nsMsgViewSortType::byId)
EntryInfo1.dword = EntryInfo1.id;
}
else {
else
GetLongField(msgHdr, sortType, &EntryInfo1.dword);
}
comparisonFun = FnSortIdDWord;
break;
default:
@ -4323,7 +4321,8 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.GetSize(), "view arrays out of sync!");
#endif
if (!GetShowingIgnored()) {
if (!GetShowingIgnored())
{
nsCOMPtr <nsIMsgThread> thread;
m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(thread));
if (thread)
@ -4471,7 +4470,7 @@ nsresult nsMsgDBView::ListIdsInThreadOrder(nsIMsgThread *threadHdr, nsMsgKey par
return rv; // we don't want to return the rv from the enumerator when it reaches the end, do we?
}
nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
{
NS_ENSURE_ARG(threadHdr);
// these children ids should be in thread order.
@ -4807,10 +4806,11 @@ NS_IMETHODIMP nsMsgDBView::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags)
}
m_viewFlags = aViewFlags;
if (m_folder)
if (m_viewFolder)
{
nsCOMPtr <nsIMsgDatabase> db;
nsCOMPtr <nsIDBFolderInfo> folderInfo;
nsresult rv = m_folder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(m_db));
nsresult rv = m_viewFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
NS_ENSURE_SUCCESS(rv,rv);
return folderInfo->SetViewFlags(aViewFlags);
}
@ -5419,8 +5419,8 @@ nsresult nsMsgDBView::ToggleIgnored(nsMsgViewIndex * indices, PRInt32 numIndices
nsMsgViewIndex nsMsgDBView::GetThreadFromMsgIndex(nsMsgViewIndex index,
nsIMsgThread **threadHdr)
{
nsMsgKey msgKey = GetAt(index);
nsMsgViewIndex threadIndex;
nsMsgKey msgKey = GetAt(index);
nsMsgViewIndex threadIndex;
NS_ENSURE_ARG(threadHdr);
nsresult rv = GetThreadContainingIndex(index, threadHdr);

Просмотреть файл

@ -213,7 +213,7 @@ protected:
// helper routines for thread expanding and collapsing.
nsresult GetThreadCount(nsMsgKey messageKey, PRUint32 *pThreadCount);
nsMsgViewIndex GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread *threadHdr);
nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
virtual nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
virtual nsMsgViewIndex ThreadIndexOfMsg(nsMsgKey msgKey,
nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
PRInt32 *pThreadCount = nsnull,
@ -221,7 +221,7 @@ protected:
virtual nsresult GetThreadContainingMsgHdr(nsIMsgDBHdr *msgHdr, nsIMsgThread **pThread);
nsMsgKey GetKeyOfFirstMsgInThread(nsMsgKey key);
PRInt32 CountExpandedThread(nsMsgViewIndex index);
nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
virtual nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
nsresult ReverseSort();
nsresult ReverseThreads();
nsresult SaveSortInfo(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
@ -236,7 +236,7 @@ protected:
virtual nsresult GetFolders(nsISupportsArray **folders);
virtual nsresult GetFolderFromMsgURI(const char *aMsgURI, nsIMsgFolder **aFolder);
nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
virtual nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
nsresult ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
nsMsgViewIndex FindParentInThread(nsMsgKey parentKey, nsMsgViewIndex startOfThreadViewIndex);
nsresult ListIdsInThreadOrder(nsIMsgThread *threadHdr, nsMsgKey parentKey, PRInt32 level, nsMsgViewIndex *viewIndex, PRUint32 *pNumListed);

Просмотреть файл

@ -43,6 +43,7 @@
#include "nsMsgBaseCID.h"
#include "nsIMsgImapMailFolder.h"
#include "nsImapCore.h"
#include "nsIMsgHdr.h"
nsMsgQuickSearchDBView::nsMsgQuickSearchDBView()
{
@ -55,6 +56,19 @@ nsMsgQuickSearchDBView::~nsMsgQuickSearchDBView()
NS_IMPL_ISUPPORTS_INHERITED2(nsMsgQuickSearchDBView, nsMsgDBView, nsIMsgDBView, nsIMsgSearchNotify)
NS_IMETHODIMP nsMsgQuickSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder, nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount)
{
nsresult rv = nsMsgDBView::Open(folder, sortType, sortOrder, viewFlags, pCount);
NS_ENSURE_SUCCESS(rv, rv);
if (!m_db)
return NS_ERROR_NULL_POINTER;
if (pCount)
*pCount = 0;
m_viewFolder = nsnull;
return InitThreadedView(pCount);
}
NS_IMETHODIMP nsMsgQuickSearchDBView::DoCommand(nsMsgViewCommandTypeValue aCommand)
{
if (aCommand == nsMsgViewCommandType::markAllRead)
@ -100,7 +114,7 @@ nsresult nsMsgQuickSearchDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aPare
if (searchSession)
searchSession->MatchHdr(newHdr, m_db, &match);
if (match)
AddHdr(newHdr); // do not add a new message if there isn't a match.
nsMsgThreadedDBView::OnNewHeader(newHdr, aParentKey, ensureListed); // do not add a new message if there isn't a match.
}
return NS_OK;
}
@ -163,20 +177,9 @@ NS_IMETHODIMP
nsMsgQuickSearchDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
{
NS_ENSURE_ARG(aMsgHdr);
NS_ENSURE_ARG(folder);
nsMsgKey msgKey;
PRUint32 msgFlags;
aMsgHdr->GetMessageKey(&msgKey);
aMsgHdr->GetFlags(&msgFlags);
m_keys.Add(msgKey);
m_levels.Add(0);
m_flags.Add(msgFlags);
// this needs to happen after we add the key, as RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(GetSize() - 1, 1);
return NS_OK;
if (!m_db)
return NS_ERROR_NULL_POINTER;
return AddHdr(aMsgHdr);
}
NS_IMETHODIMP
@ -207,20 +210,196 @@ nsMsgQuickSearchDBView::OnNewSearch()
return NS_OK;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder)
nsresult nsMsgQuickSearchDBView::GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result)
{
nsMsgKey preservedKey;
nsMsgKeyArray preservedSelection;
SaveAndClearSelection(&preservedKey, &preservedSelection);
nsMsgDBView::Sort(sortType, sortOrder);
RestoreSelection(preservedKey, &preservedSelection);
if (mTree)
mTree->Invalidate();
PRUint32 numChildren;
nsresult rv = NS_OK;
PRUint8 minLevel = 0xff;
nsMsgKey threadRootKey;
PRUint32 folderFlags;
if (m_viewFolder && NS_SUCCEEDED(m_viewFolder->GetFlags(&folderFlags)) && folderFlags & MSG_FOLDER_FLAG_VIRTUAL)
SaveSortInfo(sortType, sortOrder);
threadHdr->GetNumChildren(&numChildren);
threadHdr->GetThreadKey(&threadRootKey);
if ((PRInt32) numChildren < 0)
numChildren = 0;
nsCOMPtr <nsIMsgDBHdr> retHdr;
// iterate over thread, finding mgsHdr in view with the lowest level.
for (PRUint32 childIndex = 0; childIndex < numChildren; childIndex++)
{
nsCOMPtr <nsIMsgDBHdr> child;
rv = threadHdr->GetChildHdrAt(childIndex, getter_AddRefs(child));
if (NS_SUCCEEDED(rv) && child)
{
nsMsgKey msgKey;
child->GetMessageKey(&msgKey);
// this works because we've already sorted m_keys by id.
nsMsgViewIndex keyIndex = m_origKeys.IndexOfSorted(msgKey);
if (keyIndex != kNotFound)
{
// this is the root, so it's the best we're going to do.
if (msgKey == threadRootKey)
{
retHdr = child;
break;
}
PRUint8 level = 0;
nsMsgKey parentId;
child->GetThreadParent(&parentId);
nsCOMPtr <nsIMsgDBHdr> parent;
// count number of ancestors - that's our level
while (parentId != nsMsgKey_None)
{
rv = m_db->GetMsgHdrForKey(parentId, getter_AddRefs(parent));
if (parent)
{
parent->GetThreadParent(&parentId);
level++;
}
}
if (level < minLevel)
{
minLevel = level;
retHdr = child;
}
}
}
}
NS_IF_ADDREF(*result = retHdr);
return NS_OK;
}
nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder)
{
// iterate over the messages in the view, getting the thread id's
if (sortType == nsMsgViewSortType::byId)
{
// sort m_keys so we can quickly find if a key is in the view.
m_keys.QuickSort();
// array of the threads' root hdr keys.
nsMsgKeyArray threadRootIds;
nsCOMPtr <nsIMsgDBHdr> rootHdr;
nsCOMPtr <nsIMsgDBHdr> msgHdr;
nsCOMPtr <nsIMsgThread> threadHdr;
for (PRUint32 i = 0; i < m_keys.GetSize(); i++)
{
GetMsgHdrForViewIndex(i, getter_AddRefs(msgHdr));
m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(threadHdr));
if (threadHdr)
{
nsMsgKey rootKey;
threadHdr->GetChildKeyAt(0, &rootKey);
nsMsgViewIndex threadRootIndex = threadRootIds.IndexOfSorted(rootKey);
// if we already have that id in top level threads, ignore this msg.
if (threadRootIndex != kNotFound)
continue;
// it would be nice if GetInsertIndexHelper always found the hdr, but it doesn't.
threadHdr->GetChildHdrAt(0, getter_AddRefs(rootHdr));
threadRootIndex = GetInsertIndexHelper(rootHdr, &threadRootIds, nsMsgViewSortOrder::ascending, sortType);
threadRootIds.InsertAt(threadRootIndex, rootKey);
}
}
// now we've build up the list of thread ids - need to build the view
// from that. So for each thread id, we need to list the messages in the thread.
m_origKeys.CopyArray(m_keys);
m_keys.RemoveAll();
m_levels.RemoveAll();
m_flags.RemoveAll();
PRUint32 numThreads = threadRootIds.GetSize();
for (PRUint32 threadIndex = 0; threadIndex < numThreads; threadIndex++)
{
m_db->GetMsgHdrForKey(threadRootIds[threadIndex], getter_AddRefs(rootHdr));
if (rootHdr)
{
nsCOMPtr <nsIMsgDBHdr> displayRootHdr;
m_db->GetThreadContainingMsgHdr(rootHdr, getter_AddRefs(threadHdr));
if (threadHdr)
{
nsMsgKey rootKey;
PRUint32 rootFlags;
GetFirstMessageHdrToDisplayInThread(threadHdr, getter_AddRefs(displayRootHdr));
displayRootHdr->GetMessageKey(&rootKey);
displayRootHdr->GetFlags(&rootFlags);
rootFlags |= MSG_VIEW_FLAG_ISTHREAD;
m_keys.Add(rootKey);
m_flags.Add(rootFlags);
m_levels.Add(0);
nsMsgViewIndex startOfThreadViewIndex = m_keys.GetSize() - 1;
PRUint32 numListed;
ListIdsInThread(threadHdr, startOfThreadViewIndex, &numListed);
}
}
}
}
return NS_OK;
}
nsresult nsMsgQuickSearchDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
{
PRUint32 numChildren;
threadHdr->GetNumChildren(&numChildren);
PRUint32 i;
PRUint32 viewIndex = startOfThreadViewIndex + 1;
nsCOMPtr <nsIMsgDBHdr> rootHdr;
nsMsgKey rootKey;
PRUint32 rootFlags = m_flags[startOfThreadViewIndex];
*pNumListed = 0;
GetMsgHdrForViewIndex(startOfThreadViewIndex, getter_AddRefs(rootHdr));
rootHdr->GetMessageKey(&rootKey);
for (i = 0; i < numChildren; i++)
{
nsCOMPtr <nsIMsgDBHdr> msgHdr;
threadHdr->GetChildHdrAt(i, getter_AddRefs(msgHdr));
if (msgHdr != nsnull)
{
nsMsgKey msgKey;
msgHdr->GetMessageKey(&msgKey);
if (msgKey != rootKey)
{
nsMsgViewIndex threadRootIndex = m_origKeys.IndexOfSorted(msgKey);
// if this hdr is in the original view, add it to new view.
if (threadRootIndex != kNotFound)
{
PRUint32 childFlags;
msgHdr->GetFlags(&childFlags);
PRUint8 levelToAdd;
m_keys.InsertAt(viewIndex, msgKey);
m_flags.InsertAt(viewIndex, childFlags);
if (! (rootFlags & MSG_VIEW_FLAG_HASCHILDREN))
{
rootFlags |= MSG_VIEW_FLAG_HASCHILDREN;
m_flags.SetAt(startOfThreadViewIndex, rootFlags);
}
levelToAdd = FindLevelInThread(msgHdr, startOfThreadViewIndex, viewIndex);
m_levels.InsertAt(viewIndex, levelToAdd);
viewIndex++;
(*pNumListed)++;
}
}
}
}
return NS_OK;
}
nsresult nsMsgQuickSearchDBView::ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta)
{
*expansionDelta = 0;
if ( index > ((nsMsgViewIndex) m_keys.GetSize()))
return NS_MSG_MESSAGE_NOT_FOUND;
char flags = m_flags[index];
if (!(m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
return NS_OK;
// The client can pass in the key of any message
// in a thread and get the expansion delta for the thread.
PRInt32 numChildren = CountExpandedThread(index);
*expansionDelta = (flags & MSG_FLAG_ELIDED) ?
numChildren - 1 : - (PRInt32) (numChildren - 1);
return NS_OK;
}

Просмотреть файл

@ -39,11 +39,11 @@
#ifndef _nsMsgQuickSearchDBViewsH_
#define _nsMsgQuickSearchDBView_H_
#include "nsMsgDBView.h"
#include "nsMsgThreadedDBView.h"
#include "nsIMsgSearchNotify.h"
#include "nsIMsgSearchSession.h"
class nsMsgQuickSearchDBView : public nsMsgDBView, public nsIMsgSearchNotify
class nsMsgQuickSearchDBView : public nsMsgThreadedDBView, public nsIMsgSearchNotify
{
public:
nsMsgQuickSearchDBView();
@ -53,17 +53,24 @@ public:
NS_DECL_NSIMSGSEARCHNOTIFY
virtual const char * GetViewName(void) {return "QuickSearchView"; }
NS_IMETHOD Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType,
nsMsgViewSortOrderValue sortOrder,
nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount);
NS_IMETHOD DoCommand(nsMsgViewCommandTypeValue aCommand);
NS_IMETHOD GetViewType(nsMsgViewTypeValue *aViewType);
NS_IMETHOD SetSearchSession(nsIMsgSearchSession *aSearchSession);
NS_IMETHOD GetSearchSession(nsIMsgSearchSession* *aSearchSession);
NS_IMETHOD Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
NS_IMETHOD OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags,
PRUint32 aNewFlags, nsIDBChangeListener *aInstigator);
protected:
nsWeakPtr m_searchSession;
nsMsgKeyArray m_origKeys;
virtual nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed);
virtual nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
virtual nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
virtual nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
virtual nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
void SavePreSearchInfo();
void ClearPreSearchInfo();

Просмотреть файл

@ -286,7 +286,7 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
// sort threads by sort order
PRBool sortThreads = m_viewFlags & (nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort);
// if sort type is by thread, but we're not threaded, change sort type to byId
// if sort type is by thread, and we're already threaded, change sort type to byId
if (sortType == nsMsgViewSortType::byThread && (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay) != 0)
sortType = nsMsgViewSortType::byId;
@ -489,6 +489,10 @@ nsresult nsMsgThreadedDBView::ListThreadIds(nsMsgKey *startMsg, PRBool unreadOnl
else
{
*startMsg = nsMsgKey_None;
nsCOMPtr <nsIDBChangeListener> dbListener = do_QueryInterface(m_threadEnumerator);
// this is needed to make the thread enumerator release its reference to the db.
if (dbListener)
dbListener->OnAnnouncerGoingAway(nsnull);
m_threadEnumerator = nsnull;
}
*pNumListed = numListed;

Просмотреть файл

@ -67,7 +67,7 @@ protected:
nsresult ListThreadIds(nsMsgKey *startMsg, PRBool unreadOnly, nsMsgKey *pOutput, PRInt32 *pFlags, char *pLevels,
PRInt32 numToList, PRInt32 *pNumListed, PRInt32 *pTotalHeaders);
nsresult InitSort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
virtual nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
virtual void OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extraFlag);
virtual void OnHeaderAddedOrDeleted();
void ClearPrevIdArray();

Просмотреть файл

@ -331,3 +331,24 @@ void nsUInt32Array::QuickSort (int (* PR_CALLBACK compare) (const void *elem1, c
if (m_nSize > 1)
NS_QuickSort(m_pData, m_nSize, sizeof(PRUint32), compare ? compare : CompareDWord, nsnull);
}
// Does a binary search - assumes array is sorted in ascending order.
PRUint32 nsUInt32Array::IndexOfSorted(PRUint32 element)
{
PRInt32 msgIndex = 0;
PRInt32 hi = m_nSize - 1;
PRInt32 lo = 0;
while (lo <= hi)
{
msgIndex = (lo + hi) / 2;
if (m_pData[msgIndex] == element)
return msgIndex;
if (m_pData[msgIndex] > element)
hi = msgIndex -1;
else if (m_pData[msgIndex] < element)
lo = msgIndex + 1;
}
return kNotFound;
}

Просмотреть файл

@ -74,6 +74,7 @@ public:
PRUint32 *GetData();
void SetAt(PRUint32 nIndex, PRUint32 newElement);
PRUint32 IndexOf(PRUint32 element);
PRUint32 IndexOfSorted(PRUint32 element);
// Insertion/deletion member functions
PRUint32 Add(PRUint32 newElement);