96 // ---------------------------------------------------------------------------- |
96 // ---------------------------------------------------------------------------- |
97 CPcsCache::~CPcsCache() |
97 CPcsCache::~CPcsCache() |
98 { |
98 { |
99 PRINT ( _L("Enter CPcsCache::~CPcsCache") ); |
99 PRINT ( _L("Enter CPcsCache::~CPcsCache") ); |
100 |
100 |
101 if ( iURI ) |
101 delete iURI; |
102 delete iURI; |
102 |
103 |
103 RemoveAllFromCache(); // cleans up iMasterPool and iCacheInfo |
104 // Loop thru cache info and free and the data elements |
104 |
105 THashMapIter<TInt, TInt> iter(cacheInfo); |
105 iKeyArr.ResetAndDestroy(); |
106 |
|
107 do |
|
108 { |
|
109 TInt* id = const_cast<TInt*>(iter.NextKey()); |
|
110 |
|
111 if ( id == NULL ) |
|
112 break; |
|
113 |
|
114 TInt* poolMap = iter.CurrentValue(); |
|
115 |
|
116 if ( poolMap == NULL ) |
|
117 { |
|
118 continue; |
|
119 } |
|
120 |
|
121 CPsData *data = NULL; |
|
122 for ( int keyIndex = 0; keyIndex < keyArr.Count(); keyIndex++ ) |
|
123 { |
|
124 TBool present = GetPoolMap(*poolMap, keyIndex); |
|
125 |
|
126 if ( ! present ) |
|
127 { |
|
128 continue; |
|
129 } |
|
130 |
|
131 RPointerArray<CPcsPoolElement> tmpKeyMap = *(keyArr[keyIndex]); |
|
132 for ( int arrayIndex = 0; |
|
133 arrayIndex < tmpKeyMap.Count(); |
|
134 arrayIndex++ ) |
|
135 { |
|
136 CPcsPoolElement *element = tmpKeyMap[arrayIndex]; |
|
137 TInt localId = element->GetPsData()->Id(); |
|
138 if ( *id == localId ) |
|
139 { |
|
140 data = element->GetPsData(); |
|
141 delete element; |
|
142 keyArr[keyIndex]->Remove(arrayIndex); |
|
143 } |
|
144 } |
|
145 }; |
|
146 |
|
147 // Remove this element from master pool |
|
148 for ( int arrayIndex = 0; |
|
149 arrayIndex < masterPool.Count(); |
|
150 arrayIndex++ ) |
|
151 { |
|
152 CPsData *dataElement = masterPool[arrayIndex]; |
|
153 TInt localId = dataElement->Id(); |
|
154 if ( *id == localId ) |
|
155 { |
|
156 masterPool.Remove(arrayIndex); |
|
157 } |
|
158 } |
|
159 |
|
160 if( data ) |
|
161 { |
|
162 delete data; |
|
163 } |
|
164 |
|
165 } |
|
166 while (1); |
|
167 |
|
168 for(TInt i= 0; i <keyArr.Count();i++ ) |
|
169 { |
|
170 keyArr[i]->ResetAndDestroy(); |
|
171 delete keyArr[i]; |
|
172 keyArr[i] = NULL; |
|
173 } |
|
174 |
|
175 masterPool.ResetAndDestroy(); |
|
176 |
|
177 cacheInfo.Close(); |
|
178 |
|
179 keyArr.Reset(); |
|
180 iDataFields.Reset(); |
106 iDataFields.Reset(); |
181 iSortOrder.Reset(); |
107 iSortOrder.Reset(); |
182 iIndexOrder.Reset(); |
108 iIndexOrder.Reset(); |
183 |
109 iMasterPoolBackup.Close(); |
184 PRINT ( _L("End CPcsCache::~CPcsCache") ); |
110 |
|
111 PRINT ( _L("End CPcsCache::~CPcsCache") ); |
185 } |
112 } |
186 |
113 |
187 // ---------------------------------------------------------------------------- |
114 // ---------------------------------------------------------------------------- |
188 // CPcsCache::GetContactsForKeyL |
115 // CPcsCache::GetContactsForKeyL |
189 // Get list of pool elements specific to a pool |
116 // Get list of pool elements specific to a pool |
190 // ---------------------------------------------------------------------------- |
117 // ---------------------------------------------------------------------------- |
191 void CPcsCache::GetContactsForKeyL(TInt aKeyId, RPointerArray<CPcsPoolElement>& aData) |
118 void CPcsCache::GetContactsForKeyL(TInt aKeyId, RPointerArray<CPcsPoolElement>& aData) |
192 { |
119 { |
193 PRINT ( _L("Enter CPcsCache::GetContactsForKeyL") ); |
120 PRINT ( _L("Enter CPcsCache::GetContactsForKeyL") ); |
194 |
121 |
195 RPointerArray<CPcsPoolElement> arr = *keyArr[aKeyId]; |
122 const RPointerArray<CPcsPoolElement>& arr = *iKeyArr[aKeyId]; |
196 for ( int i = 0; i < arr.Count(); i++ ) |
123 for ( TInt i = 0; i < arr.Count(); i++ ) |
197 { |
124 { |
198 CPcsPoolElement* value = arr[i]; |
125 CPcsPoolElement* value = arr[i]; |
199 aData.AppendL(value); |
126 aData.AppendL(value); |
200 } |
127 } |
201 |
128 |
222 |
149 |
223 // ---------------------------------------------------------------------------- |
150 // ---------------------------------------------------------------------------- |
224 // CPcsCache::AddToPool |
151 // CPcsCache::AddToPool |
225 // Adds a contact to cache |
152 // Adds a contact to cache |
226 // ---------------------------------------------------------------------------- |
153 // ---------------------------------------------------------------------------- |
227 void CPcsCache::AddToPoolL(TInt& aPoolMap, CPsData& aData) |
154 void CPcsCache::AddToPoolL(TUint64& aPoolMap, CPsData& aData) |
228 { |
155 { |
229 // Temp hash to remember the location of pool elements |
156 // Temp hash to remember the location of pool elements |
230 // First TInt = Pool |
157 // First TInt = Pool |
231 // Second TInt = Location in the pool |
158 // Second TInt = Location in the pool |
232 // Required for memory optimization so that more than one pool |
159 // Required for memory optimization so that more than one pool |
233 // element doesn't get added for the same data |
160 // element doesn't get added for the same data |
234 RHashMap<TInt, TInt> elementHash; |
161 RHashMap<TInt, TInt> elementHash; |
|
162 CleanupClosePushL( elementHash ); |
235 TLinearOrder<CPcsPoolElement> rule( CPcsPoolElement::CompareByData ); |
163 TLinearOrder<CPcsPoolElement> rule( CPcsPoolElement::CompareByData ); |
236 |
164 |
237 // Parse thru each data element |
165 // Parse thru each data element |
238 for ( int dataIndex = 0; dataIndex < aData.DataElementCount(); dataIndex++ ) |
166 for ( TInt dataIndex = 0; dataIndex < aData.DataElementCount(); dataIndex++ ) |
239 { |
167 { |
240 // Stores first key for each word |
168 // Find store all the pool IDs where this contact should be |
241 RArray<TUint> firstKey; |
169 RArray<TUint> poolIds; |
|
170 CleanupClosePushL( poolIds ); |
242 |
171 |
243 // Recover the first character |
172 // Recover the first character |
244 if ( aData.Data(dataIndex) && aData.Data(dataIndex)->Length() != 0 ) |
173 if ( aData.Data(dataIndex) && aData.Data(dataIndex)->Length() != 0 ) |
245 { |
174 { |
246 // Split the data into words |
175 // Split the data into words |
247 CWords* words = CWords::NewLC(*aData.Data(dataIndex)); |
176 CWords* words = CWords::NewLC(*aData.Data(dataIndex)); |
248 |
177 |
249 // Store the first numeric key for each word |
178 // Store the first numeric key for each word |
250 for ( int i = 0; i < words->MdcaCount(); i++ ) |
179 for ( TInt i = 0; i < words->MdcaCount(); i++ ) |
251 { |
180 { |
252 TChar firstChar = (words->MdcaPoint(i))[0]; |
181 TChar firstChar = (words->MdcaPoint(i))[0]; |
253 firstKey.Append(firstChar); |
182 |
|
183 // Pool ID according to ITU-T mappings |
|
184 TInt itutPoolId = iKeyMap->PoolIdForCharacter(firstChar, EPredictiveItuT); |
|
185 if ( itutPoolId != KErrNotFound ) |
|
186 { |
|
187 poolIds.Append(itutPoolId); |
|
188 } |
|
189 |
|
190 // Pool ID according to QWERTY mappings |
|
191 TInt qwertyPoolId = iKeyMap->PoolIdForCharacter(firstChar, EPredictiveQwerty); |
|
192 if ( qwertyPoolId != KErrNotFound ) |
|
193 { |
|
194 poolIds.Append(qwertyPoolId); |
|
195 } |
254 } |
196 } |
255 |
197 |
256 CleanupStack::PopAndDestroy(words); |
198 CleanupStack::PopAndDestroy(words); |
257 } |
199 } |
258 |
200 |
259 for ( TInt wordIndex = 0; wordIndex < firstKey.Count(); wordIndex++ ) |
201 for ( TInt poolIdIndex = 0; poolIdIndex < poolIds.Count(); poolIdIndex++ ) |
260 { |
202 { |
261 TInt arrayIndex =keyMap->PoolIdForCharacter(firstKey[wordIndex]); |
203 TUint poolId = poolIds[ poolIdIndex ]; |
262 |
|
263 CPcsPoolElement* element = NULL; |
204 CPcsPoolElement* element = NULL; |
264 |
205 |
265 // Check if an element already exists in the pool for this data |
206 // Check if an element already exists in the pool for this data |
266 TInt* loc = NULL; |
207 TInt* loc = NULL; |
267 loc = elementHash.Find(arrayIndex); |
208 loc = elementHash.Find(poolId); |
268 if ( loc != NULL ) |
209 if ( loc != NULL ) |
269 { |
210 { |
270 // Exists. Then recover ... |
211 // Exists. Then recover ... |
271 RPointerArray<CPcsPoolElement> tmpKeyMap = *(keyArr[arrayIndex]); |
212 const RPointerArray<CPcsPoolElement>& tmpKeyMap = *(iKeyArr[poolId]); |
272 element = tmpKeyMap[*loc]; |
213 element = tmpKeyMap[*loc]; |
273 } |
214 } |
274 |
215 |
275 if ( element == NULL ) // Pool element doesn't exist. Create new ... |
216 if ( element == NULL ) // Pool element doesn't exist. Create new ... |
276 { |
217 { |
277 element = CPcsPoolElement::NewL(aData); |
218 element = CPcsPoolElement::NewL(aData); |
|
219 CleanupStack::PushL( element ); |
278 element->ClearDataMatchAttribute(); |
220 element->ClearDataMatchAttribute(); |
279 element->SetDataMatch(dataIndex); |
221 element->SetDataMatch(dataIndex); |
280 |
222 |
281 // Insert to pool |
223 // Insert to pool |
282 keyArr[arrayIndex]->InsertInOrderAllowRepeatsL(element, rule); |
224 iKeyArr[poolId]->InsertInOrderAllowRepeatsL(element, rule); |
283 TInt index = keyArr[arrayIndex]->FindInOrderL(element, rule); |
225 CleanupStack::Pop( element ); // ownership transferred |
|
226 TInt index = iKeyArr[poolId]->FindInOrderL(element, rule); |
284 |
227 |
285 // Set the bit for this pool |
228 // Set the bit for this pool |
286 SetPoolMap(aPoolMap, arrayIndex); |
229 SetPoolMap(aPoolMap, poolId); |
287 |
230 |
288 // Store the array index in the temp hash |
231 // Store the array index in the temp hash |
289 elementHash.InsertL(arrayIndex, index ); |
232 elementHash.InsertL(poolId, index); |
290 } |
233 } |
291 else // Pool element exists. Just alter the data match attribute |
234 else // Pool element exists. Just alter the data match attribute |
292 { |
235 { |
293 element->SetDataMatch(dataIndex); |
236 element->SetDataMatch(dataIndex); |
294 |
237 |
295 // Set the bit for this pool |
238 // Set the bit for this pool |
296 SetPoolMap(aPoolMap, arrayIndex); |
239 SetPoolMap(aPoolMap, poolId); |
297 } |
240 } |
298 |
|
299 |
241 |
300 } // for 2 loop |
242 } // for 2 loop |
301 |
243 |
302 firstKey.Reset(); |
244 CleanupStack::PopAndDestroy( &poolIds ); |
303 |
245 |
304 } // for 1 loop |
246 } // for 1 loop |
305 |
247 |
306 elementHash.Close(); |
248 CleanupStack::PopAndDestroy( &elementHash ); |
307 } |
249 } |
308 |
250 |
309 // --------------------------------------------------------------------- |
251 // --------------------------------------------------------------------- |
310 // CPcsCache::AddToCacheL |
252 // CPcsCache::AddToCacheL |
311 // |
253 // |
312 // --------------------------------------------------------------------- |
254 // --------------------------------------------------------------------- |
313 void CPcsCache::AddToCacheL( CPsData& aData ) |
255 void CPcsCache::AddToCacheL( CPsData& aData ) |
314 { |
256 { |
315 // Protect against duplicate items getting added |
257 // Protect against duplicate items getting added |
316 if ( cacheInfo.Find(aData.Id()) != NULL ) |
258 if ( iCacheInfo.Find(aData.Id()) != NULL ) |
317 { |
259 { |
318 return; |
260 return; |
319 } |
261 } |
320 |
262 |
321 // Include this element in the pool |
263 // Include this element in the pool |
322 TInt poolMap = 0; |
264 TUint64 poolMap = 0; |
323 AddToPoolL(poolMap, aData); |
265 AddToPoolL(poolMap, aData); |
324 cacheInfo.InsertL(aData.Id(), poolMap); |
266 iCacheInfo.InsertL(aData.Id(), poolMap); |
325 |
267 |
326 // Include this element in master pool |
268 // Include this element in master pool |
327 TLinearOrder<CPsData> rule( CPcsAlgorithm1Utils::CompareDataBySortOrderL ); |
269 TLinearOrder<CPsData> rule( CPcsAlgorithm1Utils::CompareDataBySortOrderL ); |
328 masterPool.InsertInOrderAllowRepeatsL(&aData, rule); |
270 iMasterPool.InsertInOrderAllowRepeatsL(&aData, rule); |
329 } |
271 } |
330 |
272 |
331 // --------------------------------------------------------------------- |
273 // --------------------------------------------------------------------- |
332 // CPcsCache::RemoveContactL |
274 // CPcsCache::RemoveContactL |
333 // |
275 // |
334 // --------------------------------------------------------------------- |
276 // --------------------------------------------------------------------- |
335 void CPcsCache::RemoveFromCacheL( TInt aItemId ) |
277 void CPcsCache::RemoveFromCacheL( TInt aItemId ) |
336 { |
278 { |
337 CPsData *data = NULL; |
279 CPsData *data = NULL; |
338 |
280 |
339 TInt* poolMap = cacheInfo.Find(aItemId); |
281 TUint64* poolMap = iCacheInfo.Find(aItemId); |
340 |
282 |
341 if ( poolMap == NULL ) |
283 if ( poolMap == NULL ) |
342 { |
284 { |
343 return; |
285 return; |
344 } |
286 } |
345 |
287 |
346 // Remove this element from pools |
288 // Remove this element from pools |
347 for ( int keyIndex = 0; keyIndex < keyArr.Count(); keyIndex++ ) |
289 for ( TInt keyIndex = 0; keyIndex < iKeyArr.Count(); keyIndex++ ) |
348 { |
290 { |
349 TBool present = GetPoolMap(*poolMap, keyIndex); |
291 TBool present = GetPoolMap(*poolMap, keyIndex); |
350 |
292 |
351 if ( ! present ) |
293 if ( ! present ) |
352 { |
294 { |
353 continue; |
295 continue; |
354 } |
296 } |
355 |
297 |
356 RPointerArray<CPcsPoolElement> tmpKeyMap = *(keyArr[keyIndex]); |
298 const RPointerArray<CPcsPoolElement>& tmpKeyMap = *(iKeyArr[keyIndex]); |
357 for ( int arrayIndex = 0; |
299 for ( TInt arrayIndex = 0; |
358 arrayIndex < tmpKeyMap.Count(); |
300 arrayIndex < tmpKeyMap.Count(); |
359 arrayIndex++ ) |
301 arrayIndex++ ) |
360 { |
302 { |
361 CPcsPoolElement *element = tmpKeyMap[arrayIndex]; |
303 CPcsPoolElement *element = tmpKeyMap[arrayIndex]; |
362 TInt id = element->GetPsData()->Id(); |
304 TInt id = element->GetPsData()->Id(); |
363 if ( id == aItemId ) |
305 if ( id == aItemId ) |
364 { |
306 { |
365 data = element->GetPsData(); |
307 data = element->GetPsData(); |
366 delete element; |
308 delete element; |
367 keyArr[keyIndex]->Remove(arrayIndex); |
309 iKeyArr[keyIndex]->Remove(arrayIndex); |
368 } |
310 } |
369 } |
311 } |
370 }; |
312 }; |
371 |
313 |
372 // Remove this element from master pool |
314 // Remove this element from master pool |
373 for ( int arrayIndex = 0; |
315 for ( TInt arrayIndex = 0; |
374 arrayIndex < masterPool.Count(); |
316 arrayIndex < iMasterPool.Count(); |
375 arrayIndex++ ) |
317 arrayIndex++ ) |
376 { |
318 { |
377 CPsData *dataElement = masterPool[arrayIndex]; |
319 CPsData *dataElement = iMasterPool[arrayIndex]; |
378 TInt id = dataElement->Id(); |
320 TInt id = dataElement->Id(); |
379 if ( id == aItemId ) |
321 if ( id == aItemId ) |
380 { |
322 { |
381 masterPool.Remove(arrayIndex); |
323 iMasterPool.Remove(arrayIndex); |
382 } |
324 } |
383 } |
325 } |
384 |
326 |
385 // Delete data |
327 // Delete data |
386 if ( data ) |
328 if ( data ) |
388 delete data; |
330 delete data; |
389 data = NULL; |
331 data = NULL; |
390 } |
332 } |
391 |
333 |
392 // Clear up cache information |
334 // Clear up cache information |
393 cacheInfo.Remove(aItemId); |
335 iCacheInfo.Remove(aItemId); |
394 } |
336 } |
395 |
337 |
396 // --------------------------------------------------------------------- |
338 // --------------------------------------------------------------------- |
397 // CPcsCache::RemoveAllFromCacheL |
339 // CPcsCache::RemoveAllFromCache |
398 // |
340 // |
399 // --------------------------------------------------------------------- |
341 // --------------------------------------------------------------------- |
400 void CPcsCache::RemoveAllFromCacheL() |
342 void CPcsCache::RemoveAllFromCache() |
401 { |
343 { |
402 PRINT ( _L("Enter CPcsCache::RemoveAllFromCacheL") ); |
344 PRINT ( _L("Enter CPcsCache::RemoveAllFromCache") ); |
403 |
345 |
|
346 for ( TInt i = 0 ; i < iKeyArr.Count() ; i++ ) |
|
347 { |
|
348 iKeyArr[i]->ResetAndDestroy(); |
|
349 } |
404 |
350 |
405 for(TInt i= 0; i <keyArr.Count();i++ ) |
351 iMasterPool.ResetAndDestroy(); |
406 { |
352 iCacheInfo.Close(); |
407 keyArr[i]->ResetAndDestroy(); |
|
408 |
|
409 } |
|
410 |
353 |
411 masterPool.ResetAndDestroy(); |
354 PRINT ( _L("End CPcsCache::RemoveAllFromCache") ); |
412 cacheInfo.Close(); |
|
413 |
|
414 PRINT ( _L("End CPcsCache::RemoveAllFromCacheL") ); |
|
415 } |
355 } |
416 |
356 |
417 // --------------------------------------------------------------------- |
357 // --------------------------------------------------------------------- |
418 // CPcsCache::SetPoolMap |
358 // CPcsCache::SetPoolMap |
419 // |
359 // |
420 // --------------------------------------------------------------------- |
360 // --------------------------------------------------------------------- |
421 void CPcsCache::SetPoolMap(TInt& aPoolMap, TInt arrayIndex) |
361 void CPcsCache::SetPoolMap(TUint64& aPoolMap, TInt aArrayIndex) |
422 { |
362 { |
423 TReal val; |
363 __ASSERT_DEBUG( aArrayIndex < 64, User::Panic(_L("CPcsCache"), KErrOverflow ) ); |
424 Math::Pow(val, 2, arrayIndex); |
364 TUint64 val = 1 << aArrayIndex; |
425 |
365 aPoolMap |= val; |
426 aPoolMap |= (TInt)val; |
|
427 } |
366 } |
428 |
367 |
429 // --------------------------------------------------------------------- |
368 // --------------------------------------------------------------------- |
430 // CPcsCache::GetPoolMap |
369 // CPcsCache::GetPoolMap |
431 // |
370 // |
432 // --------------------------------------------------------------------- |
371 // --------------------------------------------------------------------- |
433 TBool CPcsCache::GetPoolMap(TInt& aPoolMap, TInt arrayIndex) |
372 TBool CPcsCache::GetPoolMap(TUint64& aPoolMap, TInt aArrayIndex) |
434 { |
373 { |
435 TReal val; |
374 __ASSERT_DEBUG( aArrayIndex < 64, User::Panic(_L("CPcsCache"), KErrOverflow ) ); |
436 Math::Pow(val, 2, arrayIndex); |
375 TUint64 val = 1 << aArrayIndex; |
437 |
376 return (aPoolMap & val); |
438 return (aPoolMap & (TInt)val); |
|
439 } |
377 } |
440 |
378 |
441 // --------------------------------------------------------------------- |
379 // --------------------------------------------------------------------- |
442 // CPcsCache::GetURI |
380 // CPcsCache::GetURI |
443 // |
381 // |