-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Configuration entry iteration in order #4525
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
Conversation
Small note: I highly recommend reviewing the commits one by one. There's a lot of renaming going on step by step, which becomes a whole lot easier to do if not reviewing the complete diff at once. |
Are you hoping that we land this for the immediate next release? Seems like a Big Change and my preference would be to land it after we cut the next release, but I want to make sure we're both on the same page. |
We are on the same page ;) |
2203647
to
2ddeafa
Compare
Rebased to fix merge conflicts with #4552 |
We currently provide a lot of macros for the `cvar_t` structure which are never being used. In fact, the only macro we need is to access the `next` pointer of `cvar_t`, which really does not require a macro at all. Remove all these macros and replace usage of `CVAR_LIST_NEXT(cvar)` with `cvar->next`.
The code appending new configuration entries to our current list first allocates the `cvar` structure and then passes it to `append_entry`. As we want to extend `append_entry` to store configuration entries in a map as well as in a list for ordered iteration, we will have to create two `cvar` structures, though. As such, the future change will become much easier when allocation of the `cvar` structure is doen in `append_entry` itself.
In order to reject writes to included configuration entries, we need to keep track of whether an entry was included via another configuration file or not. This information is being stored in the `cvar` structure, which is a rather weird location, as it is only used to create a list structure of config entries. Move the include depth into the structure `git_config_entry` instead. While this fixes the layering issue, it enables users of libgit2 to access the depth, too.
The `cvar_t` structure is really awkward to grasp, because its name actively hinders discovery of what it actually is. As it is nothing more than a singly-linked list of configuration entries, name rename it to just that: `config_entry_list`.
The interface for freeing config list entries is more tangled than required. Instead of calling `cvar_free` for every list entry in `free_vars`, we now just provide a function `config_entry_list_free`. This function will iterate through all list entries and free the associated configuration entry as well as the list entry itself.
The struct `parse_data` sounds as if it was defined and passed to us from the configuration parser, which is not true. Instead, `parse_data` is specific to the diskfile backend parsing logic. Rename it to `diskfile_parse_state` to make that clearer. This also follows existing naming patterns with the "diskfile" prefix.
The config file parsing code all revolves around the `refcounted_strmap` structure, which is a map of entry names to their respective keys. This naming scheme made grasping the code quite hard, warranting a rename. A good alternative is `diskfile_entries`, making clear that this really only holds all configuration entries. Furthermore, we are about to introduce a new linked list of configuration entries into the configuration file code. This list will be used to iterate over configuration entries in the order they are listed inside of the parsed configuration file. After renaming `refcounted_strmap` to `diskfile_entries`, this struct also becomes the natural target where to add that new list. Like this, data structures holding all entries are neatly contained inside of it.
Currently, we only parse the entry map into `append_entry` to append new configuration entries to it. Instead, though, we can just pass the complete `diskfile_entries` structure into it. This allows us to easily extend `diskfile_entries` by another singly linked list of configuration entries.
Right now, we only keep all configuration entries in a string map. This is required to efficiently access configuration entries by keys. It has the disadvantage of not being able to iterate through configuration entries in the order they were read, though. Instead, we only iterate through entries in a seemingly random order. Extend `diskfile_entries` by another list holding configuration entries. Like this, we maintain all entries in two data structures and can use the required one based on the current use case.
Currently, all configuration entries were only held in a string map, making iteration order mostly based on the hash of each entry's key. Now that we have extended the `diskfile_entries` structure by a list of config entries, we can effectively iterate through entries in the order they were added, though.
2ddeafa
to
6a15f65
Compare
This was a good hint. Reviewing each commit was helpful in seeing the progression. Thanks for tackling this; there's some nice cleanup in here and improved functionality. 👍 |
I've finally pulled myself together and tackled my itch of iterating through configuration entries in the order they appear in the file. At first, I started getting annoyed again by the unnecessarily complex config file code, so I preceded the actual logic by quite a lot of refactoring and renaming of structures and functions. The result is actually very pleasant: while maintaining a second data structure alongside the map of entries, this PR still has more deletions than additions. So I definitly think that this PR helps a whole lot regarding readability.