Replace O(n) window list scan with O(1) open-addressing hash table - #50
Open
jEsuSdA wants to merge 1 commit into
Open
Replace O(n) window list scan with O(1) open-addressing hash table#50jEsuSdA wants to merge 1 commit into
jEsuSdA wants to merge 1 commit into
Conversation
Currently, find_win() scans the entire window list linearly to locate a window by ID. For each frame, paint_all() calls find_win() for every event window lookup, and on a typical desktop with 10-50 windows this adds up to hundreds of O(n) scans per second. As the window count grows, this becomes a significant bottleneck. Replace the linear scan with an open-addressing hash table (power-of-2 size, linear probing, tombstones for deletion, automatic rehash at 75% load or when tombstones exceed live entries). Changes: - find_win() now uses hash table lookup (O(1) amortized) - find_win_any_state() added for lookups that include destroyed windows - add_win() inserts into the hash table (with anti-duplicate guard via find_win_any_state to prevent duplicate win* for the same Window ID) - finish_destroy_win() removes from the hash table and now accepts win* directly instead of Window ID, fixing the zombie window leak where find_win() filters out destroyed entries and finish_destroy_win() could never find them again - The hash table handles OOM gracefully (resize failure does not abort, but guards against infinite loops with a probe limit) This is the single biggest performance improvement for long-running sessions with many windows.
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.
Summary
Replaces the O(n) linear window list scan with an O(1) open-addressing hash table, providing the single biggest performance improvement for long-running sessions with many windows.
Problem
find_win()scans the entire window list linearly to locate a window by ID. For each frame,paint_all()callsfind_win()for every event window lookup. On a typical desktop with 10–50 windows, this adds up to hundreds of O(n) scans per second. As the window count grows (e.g. after hours of browsing with many tabs), this becomes a significant bottleneck.Solution
Open-addressing hash table
Changes
find_win()→win_hash_lookup()(O(1) amortized, filters outdestroyedentries)find_win_any_state()— new, for lookups that include destroyed windows (needed forfinish_destroy_winand anti-duplicate guard)add_win()— inserts into the hash table + anti-duplicate guard viafind_win_any_state()(prevents duplicatewin*for the same Window ID, which caused use-after-free crashes)finish_destroy_win()— removes from the hash table and now acceptswin*directly instead ofWindowID. This fixes the zombie window leak wherefind_win()filtered out destroyed entries andfinish_destroy_win()could never find them againFiles changed
cm-window.c— hash table implementationcm-window.h— declarations forfind_win_any_state(),win_hash_insert(),win_hash_remove()fastcompmgr.c— updatedadd_win(),finish_destroy_win(),destroy_win(),destroy_callback()Scope
make clean && makeproduces zero warnings, zero errorsImpact
Single biggest performance improvement for long-running sessions. On a desktop with 50 windows,
find_win()goes from ~25 pointer comparisons per call to ~1–2 probes. The effect compounds across hundreds of calls per frame.