Add bulk DeleteItems to TALDynamicListBox - #519
Open
Spelt wants to merge 2 commits into
Open
Conversation
Deleting a large range of items one by one via DeleteItemAtIndex is quadratic: every removal shifts the controls array, renumbers all trailing indexes and triggers a realign. Collapsing a 24k-item branch in a virtualized tree built on TALDynamicListBox took ~3 seconds. DeleteItems(AIndex, ACount) on TMainContent/TView/TALDynamicListBox is the bulk counterpart of the existing InsertItems: detach the doomed items in O(1) each (owner/host cleared, delayed destruction like DeleteItemAtIndex), then one array shift, one renumber, the same index bookkeeping as InsertItems (visible/preloaded/download-trigger), and a single Realign. Deleting a range becomes as fast as inserting one.
Collaborator
|
thanks @Spelt i will review it soon ! |
InsertItems: inserting inside the preloaded window used to extend the window across the inserted (never prepared) items; the next SetViewportPosition then called Unprepare once per inserted item (a 24k insert = 24k calls) and the window no longer matched which items were actually prepared. Clamp the window to the part before the insertion point and unprepare the shifted prepared tail instead. DeleteItems: when the deleted block overlaps the window, the prepared range can split into a head and a shifted tail; keep the head and unprepare the tail (or keep the shifted tail when there is no head). Previously rows below the collapse point could stay unprepared while visible. TItem.Unprepare: fast exit when there is nothing to cancel or free. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
|
Added a second commit that keeps the preloaded window consistent across bulk InsertItems/DeleteItems: inserting inside the window no longer marks the inserted (never prepared) items as prepared, deleting a block that overlaps the window keeps the prepared head and unprepares the shifted tail, and TItem.Unprepare exits early when there is nothing to cancel or free. Found while collapsing/expanding a 24k-item folder repeatedly |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Deleting a large range of items one by one via
DeleteItemAtIndexis quadratic: every removal shifts the controls array, renumbers all trailing indexes and triggers aRealign. In a virtualized directory tree built onTALDynamicListBox, collapsing a branch with 24,000 children took ~3 seconds, while expanding the same branch was instant thanks to the existing bulkInsertItems.Solution
DeleteItems(AIndex, ACount)onTView.TMainContent,TViewandTALDynamicListBox— the bulk counterpart ofInsertItems:FOwner/FIndex,SetHost(nil)(releases hovered/captured refs), thenALFreeAndNil(..., true{delayed})for the same reasonDeleteItemAtIndexuses delayed destructionALMoveover the controls array, one renumber passInsertItems(first/last visible, first/last preloaded, download trigger), shifted down instead of up, with indexes inside the removed block collapsing ontoAIndexRealign(AIndex)+RepaintDeleting a 24k range is now as fast as inserting it.
Tested on Delphi 13, Win64, with a file-explorer style tree: expand/collapse of 24k-item directories, selection, scrolling and re-expand behave correctly.