[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