51 __FLOG_STMT(_LIT8(KComponent,"MTPObjectStore");) |
51 __FLOG_STMT(_LIT8(KComponent,"MTPObjectStore");) |
52 const TInt KMaxLimitCommitInEnumeration = 1024; |
52 const TInt KMaxLimitCommitInEnumeration = 1024; |
53 const TInt KMaxLimitCommitAfterEnumeration = 256; |
53 const TInt KMaxLimitCommitAfterEnumeration = 256; |
54 const TInt KMaxLimitCompactInEnumeration = 2048; |
54 const TInt KMaxLimitCompactInEnumeration = 2048; |
55 const TInt KMaxLimitCompactAfterEnumeration = 1024; |
55 const TInt KMaxLimitCompactAfterEnumeration = 1024; |
|
56 const TInt KSnapshotGranularity = 128; |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 CMTPObjectStore::CSnapshotWorker* CMTPObjectStore::CSnapshotWorker::NewL(CMTPObjectStore* aObjectStore, TBool aOnlyRoot) |
|
63 { |
|
64 CSnapshotWorker* self = new (ELeave) CMTPObjectStore::CSnapshotWorker(aObjectStore, aOnlyRoot); |
|
65 CleanupStack::PushL(self); |
|
66 self->ConstructL(); |
|
67 CleanupStack::Pop(self); |
|
68 return self; |
|
69 |
|
70 } |
|
71 |
|
72 void CMTPObjectStore::CSnapshotWorker::RunL() |
|
73 { |
|
74 iObjectStore->CleanDBSnapshotL(iOnlyRoot); |
|
75 } |
|
76 |
|
77 void CMTPObjectStore::CSnapshotWorker::DoCancel() |
|
78 { |
|
79 //nothing to do |
|
80 } |
|
81 |
|
82 TInt CMTPObjectStore::CSnapshotWorker::RunErr() |
|
83 { |
|
84 return KErrNone; |
|
85 } |
|
86 |
|
87 void CMTPObjectStore::CSnapshotWorker::ActiveSelf() |
|
88 { |
|
89 TRequestStatus *status = &iStatus; |
|
90 iStatus = KRequestPending; |
|
91 User::RequestComplete(status, KErrNone); |
|
92 SetActive(); |
|
93 } |
|
94 |
|
95 CMTPObjectStore::CSnapshotWorker::CSnapshotWorker(CMTPObjectStore* aObjectStore, TBool aOnlyRoot): |
|
96 CActive(EPriorityLow), iObjectStore(aObjectStore), iOnlyRoot(aOnlyRoot) |
|
97 { |
|
98 |
|
99 } |
|
100 |
|
101 void CMTPObjectStore::CSnapshotWorker::ConstructL() |
|
102 { |
|
103 CActiveScheduler::Add(this); |
|
104 } |
|
105 |
56 /** |
106 /** |
57 MTP object meta data store factory method. |
107 MTP object meta data store factory method. |
58 @return A pointer to a new CMTPObjectStore instance, ownership IS transferred. |
108 @return A pointer to a new CMTPObjectStore instance, ownership IS transferred. |
59 @leave One of the system wide error codes, if a processing failure occurs. |
109 @leave One of the system wide error codes, if a processing failure occurs. |
60 */ |
110 */ |
831 iCompactor = CDbCompactor::NewL(&iDatabase); |
893 iCompactor = CDbCompactor::NewL(&iDatabase); |
832 iMtpDeltaDataMgr = CMtpDeltaDataMgr::NewL(iDatabase); |
894 iMtpDeltaDataMgr = CMtpDeltaDataMgr::NewL(iDatabase); |
833 iReferenceMgr = CMTPReferenceMgr::NewL(*this); |
895 iReferenceMgr = CMTPReferenceMgr::NewL(*this); |
834 iDPIDStore = CMTPDPIDStore::NewL(iDatabase); |
896 iDPIDStore = CMTPDPIDStore::NewL(iDatabase); |
835 iPkgIDStore = CMTPPkgIDStore::NewL(iDatabase); |
897 iPkgIDStore = CMTPPkgIDStore::NewL(iDatabase); |
836 iBatched.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
898 User::LeaveIfError(iBatched.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
837 iBatched.SetIndex(KSQLHandleId); |
899 User::LeaveIfError(iBatched.SetIndex(KSQLHandleId)); |
838 iBatched_SuidHashID.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
900 User::LeaveIfError(iBatched_SuidHashID.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
839 iBatched_SuidHashID.SetIndex(KSQLSuidHash); |
901 User::LeaveIfError(iBatched_SuidHashID.SetIndex(KSQLSuidHash)); |
840 iHandleAllocator = CMTPHandleAllocator::NewL(*this); |
902 iHandleAllocator = CMTPHandleAllocator::NewL(*this); |
841 iSentinal = CEnumertingCacheItem::NewL(0, 0, 0, 0, 0); |
903 iSentinal = CEnumertingCacheItem::NewL(0, 0, 0, 0, 0, 0); |
842 BeginTransactionL(); |
904 BeginTransactionL(); |
843 } |
905 } |
844 |
906 |
845 /** |
907 /** |
846 Initialises the database, it creates the table and index if the database does not exist, otherwise, |
908 Initialises the database, it creates the table and index if the database does not exist, otherwise, |
1169 } |
1232 } |
1170 } |
1233 } |
1171 } |
1234 } |
1172 } |
1235 } |
1173 |
1236 |
|
1237 |
|
1238 |
1174 void CMTPObjectStore::EstablishDBSnapshotL(TUint32 aStorageId) |
1239 void CMTPObjectStore::EstablishDBSnapshotL(TUint32 aStorageId) |
1175 { |
1240 { |
1176 //Currently, i only do this for File DP since it is non-persistent, later, if we take the proposal that |
1241 //Currently, i only do this for File DP since it is non-persistent, later, if we take the proposal that |
1177 //1. FileDP is the last DP to be enumerated. |
1242 //1. FileDP is the last DP to be enumerated. |
1178 //2. FileDP will san the whole file system, and will try to enumerate all of the objects(might on behalf of another DP) if the objects is still not |
1243 //2. FileDP will san the whole file system, and will try to enumerate all of the objects(might on behalf of another DP) if the objects is still not |
1179 // in the object store after all other DP finish its enumeration. |
1244 // in the object store after all other DP finish its enumeration. |
1180 //3. Then notify the related DP about the newly added objects by notification API; |
1245 //3. Then notify the related DP about the newly added objects by notification API; |
1181 //_LIT(KInsert, "CMTPObjectStore::EstablishDBSnapshotL"); |
1246 __FLOG(_L8("EstablishDBSnapshotL - Entry")); |
1182 //volatile TTimer t(KInsert); |
1247 RDbTable temp; |
1183 RDbTable temp; |
1248 CleanupClosePushL(temp); |
1184 CleanupClosePushL(temp); |
1249 User::LeaveIfError(temp.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
1185 temp.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
|
1186 if(!iCacheExist) |
1250 if(!iCacheExist) |
1187 { |
1251 { |
1188 TInt32 count = temp.CountL(RDbRowSet::EQuick); |
1252 TInt32 count = temp.CountL(RDbRowSet::EQuick); |
1189 iEnumeratingCacheObjList.ReserveL(count); |
1253 iEnumeratingCacheObjList.ReserveL(count); |
1190 } |
1254 } |
1191 temp.FirstL(); |
1255 temp.FirstL(); |
1192 while (!temp.AtEnd()) |
1256 |
1193 { |
1257 while (!temp.AtEnd()) |
1194 temp.GetL(); |
1258 { |
1195 if (temp.ColUint8(EObjectStoreDPFlag) == 1 && (KMTPStorageAll == aStorageId || temp.ColUint32(EObjectStoreStorageId) == aStorageId)) |
1259 temp.GetL(); |
1196 { |
1260 if (temp.ColUint8(EObjectStoreDPFlag) == 1 |
1197 TUint32 handleID = temp.ColUint32(EObjectStoreHandleId); |
1261 && (KMTPStorageAll == aStorageId || temp.ColUint32(EObjectStoreStorageId) == aStorageId)) |
1198 TInt64 pUID = temp.ColInt64(EObjectStorePOUID); |
1262 { |
1199 iHandleAllocator->SetIdL(handleID, pUID); |
1263 TUint32 handleID = temp.ColUint32(EObjectStoreHandleId); |
1200 CEnumertingCacheItem* item = CEnumertingCacheItem::NewLC( |
1264 TUint32 parentID = temp.ColUint32(EObjectStoreParentHandle); |
1201 temp.ColUint32(EObjectStoreSUIDHash), handleID, |
1265 TInt64 pUID = temp.ColInt64(EObjectStorePOUID); |
1202 temp.ColUint16(EObjectStoreFormatCode), pUID, temp.ColUint8(EObjectStoreDataProviderId)); |
1266 iHandleAllocator->SetIdL(handleID, pUID); |
1203 TInt result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1267 CEnumertingCacheItem* item = CEnumertingCacheItem::NewLC( |
1204 if (KErrAlreadyExists == result) //hash collision |
1268 temp.ColUint32(EObjectStoreSUIDHash), handleID, parentID, |
1205 { |
1269 temp.ColUint16(EObjectStoreFormatCode), pUID, temp.ColUint8(EObjectStoreDataProviderId)); |
1206 TInt found = iEnumeratingCacheObjList.FindInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1270 TInt result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1207 CEnumertingCacheItem* colliItem = iEnumeratingCacheObjList[found]; |
1271 if (KErrAlreadyExists == result) //hash collision |
|
1272 { |
|
1273 TInt found = iEnumeratingCacheObjList.FindInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
|
1274 CEnumertingCacheItem* colliItem = iEnumeratingCacheObjList[found]; |
1208 TFileName suid; |
1275 TFileName suid; |
1209 if (colliItem->iSuid == NULL) |
1276 if (colliItem->iSuid == NULL) |
1210 { |
1277 { |
1211 if (LocateByHandleL(colliItem->iObjHandleId)) |
1278 if (LocateByHandleL(colliItem->iObjHandleId)) |
1212 { |
1279 { |
1213 DbColReadStreamL(iBatched, EObjectStoreSUID, suid); |
1280 DbColReadStreamL(iBatched, EObjectStoreSUID, suid); |
1214 |
1281 colliItem->iSuid = suid.AllocL(); |
1215 colliItem->iSuid = suid.AllocL(); |
1282 colliItem->iSuidPtr.Set(*colliItem->iSuid); |
1216 |
1283 } |
1217 colliItem->iSuidPtr.Set(*colliItem->iSuid); |
1284 } |
1218 } |
1285 |
1219 } |
|
1220 DbColReadStreamL(temp, EObjectStoreSUID, suid); |
1286 DbColReadStreamL(temp, EObjectStoreSUID, suid); |
1221 |
1287 |
1222 item->iSuid = suid.AllocL(); |
1288 item->iSuid = suid.AllocL(); |
1223 |
1289 |
1224 item->iSuidPtr.Set(*item->iSuid); |
1290 item->iSuidPtr.Set(*item->iSuid); |
1225 result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1291 result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1226 } |
1292 } |
|
1293 |
1227 if(result != KErrAlreadyExists) |
1294 if(result != KErrAlreadyExists) |
1228 { |
1295 { |
1229 User::LeaveIfError(result); |
1296 User::LeaveIfError(result); |
1230 } |
1297 CleanupStack::Pop(item); |
1231 CleanupStack::Pop(item); |
1298 } |
1232 } |
1299 else |
1233 temp.NextL(); |
1300 { |
1234 } |
1301 CleanupStack::PopAndDestroy(item); |
1235 CleanupStack::PopAndDestroy(&temp); |
1302 } |
1236 iCacheExist = ETrue; |
1303 |
1237 } |
1304 } |
1238 |
1305 temp.NextL(); |
1239 void CMTPObjectStore::CleanDBSnapshotL() |
1306 } |
1240 { |
1307 |
1241 //For those items left in the iEnumeratingCacheObjList, remove the object entry if the DPID of the handle is not persistent. and populate the |
1308 CleanupStack::PopAndDestroy(&temp); |
1242 //roundtrip table if needed. |
1309 iCacheExist = ETrue; |
1243 //and then close the iEnumeratingCacheObjList to release the memory. |
1310 __FLOG_VA((_L8("EstablishDBSnapshotL - Exit build %d items"), iEnumeratingCacheObjList.Count())); |
1244 //_LIT(KInsert, "CMTPObjectStore::CleanDBSnapshot"); |
1311 } |
1245 //volatile TTimer t(KInsert); |
1312 /* |
1246 if(iCacheExist) |
1313 * All Objects enumeration complete |
1247 { |
1314 */ |
1248 iCacheExist = EFalse; |
1315 void CMTPObjectStore::ObjectsEnumComplete() |
1249 } |
1316 { |
1250 else |
1317 if(iCacheExist) |
1251 return; |
1318 { |
1252 |
1319 iCacheExist = EFalse; |
1253 for (TInt i = iEnumeratingCacheObjList.Count() - 1; i >= 0; i--) |
1320 } |
1254 { |
1321 iNonPersistentDPList.Close(); |
1255 TInt rc = iNonPersistentDPList.FindInOrder(iEnumeratingCacheObjList[i]->iDpID); |
1322 iEnumeratingCacheObjList.ResetAndDestroy(); |
1256 if (rc != KErrNotFound) |
1323 iUpdateDeltaDataTable = ETrue; |
1257 {//This is a non persistent DP. |
1324 iMaxCommitLimit = KMaxLimitCommitAfterEnumeration; |
1258 RemoveObjectL(iEnumeratingCacheObjList[i]->iObjHandleId); |
1325 iMaxCompactLimit = KMaxLimitCompactAfterEnumeration; |
1259 } |
|
1260 } |
|
1261 iNonPersistentDPList.Close(); |
|
1262 iEnumeratingCacheObjList.ResetAndDestroy(); |
|
1263 iUpdateDeltaDataTable = ETrue; |
|
1264 iMaxCommitLimit = KMaxLimitCommitAfterEnumeration; |
|
1265 iMaxCompactLimit = KMaxLimitCompactAfterEnumeration; |
|
1266 CommitTransactionL(); |
1326 CommitTransactionL(); |
1267 User::LeaveIfError(iDatabase.Compact()); |
1327 User::LeaveIfError(iDatabase.Compact()); |
1268 BeginTransactionL(); |
1328 BeginTransactionL(); |
1269 } |
1329 } |
1270 |
1330 |
1271 CMTPObjectStore::CEnumertingCacheItem::CEnumertingCacheItem(TUint32 aSuidHash, TUint32 aHandle, TUint32 aFormat, TUint64 aId, TUint8 aDpID) |
1331 |
|
1332 void CMTPObjectStore::CleanDBSnapshotL(TBool aOnlyRoot/* = EFalse*/) |
|
1333 { |
|
1334 //For those items left in the iEnumeratingCacheObjList, remove the object entry if the DPID of the handle is not persistent. and populate the |
|
1335 //roundtrip table if needed. |
|
1336 //and then close the iEnumeratingCacheObjList to release the memory. |
|
1337 //_LIT(KInsert, "CMTPObjectStore::CleanDBSnapshot"); |
|
1338 //volatile TTimer t(KInsert); |
|
1339 __FLOG(_L8("CleanDBSnapshotL Entry")); |
|
1340 if (iSnapshotWorker == NULL) |
|
1341 { |
|
1342 iSnapshotCleanPos = iEnumeratingCacheObjList.Count() - 1; |
|
1343 iSnapshotWorker = CSnapshotWorker::NewL(this, aOnlyRoot); |
|
1344 } |
|
1345 |
|
1346 //for (TInt i = iEnumeratingCacheObjList.Count() - 1; i >= 0; i--) |
|
1347 for (TInt i = 0; iSnapshotCleanPos >= 0 && i <= KSnapshotGranularity; --iSnapshotCleanPos, ++i) |
|
1348 { |
|
1349 if((aOnlyRoot && iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjParentId == KMTPHandleNoParent) //only root |
|
1350 ||(!aOnlyRoot)) //everything |
|
1351 { |
|
1352 TInt rc = iNonPersistentDPList.FindInOrder(iEnumeratingCacheObjList[iSnapshotCleanPos]->iDpID); |
|
1353 if (rc != KErrNotFound) |
|
1354 {//This is a non persistent DP. |
|
1355 __FLOG_VA((_L8("Remove Object 0x%x"), iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjHandleId)); |
|
1356 RemoveObjectL(iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjHandleId); |
|
1357 } |
|
1358 } |
|
1359 } |
|
1360 |
|
1361 if (iSnapshotCleanPos >= 0) |
|
1362 { |
|
1363 iSnapshotWorker->ActiveSelf(); |
|
1364 } |
|
1365 else |
|
1366 { |
|
1367 //TRequestStatus *status = &aStatus; |
|
1368 //User::RequestComplete(status, KErrNone); |
|
1369 iSingletons.DpController().Schedule(); |
|
1370 iSnapshotCleanPos = 0; |
|
1371 delete iSnapshotWorker; |
|
1372 iSnapshotWorker = NULL; |
|
1373 } |
|
1374 |
|
1375 __FLOG(_L8("CleanDBSnapshotL Exit")); |
|
1376 } |
|
1377 |
|
1378 CMTPObjectStore::CEnumertingCacheItem::CEnumertingCacheItem(TUint32 aSuidHash, TUint32 aHandle, TUint32 aParent, TUint32 aFormat, TUint64 aId, TUint8 aDpID) |
1272 { |
1379 { |
1273 iObjSuiIdHash = aSuidHash; |
1380 iObjSuiIdHash = aSuidHash; |
1274 iObjHandleId = aHandle; |
1381 iObjHandleId = aHandle; |
|
1382 iObjParentId = aParent; |
1275 iFormatcode = aFormat; |
1383 iFormatcode = aFormat; |
1276 iPOUID = aId; |
1384 iPOUID = aId; |
1277 iDpID = aDpID; |
1385 iDpID = aDpID; |
1278 } |
1386 } |
1279 |
1387 |