зеркало из https://github.com/mozilla/pjs.git
Enhanced GetAllEvents() and added comments for further improvement in
bug 262620: GetAllEvents() is slow
This commit is contained in:
Родитель
b7b1ca9fe9
Коммит
8502dea2a5
|
@ -1291,6 +1291,18 @@ oeICalImpl::DeleteEvent( const char *id )
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* GetAllEvents
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Returns a list of all the events in this calendar in an enumerator.
|
||||||
|
* The events are sorted based on the order of their next occurence if they recur in
|
||||||
|
* the future or their last occurence in the past otherwise.
|
||||||
|
* Here's a presentation of the sort criteria using the time axis:
|
||||||
|
* -----(Last occurence of Event1)---(Last occurence of Event2)----(Now)----(Next occurence of Event3)---->
|
||||||
|
* (Note that Event1 and Event2 will not recur in the future.)
|
||||||
|
*/
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
|
oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
|
||||||
{
|
{
|
||||||
|
@ -1298,15 +1310,19 @@ oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
|
||||||
printf( "oeICalImpl::GetAllEvents()\n" );
|
printf( "oeICalImpl::GetAllEvents()\n" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Create a new enumerator to be returned
|
||||||
oeEventEnumerator *eventEnum = new oeEventEnumerator();
|
oeEventEnumerator *eventEnum = new oeEventEnumerator();
|
||||||
if (!eventEnum)
|
if (!eventEnum)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
//Create an array to temporarily store the events in
|
||||||
|
//Events added to the enumerator will be removed from this array
|
||||||
nsCOMPtr<nsISupportsArray> eventArray;
|
nsCOMPtr<nsISupportsArray> eventArray;
|
||||||
NS_NewISupportsArray(getter_AddRefs(eventArray));
|
NS_NewISupportsArray(getter_AddRefs(eventArray));
|
||||||
if (eventArray == nsnull)
|
if (eventArray == nsnull)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
//Fill in the array
|
||||||
EventList *tmplistptr = &m_eventlist;
|
EventList *tmplistptr = &m_eventlist;
|
||||||
while( tmplistptr ) {
|
while( tmplistptr ) {
|
||||||
if( tmplistptr->event ) {
|
if( tmplistptr->event ) {
|
||||||
|
@ -1315,21 +1331,29 @@ oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
|
||||||
tmplistptr = tmplistptr->next;
|
tmplistptr = tmplistptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRTime todayinms = PR_Now();
|
//Calculate the present time in milliseconds
|
||||||
|
PRTime nowinms = PR_Now();
|
||||||
PRInt64 usecpermsec;
|
PRInt64 usecpermsec;
|
||||||
LL_I2L( usecpermsec, PR_USEC_PER_MSEC );
|
LL_I2L( usecpermsec, PR_USEC_PER_MSEC );
|
||||||
LL_DIV( todayinms, todayinms, usecpermsec );
|
LL_DIV( nowinms, nowinms, usecpermsec );
|
||||||
|
|
||||||
struct icaltimetype checkdate = ConvertFromPrtime( todayinms );
|
struct icaltimetype now = ConvertFromPrtime( nowinms );
|
||||||
struct icaltimetype now = ConvertFromPrtime( todayinms );
|
struct icaltimetype checkdate = now;
|
||||||
|
//use Now-1 so we ensure we consider Now in the calculation
|
||||||
icaltime_adjust( &now, 0, 0, 0, -1 );
|
icaltime_adjust( &now, 0, 0, 0, -1 );
|
||||||
|
|
||||||
icaltimetype nextcheckdate;
|
|
||||||
PRUint32 num;
|
PRUint32 num;
|
||||||
|
oeIICalEvent* oldestEvent;
|
||||||
|
|
||||||
|
//This do-while loop finds the last occurences of events that don't recur in the future
|
||||||
|
//and adds them to the enumerator starting with the oldest occuring event
|
||||||
do {
|
do {
|
||||||
icaltimetype soonest = icaltime_null_time();
|
icaltimetype oldest;
|
||||||
eventArray->Count( &num );
|
eventArray->Count( &num );
|
||||||
|
int index_of_oldest=0;
|
||||||
|
oldestEvent=nsnull;
|
||||||
|
//This loop finds the oldest between the last instances of events in the passed
|
||||||
|
//that don't have a recurrence in the future.
|
||||||
for ( unsigned int i=0; i<num; i++ ) {
|
for ( unsigned int i=0; i<num; i++ ) {
|
||||||
nsCOMPtr<oeIICalEvent> tmpcomp;
|
nsCOMPtr<oeIICalEvent> tmpcomp;
|
||||||
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
||||||
|
@ -1338,77 +1362,68 @@ oeICalImpl::GetAllEvents(nsISimpleEnumerator **resultList )
|
||||||
if( !icaltime_is_null_time( next ) )
|
if( !icaltime_is_null_time( next ) )
|
||||||
continue;
|
continue;
|
||||||
icaltimetype previous = ((oeICalEventImpl *)tmpevent)->GetPreviousOccurrence( checkdate );
|
icaltimetype previous = ((oeICalEventImpl *)tmpevent)->GetPreviousOccurrence( checkdate );
|
||||||
if( !icaltime_is_null_time( previous ) && ( icaltime_is_null_time( soonest ) || (icaltime_compare( soonest, previous ) > 0) ) ) {
|
if( !icaltime_is_null_time( previous ) && ( !oldestEvent || (icaltime_compare( oldest, previous ) > 0) ) ) {
|
||||||
soonest = previous;
|
oldest = previous;
|
||||||
|
index_of_oldest = i;
|
||||||
|
oldestEvent = tmpevent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextcheckdate = soonest;
|
//The oldest event is added to the enum and removed from the array
|
||||||
if( !icaltime_is_null_time( nextcheckdate )) {
|
//so the loop can continue
|
||||||
|
if( oldestEvent ) {
|
||||||
for ( unsigned int i=0; i<num; i++ ) {
|
eventEnum->AddEvent( oldestEvent );
|
||||||
nsCOMPtr<oeIICalEvent> tmpcomp;
|
eventArray->RemoveElementAt( index_of_oldest );
|
||||||
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
|
||||||
oeIICalEvent* tmpevent = tmpcomp;
|
|
||||||
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( now, nsnull );
|
|
||||||
if( !icaltime_is_null_time( next ) )
|
|
||||||
continue;
|
|
||||||
icaltimetype previous = ((oeICalEventImpl *)tmpevent)->GetPreviousOccurrence( checkdate );
|
|
||||||
if( !icaltime_is_null_time( previous ) && (icaltime_compare( nextcheckdate, previous ) == 0) ) {
|
|
||||||
eventEnum->AddEvent( tmpevent );
|
|
||||||
// PRTime nextdateinms = ConvertToPrtime( nextcheckdate );
|
|
||||||
// dateEnum->AddDate( nextdateinms );
|
|
||||||
eventArray->RemoveElementAt( i );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while ( !icaltime_is_null_time( nextcheckdate ) );
|
|
||||||
|
|
||||||
checkdate = ConvertFromPrtime( todayinms );
|
} while ( oldestEvent );
|
||||||
icaltime_adjust( &checkdate, 0, 0, 0, -1 );
|
|
||||||
|
//start with Now
|
||||||
|
checkdate = ConvertFromPrtime( nowinms );
|
||||||
|
|
||||||
|
oeIICalEvent* soonestEvent;
|
||||||
|
//This do-while loop finds the next occurences of events
|
||||||
|
//and adds them to the enumerator starting with the soonest occuring event
|
||||||
do {
|
do {
|
||||||
|
int index_of_soonest=0;
|
||||||
icaltimetype soonest = icaltime_null_time();
|
icaltimetype soonest;
|
||||||
eventArray->Count( &num );
|
eventArray->Count( &num );
|
||||||
|
soonestEvent=nsnull;
|
||||||
|
//start checking from checkdate-1 which ensures we consider
|
||||||
|
//events happening right on checkdate as well
|
||||||
|
icaltime_adjust( &checkdate, 0, 0, 0, -1 );
|
||||||
|
|
||||||
for ( unsigned int i=0; i<num; i++ ) {
|
for ( unsigned int i=0; i<num; i++ ) {
|
||||||
nsCOMPtr<oeIICalEvent> tmpcomp;
|
nsCOMPtr<oeIICalEvent> tmpcomp;
|
||||||
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
||||||
oeIICalEvent* tmpevent = tmpcomp;
|
oeIICalEvent* tmpevent = tmpcomp;
|
||||||
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( checkdate, nsnull );
|
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( checkdate, nsnull );
|
||||||
next.is_date = false;
|
next.is_date = false;
|
||||||
if( !icaltime_is_null_time( next ) && ( icaltime_is_null_time( soonest ) || (icaltime_compare( soonest, next ) > 0) ) ) {
|
if( !icaltime_is_null_time( next ) && ( !soonestEvent || (icaltime_compare( soonest, next ) > 0) ) ) {
|
||||||
soonest = next;
|
soonest = next;
|
||||||
|
index_of_soonest = i;
|
||||||
|
soonestEvent = tmpevent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextcheckdate = soonest;
|
if( soonestEvent ) {
|
||||||
|
eventEnum->AddEvent( soonestEvent );
|
||||||
if( !icaltime_is_null_time( nextcheckdate )) {
|
eventArray->RemoveElementAt( index_of_soonest );
|
||||||
|
//continue checking from soonest instead of Now
|
||||||
for ( unsigned int i=0; i<num; i++ ) {
|
checkdate = soonest;
|
||||||
nsCOMPtr<oeIICalEvent> tmpcomp;
|
|
||||||
eventArray->GetElementAt( i, getter_AddRefs( tmpcomp ) );
|
|
||||||
oeIICalEvent* tmpevent = tmpcomp;
|
|
||||||
icaltimetype next = ((oeICalEventImpl *)tmpevent)->GetNextRecurrence( checkdate, nsnull );
|
|
||||||
next.is_date = false;
|
|
||||||
if( !icaltime_is_null_time( next ) && (icaltime_compare( nextcheckdate, next ) == 0) ) {
|
|
||||||
eventEnum->AddEvent( tmpevent );
|
|
||||||
// PRTime nextdateinms = ConvertToPrtime( nextcheckdate );
|
|
||||||
// dateEnum->AddDate( nextdateinms );
|
|
||||||
eventArray->RemoveElementAt( i );
|
|
||||||
icaltime_adjust( &nextcheckdate, 0, 0, 0, -1 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkdate = nextcheckdate;
|
|
||||||
}
|
}
|
||||||
} while ( !icaltime_is_null_time( nextcheckdate ) );
|
|
||||||
|
|
||||||
// bump ref count
|
} while ( soonestEvent );
|
||||||
// return eventEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)resultList);
|
|
||||||
|
#ifdef ICAL_DEBUG
|
||||||
|
//There shouldn't be any events in the array when we get here
|
||||||
|
eventArray->Count( &num );
|
||||||
|
if( num )
|
||||||
|
printf( "oeICalImpl::GetAllEvents - WARNING: Not all events were processed\n" );
|
||||||
|
#endif
|
||||||
|
|
||||||
*resultList = eventEnum;
|
*resultList = eventEnum;
|
||||||
|
// bump ref count
|
||||||
NS_ADDREF(*resultList);
|
NS_ADDREF(*resultList);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче