-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize resolveGroupShare #27434
Optimize resolveGroupShare #27434
Conversation
@DeepDiver1975 @SergioBertolinSG @PVince81 Do we have integration for this scenario of moving group share to other folder, group share folder, fed share whatever? Unit test cover the changes already. |
* Resolve a group share to a user specific share | ||
* Thus if the user moved their group share make sure this is properly reflected here. | ||
* Resolve a group shares to a user specific share. | ||
* Returns in the array both the updated share if one was found and for not found in DB passing predicate, the original shares. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind clarifying what you mean with "updated share" and "original share" ?
Do you mean that "original share" is the actual group share and "updated share" is the user-specific special entry ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ok, I should say resolved :>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an the line is too long - 80 chars please
@mrow4a There are quite a few int. tests about sharing, perhaps the test you are looking for is this one https://github.com/owncloud/core/blob/master/tests/integration/features/sharing-v1.feature#L522 . If you miss some specific case, please tell me / open a ticket in QA repo. |
* Resolve a group share to a user specific share | ||
* Thus if the user moved their group share make sure this is properly reflected here. | ||
* Resolve a group shares to a user specific share. | ||
* Returns in the array both the updated share if one was found and for not found in DB passing predicate, the original shares. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an the line is too long - 80 chars please
$qb = $this->dbConn->getQueryBuilder(); | ||
|
||
$stmt = $qb->select('*') | ||
$shareParentIds = array_keys($parentIdToShareMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chunk to 1000 max?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point
bb6291e
to
63b95a4
Compare
->setMaxResults(1) | ||
->execute(); | ||
$shareParentIds = []; | ||
$parentIdToShareMap = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to shareIdToShareMap
or simply sharesMap
? Because it seems that's what it is.
It can of course be used to resolve parents but that's only one possibility
The "parent" bit confused me.
)) | ||
->setMaxResults(1) | ||
->execute(); | ||
$shareParentIds = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have trouble understanding the chunking part, it seems this array stores chunks so call it something with "chunk" in its name. See comment below to possibly avoid saying "parent".
} else { | ||
$shareNo++; | ||
} | ||
$shareParentIds[$chunkId][] = $parentId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the chunking part with code comments ?
It seems it's basically just building a chunked array of share ids ?
The "parent" part in the name makes it more confusing, I suggest removing it.
$parentId
is just $shareId
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, it just optimised for this case array_chunk, avoiding unnecessary loops.
@mrow4a code looks good. Took me a while due to the variable names confusing me. |
63b95a4
to
1b4520c
Compare
$shareIdToShareMap = []; | ||
$chunkId = 0; | ||
$shareNo = 0; | ||
foreach($shares as $share) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to another function so we can unittest it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TO unit tests it is to have >100 shares
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part of code involves chunking the shares list, which isn't related to the DB access that the rest of the function perform. That another reason to extract this piece out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea what you want to achieve here, I need to contruct $shareIdToShareMap and $chunkedShareIds, and this is what the loop is doing. I need that to avoid unnecesairly loops over shares
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to contruct $shareIdToShareMap and $chunkedShareIds
My point is that another private function could take care of the chunking in order to make this function to focus on fetching the data from the DB. It's fine if this function calls the "chunking function" and then fetch the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function would need to return 2 arrays...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will try it and see how it looks like. I get your point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jvillafanez Addressed this in the commit, wrote function chunkSharesToMaps()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
return $share; | ||
$resolvedShares = array_values($shareIdToShareMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the array_values
needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm good question, how array merge will handle it in upper layer. This is basicaly converting from map to classical array, which is used in upper layer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$shareId = $data['parent'];
I guess this won't be unqiue, will it? But if it won't be unique, the check above (if (isset($shareIdToShareMap[$shareId]))
) could be problematic.... I need some light there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but there could be several entries with the same parent.... that's what worries me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am discussing this with @cdamken lets see what comes out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok we tried things and seems impossible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If consider the parent will be unique, I think it's better to make the consideration all the way through, so if the assumption is wrong 💥 and 🚑 , otherwise it will be a pain to debug what's going on.
So, the key of the $shareIdToShareMap
map will be unique and the array_merge
(without the array_values
) shouldn't be a problem. The only question is if those keys are used in any other place, if not we could ignore the array_values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need array_values... the other array in upper layer is not a map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, fair enough. Maybe something to check in the future. Anyway 👍
// If we pass to resolveGroupShares map with one element, we expect to receive exactly one element, otherwise it is error | ||
$share = $resolvedShares[0]; | ||
} else { | ||
throw new \Exception("ResolveGroupShares() returned wrong result"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any other better exception that we could throw here? I'm not fan of throwing plain exceptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already throw this exception in this class, and this error is basicaly WTF error which should not happen -> if developer later touches this and breaks, he will know immedietaly :> Other alternative is just to throw IndexError as default, but it will probably confuse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will use @throws ProviderException
$share = $this->resolveGroupShare($share, $recipientId); | ||
$resolvedShares = $this->resolveGroupShares([$share], $recipientId); | ||
if (count($resolvedShares) === 1){ | ||
// If we pass to resolveGroupShares map with one element, we expect to receive exactly one element, otherwise it is error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
80 chars 😉
3297113
to
a14d271
Compare
if (!isset($shareParents[$shareParent])) { | ||
$shareParents[] = $shareParent; | ||
}else { | ||
throw new ProviderException('Parent of share should be unique'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jvillafanez I think this should be what you wanted to achieve
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
a14d271
to
d195262
Compare
// Ensure uniquenes of parents | ||
if (!isset($shareParents[$shareParent])) { | ||
$shareParents[] = $shareParent; | ||
}else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sneak a whitespace here?
The code is fine for me, just #27434 (review) , but unless there is any other change I don't think it's worthy. |
d195262
to
c64f0e4
Compare
I think I addressed the reviewed code @DeepDiver1975 any ideas? |
👍 from me as well, code is way more readable now. |
Not sure if we should backport this, it's a huge change and a bit risky. Needs proper retesting. Thoughts ? |
Long story short: The patch was sent to the customer because it looks like the fixes the issue. I'm not sure if cherry pick will work, but anyhow the solution works for master and 9.1.4 too. |
Agreed to not backport due to the risk. Advise to update to 10 or can provide this patch to other customers on 9.1.4 if they really want - with the risk that comes with it. |
Ok, I asked to upgrade to 10. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This optimizes the case in which you do PROPFIND to some folder, in which you had group share, and that share was moved to another folder (generaly people reorganise stuff from root folder to their required folders)
Below is what happens when you move file
testgrshare.txt
which has some group shares receiver/send to another folder and then propfind the "old" root folder: