Skip to content

Commit da53a13

Browse files
committed
Merge branch 'fix/SDK-4239_Low-performance-on-Recents-excluding-sensitive-nodes' into 'release/v7.8.0'
SDK-4239. Low performance on Recents excluding sensitive nodes (release/v7.8.0) See merge request sdk/sdk!5761
2 parents bf06f9f + ff221a2 commit da53a13

14 files changed

+248
-63
lines changed

include/mega/db.h

+3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ class MEGA_API DBTableNodes
148148
std::set<std::string>& tags,
149149
CancelToken cancelFlag) = 0;
150150

151+
virtual bool getRecentNodes(unsigned maxcount,
152+
m_time_t since,
153+
std::vector<std::pair<NodeHandle, NodeSerialized>>& nodes) = 0;
151154
virtual bool getNodesByFingerprint(const std::string& fingerprint, std::vector<std::pair<NodeHandle, NodeSerialized>>& nodes) = 0;
152155
virtual bool getNodeByFingerprint(const std::string& fingerprint, mega::NodeSerialized& node, NodeHandle& handle) = 0;
153156
virtual bool getRootNodes(std::vector<std::pair<NodeHandle, NodeSerialized>>& nodes) = 0;

include/mega/db/sqlite.h

+6
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class MEGA_API SqliteAccountState : public SqliteDbTable, public DBTableNodes
9090
bool getNodeByFingerprint(const std::string& fingerprint,
9191
mega::NodeSerialized& node,
9292
NodeHandle& handle) override;
93+
// getRecentNodes() is for the deprecated method MegaClient::getRecentActions without
94+
// excludeSensitives flag
95+
bool getRecentNodes(unsigned maxcount,
96+
m_time_t since,
97+
std::vector<std::pair<NodeHandle, NodeSerialized>>& nodes) override;
9398
bool getFavouritesHandles(NodeHandle node, uint32_t count, std::vector<mega::NodeHandle>& nodes) override;
9499
bool childNodeByNameType(NodeHandle parentHanlde, const std::string& name, nodetype_t nodeType, std::pair<NodeHandle, NodeSerialized>& node) override;
95100
bool getNodeSizeTypeAndFlags(NodeHandle node, m_off_t& size, nodetype_t& nodeType, uint64_t &oldFlags) override;
@@ -156,6 +161,7 @@ class MEGA_API SqliteAccountState : public SqliteDbTable, public DBTableNodes
156161
sqlite3_stmt* mStmtChildNode = nullptr;
157162
sqlite3_stmt* mStmtIsAncestor = nullptr;
158163
sqlite3_stmt* mStmtNumChild = nullptr;
164+
sqlite3_stmt* mStmtRecents = nullptr; // For getRecentNodes()
159165
sqlite3_stmt* mStmtFavourites = nullptr;
160166

161167
// how many SQLite instructions will be executed between callbacks to the progress handler

include/mega/megaclient.h

+8
Original file line numberDiff line numberDiff line change
@@ -1911,7 +1911,15 @@ class MEGA_API MegaClient
19111911
std::shared_ptr<Node> nodebyfingerprint(LocalNode*);
19121912
#endif /* ENABLE_SYNC */
19131913

1914+
private:
1915+
// Private helper method for getRecentActions
1916+
recentactions_vector getRecentActionsFromSharedNodeVector(sharedNode_vector&& v);
1917+
public:
19141918
// get a vector of recent actions in the account
1919+
recentactions_vector getRecentActions(unsigned maxcount,
1920+
m_time_t since); // Old getRecentActions behavior without
1921+
// newer excludeSensitive functionality
1922+
19151923
recentactions_vector getRecentActions(unsigned maxcount,
19161924
m_time_t since,
19171925
bool excludeSensitives);

include/mega/nodemanager.h

+7
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ class MEGA_API NodeManager
173173

174174
sharedNode_vector getChildren(const NodeSearchFilter& filter, int order, CancelToken cancelFlag, const NodeSearchPage& page);
175175

176+
// get up to "maxcount" nodes, not older than "since", ordered by creation time
177+
// Note: nodes are read from DB and loaded in memory
178+
// (This is used by deprecated MegaClient::getRecentNodes without exclude sensitive filter)
179+
sharedNode_vector getRecentNodes(unsigned maxcount, m_time_t since);
180+
176181
sharedNode_vector searchNodes(const NodeSearchFilter& filter, int order, CancelToken cancelFlag, const NodeSearchPage& page);
177182

178183
std::set<std::string> getAllNodeTags(const char* searchString, CancelToken cancelFlag);
@@ -403,6 +408,8 @@ class MEGA_API NodeManager
403408
sharedNode_vector searchNodes_internal(const NodeSearchFilter& filter, int order, CancelToken cancelFlag, const NodeSearchPage& page);
404409
sharedNode_vector processUnserializedNodes(const std::vector<std::pair<NodeHandle, NodeSerialized>>& nodesFromTable, CancelToken cancelFlag);
405410
sharedNode_vector getChildren_internal(const NodeSearchFilter& filter, int order, CancelToken cancelFlag, const NodeSearchPage& page);
411+
sharedNode_vector getRecentNodes_internal(unsigned maxcount,
412+
m_time_t since); // Old getRecentNodes functionality
406413

407414
std::set<std::string> getAllNodeTags_internal(const char* searchString, CancelToken cancelFlag);
408415

include/megaapi.h

+40-31
Original file line numberDiff line numberDiff line change
@@ -4098,17 +4098,17 @@ class MegaUserAlertList
40984098
virtual void clear();
40994099
};
41004100

4101-
41024101
/**
4103-
* @brief Represents a set of files uploaded or updated in MEGA.
4104-
* These are used to display the recent changes to an account.
4105-
*
4106-
* Objects of this class aren't live, they are snapshots of the state
4107-
* in MEGA when the object is created, they are immutable.
4108-
*
4109-
* MegaRecentActionBuckets can be retrieved with MegaApi::getRecentActions
4110-
*
4111-
*/
4102+
* @brief Represents a set of files uploaded or updated in MEGA.
4103+
* These are used to display the recent changes to an account.
4104+
*
4105+
* Objects of this class aren't live, they are snapshots of the state
4106+
* in MEGA when the object is created, they are immutable.
4107+
*
4108+
* MegaRecentActionBuckets can be retrieved with MegaApi::getRecentActions
4109+
* and MegaApi::getRecentActionsAsync.
4110+
*
4111+
*/
41124112
class MegaRecentActionBucket
41134113
{
41144114
public:
@@ -4178,17 +4178,19 @@ class MegaRecentActionBucket
41784178
};
41794179

41804180
/**
4181-
* @brief List of MegaRecentActionBucket objects
4182-
*
4183-
* A MegaRecentActionBucketList has the ownership of the MegaRecentActionBucket objects that it contains, so they will be
4184-
* only valid until the MegaRecentActionBucketList is deleted. If you want to retain a MegaRecentActionBucket returned by
4185-
* a MegaRecentActionBucketList, use MegaRecentActionBucket::copy.
4186-
*
4187-
* Objects of this class are immutable.
4188-
*
4189-
* @see MegaApi::getRecentActions
4190-
*
4191-
*/
4181+
* @brief List of MegaRecentActionBucket objects
4182+
*
4183+
* A MegaRecentActionBucketList has the ownership of the MegaRecentActionBucket objects that it
4184+
* contains, so they will be only valid until the MegaRecentActionBucketList is deleted. If you want
4185+
* to retain a MegaRecentActionBucket returned by a MegaRecentActionBucketList, use
4186+
* MegaRecentActionBucket::copy.
4187+
*
4188+
* Objects of this class are immutable.
4189+
*
4190+
* @see MegaApi::getRecentActions
4191+
* @see MegaApi::getRecentActionsAsync
4192+
*
4193+
*/
41924194
class MegaRecentActionBucketList
41934195
{
41944196
public:
@@ -4974,6 +4976,8 @@ class MegaRequest
49744976
* - MegaApi::dismissBanner - Returns the id of the banner
49754977
* - MegaApi::sendBackupHeartbeat - Returns the number of backup files uploaded
49764978
* - MegaApi::getRecentActions - Returns the maximum number of nodes
4979+
* - MegaApi::getRecentActionsAsync - Returns the maximum number of nodes
4980+
* - MegaApi::importPasswordsFromFile - Returns source of the file provided as an argument
49774981
*
49784982
* @return Type of parameter related to the request
49794983
*/
@@ -5028,8 +5032,10 @@ class MegaRequest
50285032
* - MegaApi::moveTransferToLast - Returns MegaTransfer::MOVE_TYPE_BOTTOM
50295033
* - MegaApi::moveTransferToLastByTag - Returns MegaTransfer::MOVE_TYPE_BOTTOM
50305034
* - MegaApi::moveTransferBefore - Returns the tag of the transfer with the target position
5031-
* - MegaApi::moveTransferBeforeByTag - Returns the tag of the transfer with the target position
5032-
* - MegaApi::setScheduledCopy - Returns the period between backups in deciseconds (-1 if cron time used)
5035+
* - MegaApi::moveTransferBeforeByTag - Returns the tag of the transfer with the target
5036+
* position
5037+
* - MegaApi::setScheduledCopy - Returns the period between backups in deciseconds (-1 if
5038+
* cron time used)
50335039
* - MegaApi::abortCurrentScheduledCopy - Returns the tag of the aborted backup
50345040
* - MegaApi::removeScheduledCopy - Returns the tag of the deleted backup
50355041
* - MegaApi::startTimer - Returns the selected period
@@ -5046,6 +5052,8 @@ class MegaRequest
50465052
* - MegaApi::getPaymentMethods - Returns a bitfield with the available payment methods
50475053
* - MegaApi::getCloudStorageUsed - Returns the sum of the sizes of file cloud nodes.
50485054
* - MegaApi::getRecentActions - Returns the number of days since nodes will be considerated
5055+
* - MegaApi::getRecentActionsAsync - Returns the number of days since nodes will be
5056+
* considered
50495057
*
50505058
* @return Number related to this request
50515059
*/
@@ -5087,7 +5095,7 @@ class MegaRequest
50875095
* - MegaApi::getVisibleWelcomeDialog - Returns true if the Welcome dialog is visible
50885096
* - MegaApi::getVisibleTermsOfService - Returns true if the Terms of Service need to be
50895097
* displayed
5090-
* - MegaApi::getRecentActions - Returns true if exclude sensitives
5098+
* - MegaApi::getRecentActionsAsync - Returns true if exclude sensitives
50915099
*
50925100
* This value is valid for these request in onRequestFinish when the
50935101
* error code is MegaError::API_OK:
@@ -18538,8 +18546,8 @@ class MegaApi
1853818546
*
1853918547
* Each bucket contains files that were added/modified in a set, by a single user.
1854018548
*
18541-
* Note: Nodes sensitives are excluded by default. Nodes are considered
18542-
* sensitive if they have that property set, or one of their ancestors has it
18549+
* Note: Nodes sensitives are NOT excluded by default. Nodes are considered
18550+
* sensitive if they have that property set, or one of their ancestors has it.
1854318551
*
1854418552
* @deprecated use getRecentActionsAsync
1854518553
*
@@ -18561,8 +18569,8 @@ class MegaApi
1856118569
*
1856218570
* You take the ownership of the returned value.
1856318571
*
18564-
* Note: Nodes sensitives are excluded by default. Nodes are considered
18565-
* sensitive if they have that property set, or one of their ancestors has it
18572+
* Note: Nodes sensitives are NOT excluded by default. Nodes are considered
18573+
* sensitive if they have that property set, or one of their ancestors has it.
1856618574
*
1856718575
* @deprecated use getRecentActionsAsync
1856818576
*
@@ -18579,7 +18587,6 @@ class MegaApi
1857918587
* Valid data in the MegaRequest object received on callbacks:
1858018588
* - MegaRequest::getNumber - Returns the number of days since nodes will be considerated
1858118589
* - MegaRequest::getParamType - Returns the maximun number of nodes
18582-
* - MegaRequest::getFlag - Returns true if sensitives are excluded
1858318590
*
1858418591
* The associated request type with this request is MegaRequest::TYPE_GET_RECENT_ACTIONS
1858518592
* Valid data in the MegaRequest object received in onRequestFinish when the error code
@@ -18590,8 +18597,10 @@ class MegaApi
1859018597
* The recommended values for the following parameters are to consider
1859118598
* interactions during the last 30 days and maximum 500 nodes.
1859218599
*
18593-
* Note: Nodes sensitives are excluded by default. Nodes are considered
18594-
* sensitive if they have that property set, or one of their ancestors has it
18600+
* Note: Nodes sensitives are NOT excluded by default. Nodes are considered
18601+
* sensitive if they have that property set, or one of their ancestors has it.
18602+
* Use getRecentActionsAsync with explicit excludeSensitives flag
18603+
* to search for sensitives and filter them depending on the flag value
1859518604
*
1859618605
* @param days Age of actions since added/modified nodes will be considered (in days)
1859718606
* @param maxnodes Maximum amount of nodes to be considered

include/megaapi_impl.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -3592,9 +3592,16 @@ class MegaApiImpl : public MegaApp
35923592

35933593
long long getBandwidthOverquotaDelay();
35943594

3595-
MegaRecentActionBucketList* getRecentActions(unsigned days = 90,
3596-
unsigned maxnodes = 500,
3597-
bool excludeSensitives = true);
3595+
private:
3596+
void getRecentActionsAsyncInternal(unsigned days,
3597+
unsigned maxnodes,
3598+
bool* optExcludeSensitives,
3599+
MegaRequestListener* listener = NULL);
3600+
public:
3601+
MegaRecentActionBucketList* getRecentActions(unsigned days = 90, unsigned maxnodes = 500);
3602+
void getRecentActionsAsync(unsigned days,
3603+
unsigned maxnodes,
3604+
MegaRequestListener* listener = NULL);
35983605
void getRecentActionsAsync(unsigned days,
35993606
unsigned maxnodes,
36003607
bool excludeSensitives,

src/db/sqlite.cpp

+53
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,9 @@ void SqliteAccountState::finalise()
12001200
sqlite3_finalize(mStmtNumChild);
12011201
mStmtNumChild = nullptr;
12021202

1203+
sqlite3_finalize(mStmtRecents);
1204+
mStmtRecents = nullptr;
1205+
12031206
sqlite3_finalize(mStmtFavourites);
12041207
mStmtFavourites = nullptr;
12051208
}
@@ -1892,6 +1895,56 @@ bool SqliteAccountState::getNodeByFingerprint(const std::string &fingerprint, me
18921895
return result;
18931896
}
18941897

1898+
bool SqliteAccountState::getRecentNodes(unsigned maxcount,
1899+
m_time_t since,
1900+
std::vector<std::pair<NodeHandle, NodeSerialized>>& nodes)
1901+
{
1902+
if (!db)
1903+
{
1904+
return false;
1905+
}
1906+
1907+
const std::string filenode = std::to_string(FILENODE);
1908+
uint64_t excludeFlags = (1 << Node::FLAGS_IS_VERSION | 1 << Node::FLAGS_IS_IN_RUBBISH);
1909+
std::string sqlQuery = "SELECT n1.nodehandle, n1.counter, n1.node "
1910+
"FROM nodes n1 "
1911+
"WHERE n1.flags & " +
1912+
std::to_string(excludeFlags) +
1913+
" = 0 AND n1.ctime >= ? AND n1.type = " + filenode +
1914+
" "
1915+
"ORDER BY n1.ctime DESC LIMIT ?";
1916+
1917+
int sqlResult = SQLITE_OK;
1918+
if (!mStmtRecents)
1919+
{
1920+
sqlResult = sqlite3_prepare_v2(db, sqlQuery.c_str(), -1, &mStmtRecents, NULL);
1921+
}
1922+
1923+
bool stepResult = false;
1924+
if (sqlResult == SQLITE_OK)
1925+
{
1926+
if (sqlResult == sqlite3_bind_int64(mStmtRecents, 1, since))
1927+
{
1928+
// LIMIT expression evaluates to a negative value, then there is no upper bound on the
1929+
// number of rows returned
1930+
int64_t nodeCount = (maxcount > 0) ? static_cast<int64_t>(maxcount) : -1;
1931+
if (sqlResult == sqlite3_bind_int64(mStmtRecents, 2, nodeCount))
1932+
{
1933+
stepResult = processSqlQueryNodes(mStmtRecents, nodes);
1934+
}
1935+
}
1936+
}
1937+
1938+
if (sqlResult != SQLITE_OK)
1939+
{
1940+
errorHandler(sqlResult, "Get recent nodes", false);
1941+
}
1942+
1943+
sqlite3_reset(mStmtRecents);
1944+
1945+
return stepResult;
1946+
}
1947+
18951948
bool SqliteAccountState::getFavouritesHandles(NodeHandle node, uint32_t count, std::vector<mega::NodeHandle> &nodes)
18961949
{
18971950
if (!db)

src/megaapi.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4138,7 +4138,7 @@ MegaRecentActionBucketList* MegaApi::getRecentActions()
41384138

41394139
void MegaApi::getRecentActionsAsync(unsigned days, unsigned maxnodes, MegaRequestListener *listener)
41404140
{
4141-
pImpl->getRecentActionsAsync(days, maxnodes, true /*excludeSensitives*/, listener);
4141+
pImpl->getRecentActionsAsync(days, maxnodes, listener);
41424142
}
41434143

41444144
void MegaApi::getRecentActionsAsync(unsigned days,

0 commit comments

Comments
 (0)