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); |
892 iCompactor = CDbCompactor::NewL(&iDatabase); |
832 iMtpDeltaDataMgr = CMtpDeltaDataMgr::NewL(iDatabase); |
893 iMtpDeltaDataMgr = CMtpDeltaDataMgr::NewL(iDatabase); |
833 iReferenceMgr = CMTPReferenceMgr::NewL(*this); |
894 iReferenceMgr = CMTPReferenceMgr::NewL(*this); |
834 iDPIDStore = CMTPDPIDStore::NewL(iDatabase); |
895 iDPIDStore = CMTPDPIDStore::NewL(iDatabase); |
835 iPkgIDStore = CMTPPkgIDStore::NewL(iDatabase); |
896 iPkgIDStore = CMTPPkgIDStore::NewL(iDatabase); |
836 iBatched.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
897 User::LeaveIfError(iBatched.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
837 iBatched.SetIndex(KSQLHandleId); |
898 User::LeaveIfError(iBatched.SetIndex(KSQLHandleId)); |
838 iBatched_SuidHashID.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
899 User::LeaveIfError(iBatched_SuidHashID.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
839 iBatched_SuidHashID.SetIndex(KSQLSuidHash); |
900 User::LeaveIfError(iBatched_SuidHashID.SetIndex(KSQLSuidHash)); |
840 iHandleAllocator = CMTPHandleAllocator::NewL(*this); |
901 iHandleAllocator = CMTPHandleAllocator::NewL(*this); |
841 iSentinal = CEnumertingCacheItem::NewL(0, 0, 0, 0, 0); |
902 iSentinal = CEnumertingCacheItem::NewL(0, 0, 0, 0, 0, 0); |
842 BeginTransactionL(); |
903 BeginTransactionL(); |
843 } |
904 } |
844 |
905 |
845 /** |
906 /** |
846 Initialises the database, it creates the table and index if the database does not exist, otherwise, |
907 Initialises the database, it creates the table and index if the database does not exist, otherwise, |
1169 } |
1234 } |
1170 } |
1235 } |
1171 } |
1236 } |
1172 } |
1237 } |
1173 |
1238 |
|
1239 |
|
1240 |
1174 void CMTPObjectStore::EstablishDBSnapshotL(TUint32 aStorageId) |
1241 void CMTPObjectStore::EstablishDBSnapshotL(TUint32 aStorageId) |
1175 { |
1242 { |
1176 //Currently, i only do this for File DP since it is non-persistent, later, if we take the proposal that |
1243 //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. |
1244 //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 |
1245 //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. |
1246 // 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; |
1247 //3. Then notify the related DP about the newly added objects by notification API; |
1181 //_LIT(KInsert, "CMTPObjectStore::EstablishDBSnapshotL"); |
1248 __FLOG(_L8("EstablishDBSnapshotL - Entry")); |
1182 //volatile TTimer t(KInsert); |
1249 RDbTable temp; |
1183 RDbTable temp; |
1250 CleanupClosePushL(temp); |
1184 CleanupClosePushL(temp); |
1251 User::LeaveIfError(temp.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable)); |
1185 temp.Open(iDatabase, KSQLHandleTableName, RDbRowSet::EUpdatable); |
|
1186 if(!iCacheExist) |
1252 if(!iCacheExist) |
1187 { |
1253 { |
1188 TInt32 count = temp.CountL(RDbRowSet::EQuick); |
1254 TInt32 count = temp.CountL(RDbRowSet::EQuick); |
1189 iEnumeratingCacheObjList.ReserveL(count); |
1255 iEnumeratingCacheObjList.ReserveL(count); |
1190 } |
1256 } |
1191 temp.FirstL(); |
1257 temp.FirstL(); |
1192 while (!temp.AtEnd()) |
1258 |
1193 { |
1259 while (!temp.AtEnd()) |
1194 temp.GetL(); |
1260 { |
1195 if (temp.ColUint8(EObjectStoreDPFlag) == 1 && (KMTPStorageAll == aStorageId || temp.ColUint32(EObjectStoreStorageId) == aStorageId)) |
1261 temp.GetL(); |
1196 { |
1262 if (temp.ColUint8(EObjectStoreDPFlag) == 1 |
1197 TUint32 handleID = temp.ColUint32(EObjectStoreHandleId); |
1263 && (KMTPStorageAll == aStorageId || temp.ColUint32(EObjectStoreStorageId) == aStorageId)) |
1198 TInt64 pUID = temp.ColInt64(EObjectStorePOUID); |
1264 { |
1199 iHandleAllocator->SetIdL(handleID, pUID); |
1265 TUint32 handleID = temp.ColUint32(EObjectStoreHandleId); |
1200 CEnumertingCacheItem* item = CEnumertingCacheItem::NewLC( |
1266 TUint32 parentID = temp.ColUint32(EObjectStoreParentHandle); |
1201 temp.ColUint32(EObjectStoreSUIDHash), handleID, |
1267 TInt64 pUID = temp.ColInt64(EObjectStorePOUID); |
1202 temp.ColUint16(EObjectStoreFormatCode), pUID, temp.ColUint8(EObjectStoreDataProviderId)); |
1268 iHandleAllocator->SetIdL(handleID, pUID); |
1203 TInt result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1269 CEnumertingCacheItem* item = CEnumertingCacheItem::NewLC( |
1204 if (KErrAlreadyExists == result) //hash collision |
1270 temp.ColUint32(EObjectStoreSUIDHash), handleID, parentID, |
1205 { |
1271 temp.ColUint16(EObjectStoreFormatCode), pUID, temp.ColUint8(EObjectStoreDataProviderId)); |
1206 TInt found = iEnumeratingCacheObjList.FindInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1272 TInt result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1207 CEnumertingCacheItem* colliItem = iEnumeratingCacheObjList[found]; |
1273 if (KErrAlreadyExists == result) //hash collision |
|
1274 { |
|
1275 TInt found = iEnumeratingCacheObjList.FindInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
|
1276 CEnumertingCacheItem* colliItem = iEnumeratingCacheObjList[found]; |
1208 TFileName suid; |
1277 TFileName suid; |
1209 if (colliItem->iSuid == NULL) |
1278 if (colliItem->iSuid == NULL) |
1210 { |
1279 { |
1211 if (!LocateByHandleL(colliItem->iObjHandleId)) |
1280 if (LocateByHandleL(colliItem->iObjHandleId)) |
1212 { |
1281 { |
1213 DbColReadStreamL(iBatched, EObjectStoreSUID, suid); |
1282 DbColReadStreamL(iBatched, EObjectStoreSUID, suid); |
1214 |
1283 colliItem->iSuid = suid.AllocL(); |
1215 colliItem->iSuid = suid.AllocL(); |
1284 colliItem->iSuidPtr.Set(*colliItem->iSuid); |
1216 |
1285 } |
1217 colliItem->iSuidPtr.Set(*colliItem->iSuid); |
1286 } |
1218 } |
1287 |
1219 } |
|
1220 DbColReadStreamL(temp, EObjectStoreSUID, suid); |
1288 DbColReadStreamL(temp, EObjectStoreSUID, suid); |
1221 |
1289 |
1222 item->iSuid = suid.AllocL(); |
1290 item->iSuid = suid.AllocL(); |
1223 |
1291 |
1224 item->iSuidPtr.Set(*item->iSuid); |
1292 item->iSuidPtr.Set(*item->iSuid); |
1225 result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1293 result = iEnumeratingCacheObjList.InsertInOrder(item, TLinearOrder<CEnumertingCacheItem>(CEnumertingCacheItem::Compare)); |
1226 } |
1294 } |
|
1295 |
1227 if(result != KErrAlreadyExists) |
1296 if(result != KErrAlreadyExists) |
1228 { |
1297 { |
1229 User::LeaveIfError(result); |
1298 User::LeaveIfError(result); |
1230 } |
1299 CleanupStack::Pop(item); |
1231 CleanupStack::Pop(item); |
1300 } |
1232 } |
1301 else |
1233 temp.NextL(); |
1302 { |
1234 } |
1303 CleanupStack::PopAndDestroy(item); |
1235 CleanupStack::PopAndDestroy(&temp); |
1304 } |
1236 iCacheExist = ETrue; |
1305 |
1237 } |
1306 } |
1238 |
1307 temp.NextL(); |
1239 void CMTPObjectStore::CleanDBSnapshotL() |
1308 } |
1240 { |
1309 |
1241 //For those items left in the iEnumeratingCacheObjList, remove the object entry if the DPID of the handle is not persistent. and populate the |
1310 CleanupStack::PopAndDestroy(&temp); |
1242 //roundtrip table if needed. |
1311 iCacheExist = ETrue; |
1243 //and then close the iEnumeratingCacheObjList to release the memory. |
1312 __FLOG_VA((_L8("EstablishDBSnapshotL - Exit build %d items"), iEnumeratingCacheObjList.Count())); |
1244 //_LIT(KInsert, "CMTPObjectStore::CleanDBSnapshot"); |
1313 } |
1245 //volatile TTimer t(KInsert); |
1314 /* |
1246 if(iCacheExist) |
1315 * All Objects enumeration complete |
1247 { |
1316 */ |
1248 iCacheExist = EFalse; |
1317 void CMTPObjectStore::ObjectsEnumComplete() |
1249 } |
1318 { |
1250 else |
1319 if(iCacheExist) |
1251 return; |
1320 { |
1252 |
1321 iCacheExist = EFalse; |
1253 for (TInt i = iEnumeratingCacheObjList.Count() - 1; i >= 0; i--) |
1322 } |
1254 { |
1323 iNonPersistentDPList.Close(); |
1255 TInt rc = iNonPersistentDPList.FindInOrder(iEnumeratingCacheObjList[i]->iDpID); |
1324 iEnumeratingCacheObjList.ResetAndDestroy(); |
1256 if (rc != KErrNotFound) |
1325 iUpdateDeltaDataTable = ETrue; |
1257 {//This is a non persistent DP. |
1326 iMaxCommitLimit = KMaxLimitCommitAfterEnumeration; |
1258 RemoveObjectL(iEnumeratingCacheObjList[i]->iObjHandleId); |
1327 iMaxCompactLimit = KMaxLimitCompactAfterEnumeration; |
1259 } |
|
1260 } |
|
1261 iNonPersistentDPList.Close(); |
|
1262 iEnumeratingCacheObjList.ResetAndDestroy(); |
|
1263 iUpdateDeltaDataTable = ETrue; |
|
1264 iMaxCommitLimit = KMaxLimitCommitAfterEnumeration; |
|
1265 iMaxCompactLimit = KMaxLimitCompactAfterEnumeration; |
|
1266 CommitTransactionL(); |
1328 CommitTransactionL(); |
1267 User::LeaveIfError(iDatabase.Compact()); |
1329 User::LeaveIfError(iDatabase.Compact()); |
1268 BeginTransactionL(); |
1330 BeginTransactionL(); |
1269 } |
1331 } |
1270 |
1332 |
1271 CMTPObjectStore::CEnumertingCacheItem::CEnumertingCacheItem(TUint32 aSuidHash, TUint32 aHandle, TUint32 aFormat, TUint64 aId, TUint8 aDpID) |
1333 |
|
1334 void CMTPObjectStore::CleanDBSnapshotL(TBool aOnlyRoot/* = EFalse*/) |
|
1335 { |
|
1336 //For those items left in the iEnumeratingCacheObjList, remove the object entry if the DPID of the handle is not persistent. and populate the |
|
1337 //roundtrip table if needed. |
|
1338 //and then close the iEnumeratingCacheObjList to release the memory. |
|
1339 //_LIT(KInsert, "CMTPObjectStore::CleanDBSnapshot"); |
|
1340 //volatile TTimer t(KInsert); |
|
1341 __FLOG(_L8("CleanDBSnapshotL Entry")); |
|
1342 if (iSnapshotWorker == NULL) |
|
1343 { |
|
1344 iSnapshotCleanPos = iEnumeratingCacheObjList.Count() - 1; |
|
1345 iSnapshotWorker = CSnapshotWorker::NewL(this, aOnlyRoot); |
|
1346 } |
|
1347 |
|
1348 //for (TInt i = iEnumeratingCacheObjList.Count() - 1; i >= 0; i--) |
|
1349 for (TInt i = 0; iSnapshotCleanPos >= 0 && i <= KSnapshotGranularity; --iSnapshotCleanPos, ++i) |
|
1350 { |
|
1351 if((aOnlyRoot && iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjParentId == KMTPHandleNoParent) //only root |
|
1352 ||(!aOnlyRoot)) //everything |
|
1353 { |
|
1354 TInt rc = iNonPersistentDPList.FindInOrder(iEnumeratingCacheObjList[iSnapshotCleanPos]->iDpID); |
|
1355 if (rc != KErrNotFound) |
|
1356 {//This is a non persistent DP. |
|
1357 __FLOG_VA((_L8("Remove Object 0x%x"), iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjHandleId)); |
|
1358 RemoveObjectL(iEnumeratingCacheObjList[iSnapshotCleanPos]->iObjHandleId); |
|
1359 } |
|
1360 } |
|
1361 } |
|
1362 |
|
1363 if (iSnapshotCleanPos >= 0) |
|
1364 { |
|
1365 iSnapshotWorker->ActiveSelf(); |
|
1366 } |
|
1367 else |
|
1368 { |
|
1369 //TRequestStatus *status = &aStatus; |
|
1370 //User::RequestComplete(status, KErrNone); |
|
1371 iSingletons.DpController().Schedule(); |
|
1372 iSnapshotCleanPos = 0; |
|
1373 delete iSnapshotWorker; |
|
1374 iSnapshotWorker = NULL; |
|
1375 } |
|
1376 |
|
1377 __FLOG(_L8("CleanDBSnapshotL Exit")); |
|
1378 } |
|
1379 |
|
1380 CMTPObjectStore::CEnumertingCacheItem::CEnumertingCacheItem(TUint32 aSuidHash, TUint32 aHandle, TUint32 aParent, TUint32 aFormat, TUint64 aId, TUint8 aDpID) |
1272 { |
1381 { |
1273 iObjSuiIdHash = aSuidHash; |
1382 iObjSuiIdHash = aSuidHash; |
1274 iObjHandleId = aHandle; |
1383 iObjHandleId = aHandle; |
|
1384 iObjParentId = aParent; |
1275 iFormatcode = aFormat; |
1385 iFormatcode = aFormat; |
1276 iPOUID = aId; |
1386 iPOUID = aId; |
1277 iDpID = aDpID; |
1387 iDpID = aDpID; |
1278 } |
1388 } |
1279 |
1389 |