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
Fix the bugs in SetSegmentation, both the original and new #26
Conversation
Maybe these functions should be templated on the second, numeric variable.
The original (written by me) had two bugs. One would make the code segfault if a partition number in inTriParts was negative; it was probably never triggered. The main bug would cause all triangle segment assignments to be lost if there was an empty partition at the end of the list. Two commits were added to this code over the past two years to try to fix the empty-partition-at-end bug and additional bugs introduced in those commits: 5fd784d and bb1f7a6. Neither fixed the original bug, and each had problems: the resulting code would tend to reassign triangles in some circumstances. So I reverted both of those commits and fixed the original bug. The mistakes in the two bug-fix commits suggest that the original code was unclear. I've tried to make it more clear by adding comments and renaming variables.
I think so. There doesn't seem to be much to test in those test cases. Here's what I did just now:
Also, in my earlier testing, I did lots of random changes, saved them, and reloaded them. I believe I understand this code thoroughly. I believe I know exactly why it misbehaved with empty segments at the end of the list in the original version, and why it would sometimes reassign partitions in the newer versions. However, additional code review and discussion seems like it could be valuable, given the problems with this function in the past. Do you want me to try to explain exactly what was wrong with the original code and why it did what it did? And why the two commits that tried to fix it didn't completely fix it? |
@sts1skj Thanks for the tests. Yes, a short and concise explanation of what the new partTriInds loop does correctly and the original code or fixes for it did not would be appreciated before I merge. No need to go too much into detail though. |
Here's the buggy code that I wrote originally (updated with new variable names and types):
Suppose we have 3 partitions with 100, 200, and 300 triangles. Then the input to this code is:
After the code, partTriInds will look like this:
This says, concisely: partition 0 starts at triangle index 0 and has 100 triangles; partition 1 starts at triangle index 100 and has 200 triangles; and partition 2 starts at triangle index 300 and has 300 triangles. Now suppose, instead of 3 partitions, we have 6: the first three have the same sizes as before; the last three are empty. triParts[triInds[i]] will look exactly the same for all i. What we want this code to produce is:
But what it actually produces is this:
This is bad. The number of triangles in partition 2 is -300, partition 5 has all 600 triangles, and partition 5 overlaps with partitions 0 and 1. The problem in the original code is the last line:
It only sets partTriInds[6] to 600; it should have set partTriInds[3..6] to 600. It should have been:
In commit eae5755, this code was inserted before the buggy last line:
For our 6-partition example, this will produce:
This is not right. The last 300 triangles are now in partition 5 instead of partition 2. Then commit bb1f7a6 wiped out the previous commit and changed it to (still before the buggy last line):
For our 6-partition example, this will produce:
That's correct. To spot the problem, we need to consider a different example. Suppose we have two partitions of sizes 50 and 0. Then we want partTriInds to look like this:
But the code produces this:
(The first loop calculates lastFilledPart to be 0. The second loop then does nothing. The final, original line sets the last value to 50.) |
The original (written by me) had two bugs. One would make the code segfault if a partition number in inTriParts was negative; it was probably never triggered. The main bug would cause all triangle segment assignments to be lost if there was an empty partition at the end of the list.
Two commits were added to this code over the past two years to try to fix the empty-partition-at-end bug and additional bugs introduced in those commits: eae5755 and bb1f7a6. Neither fixed the original bug, and each had problems: the resulting code would tend to reassign triangles in some circumstances. So I reverted both of those commits and fixed the original bug.
The mistakes in the two bug-fix commits suggest that the original code was unclear. I've tried to make it more clear by adding comments, renaming variables, and deleting blank lines that made closely related code seem unrelated.