-
Notifications
You must be signed in to change notification settings - Fork 50
EC expiration #3718
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
EC expiration #3718
Conversation
ba8a798 to
2b289c2
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3718 +/- ##
==========================================
+ Coverage 26.89% 26.93% +0.03%
==========================================
Files 658 658
Lines 41825 41879 +54
==========================================
+ Hits 11249 11279 +30
- Misses 29542 29559 +17
- Partials 1034 1041 +7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
2b289c2 to
67a0e24
Compare
| type DeleteRes struct { | ||
| // Objects that were hardly linked to objects passed to [DB.Delete] and that | ||
| // were deleted along with them. | ||
| AdditionalObjects map[oid.Address][]oid.ID |
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.
What bugs me is that we don't need maps here or below we're OK with sets of addresses with their size. So what we can do is just to have DeletedObjects []struct{addr oid.Address, size uint64} which would also cover for AvailableRemoved (not sure about RawRemoved). Then this result is easier to digest in Delete() caller, just a single pass on deleted things, not requiring any iter.Seq dances.
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 can be cases when input address list is not extended, and all its items are removed. In this case, returning shallow copy in res would be more efficient. At the same time, having []struct{addr oid.Address, size uint64} would require to make a copy anyway
then EC brings one more list of addresses (agree map is not required here, can be of []oid.Address type). So why should we concat EC list with the input one when we have iterators (or two loops if u wish)?
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.
With current code you allocate for Sizes anyway and it usually has all of the addresses from the input.
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.
do u mean
[]struct{addr oid.Address, size uint64}
to be allocated by the caller?
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.
No, it can be managed in metabase, it's a part of DeleteRes anyway.
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 same addrs passed by the caller are handled, isn't allocation of Sizes []uint64 only is lighter than []struct{addr oid.Address, size uint64} w/ copying addrs elements to 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.
It is. But you already have a map[oid.Address]uint64 there and that makes it a completely different story.
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 can keep it []uint64. But structing it with addresses makes no sense
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.
On its own it's not, but combined with AdditionalObjects it sure is. We want to allocate as little as possible both in terms of overall size and in terms of allocated objects (which adds both CPU and space overhead). A single slice is a single slice, it's easy for allocator to handle, a map is already more complex thing, a map of slices is even worse, it can require a lot of microallocations. If that would be required by the way we use this construction --- ok, no problem, but it's not.
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.
done
67a0e24 to
34e4125
Compare
79de47e to
f3254df
Compare
f3254df to
163cc35
Compare
| err = db.boltDB.Update(func(tx *bbolt.Tx) error { | ||
| // We need to clear slice because tx can try to execute multiple times. | ||
| rawRemoved, availableRemoved, err = db.deleteGroup(tx, addrs, sizes) | ||
| rawRemoved, availableRemoved, removed, err = db.deleteGroup(tx, addrs) |
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.
too many vars with confusing names to me. add suffixes like "count", "objects", etc?
| } | ||
|
|
||
| if ecPref == nil { | ||
| ecPref = slices.Concat([]byte{metaPrefixIDAttr}, partID, []byte(iec.AttributePrefix)) // any of EC attributes |
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, please, recall me, if it is possible to PUT some object with this attribute, mentioning some different object as a parent? will it be accidentally dropped too with this code?
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.
Each EC part has parent header inside, so consistency can be checked.
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 meant if it is possible to misuse this code with our regular splits custom objects that have conflicting attributes
roman-khimov
left a comment
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'll squash the first two commits.
Expiration mechanism was incompatible with EC. When a root object expires, either it or its size-split parts are submitted for deletion. Therefore, EC parts were not included. At the same time, it is important to remove physical objects within GC procedure. This corrects the behavior with minimal intrusion into original logic. Specifically, metabase `Delete()` method now automatically picks up EC parts, deletes and returns them for removal from write-cache and BLOB storage. Fixes #3712. Refs #3502, #3500, #526. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
163cc35 to
18a0c51
Compare
@evgeniiz321 try pls