O07: two arrays and a hash - #137
Merged
Merged
Conversation
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.
O07, the seventh lesson of the object model part. Six lessons have said "look in the instance dict" or "walk the class dicts" and moved straight on. This one opens the dict.
The frame is that a dict is two arrays, not one. A small array of slot numbers with all the holes in it, and a plain append only array of entries with none. Insertion order, the cost of deleting, the resize points and the size difference between a string keyed dict and an int keyed one all fall out of that split.
The centrepiece is a compact dict written out in Python, about sixty lines, including the real probe recurrence and the real resize rule. It grows at 6, 11, 22, 43, 86 and 171 keys, which is exactly where the real one grows, and it iterates identically over two hundred keys and after deletes.
What it covers:
dk_indicesanddk_entries, the four slot states, and the one byte per slot a small dict spends-1that ends a failed lookup after a single readi = mask & (i * 5 + perturb + 1), why it is not linear probing, and the0, 1, 6, 7, 4, 5, 2, 3order it produces for a size 8 tableUSABLE_FRACTIONandGROWTH_RATE, and why the growth factor is three rather than twoDKIX_DUMMY, why a deleted slot cannot go back to-1, and a churn loop that makes a five key dict grow twicepopitemas the one delete that gives the space backestimate_log2_keysize, the reverse ofUSABLE_FRACTION, and whatdict.fromkeysdoes with itSixteen citations, all resolving against the pin. Six diagrams, all under 940 px. Two new glossary terms,
compact dictandprobe sequence, bringing GLOSSARY.md to 120.Three cells carry a
varies=note, because they print byte counts and a browser build has 4 byte pointers. Everything else is identical on 3.14, on 3.15.0rc1 and on Pyodide 3.14.2.Checked with the full
just checkand withjust versions.