[fpc-devel] Who maintains TDictionary? // Re: RFC: Improvements for TDictionary and other hash containers
Martin Frb
lazarus at mfriebe.de
Sun Apr 13 20:31:08 CEST 2025
On 13/04/2025 19:49, Michael Van Canneyt wrote:
>
>
> On Sun, 13 Apr 2025, Martin Frb via fpc-devel wrote:
>
>> Just want to know if there is any interest? Or if I just gonna do
>> my own copy (somewhere in LazUtils)
>
> The 1-4 are interesting so MR is welcome,
ok, I will work on that.
> the 5 I don't understand what you want to
> achieve, I would assume a custom comparer is simply the answer ?
The custom comparer (and hasher) I already have. But its not enough.
The concrete use case is the SynEdit Highlighter.
For each text-line it assembles an object that represents the state of
the parser after the line (for the next line to start with).
This contains Flags on the parser state, fold info, and similar.
Each line has a pointer to its state.
Additionally all states end up in a pool (in this case a TDictionary).
The pool is used for de-duplication.
If an object for the state already exists then the existing object is
used (and the object that was created during working on the line is
discarded).
With the current TDictionary I have (TRange is the object for the line
state)
specialize TDictionary <TRange, TRange>
So I can then look up a range (the dictionary uses the content of the
object, the internal pointer is not part of the comparison).
But it stores the object by storing the internal pointer to it (it does
not copy the instance memory)
The same object (same instance) is key and data at the same time.
But, when I have the the current lines new range object, then I do
MyDict.TryGetValue(TempRange, WantedExistingRange) .
That all works very well, but for each range the dictionary stores 2
copies of the pointer to that object (twice the same pointer).
- One as key (even though the actual key is the data pointed too)
- One as Data (pointing to the same data).
Instead I like to do
type
TMyEmpty = record end; // empty
specialize TDictionary <TRange, TMyEmpty>
Then only the key is stored.
But then I need a way to retrieve the existing key, for a new key that I
have.
That sounds stupid, but remember that the key is passed as the internal
pointer to the object.
So 2 different pointers can point to 2 mem-locations with data that is
equal (and is the same key).
I want the "key" pointer to the original memory, with the same content
as pointed to my new key.
I admit its a very special case for a dictionary, but probably still useful.
It is done with lists all the time, that data is added "if indexof(data)
< 0" and otherwise existing data is used.
If its not added to the public interface, then maybe some protected
accessor can be created, based on which a subclass can implement it?
More information about the fpc-devel
mailing list