One of the many places that we currently use in our program is records.
Many of these records are stored in the AVL tree. < p>
The AVL tree used is universal, it contains a pointer to multiple bytes (ElemSize), and these pointers have worked well so far.
Memory of each record in the AVL tree Use GetMem to allocate, and use Move to copy.
However, if the string is a pointer to a reference counted structure, copying the memory back to the record is no longer valid, because the referenced sting is often released (automatically by reference counting).
With only a pointer and the size of the “data block”, I think it is impossible to increase the reference count of the string.
I am looking for a way to get the bite to consider when storing records in the AVL tree Reference counting.
Can I pass the record type to the tree constructor, and then cast the pointer to this type to increase the reference? Or a similar fix, I can isolate the changes mainly in the AVL unit and call its constructor.
Current code used to allocate space for storing AVL records; XData points to the record to be stored Pointer:
New(RootPtr); {create new memory space }
GetMem(RootPtr^.TreeData, ElemSize);
WITH RootPtr^ DO BEGIN
{copy data }
Move(XData^, RootPtr^.TreeData^, ElemSize);
How can I allocate, copy and deallocate a record when all I know about its type is its size?
The simple answer is that if the record does not contain a managed type, you can use GetMem, Move and FreeMem. You want to use a record that contains a Delphi string , These strings are managed. Therefore, the current methods of using GetMem and Move are not enough.
There are many ways to solve this problem. You can write your own code to do reference counting, as long as you Just know where the hosting type is in the record. I don’t recommend this. You can set your user data as a class and use polymorphism to help.
The options I want to discuss continue to support Record, and indeed allow users to choose any type they like. The reasons are as follows:
If the type contains managed types, you need to understand the type to operate on it. If the tree is generic, then it does not have this Kind of knowledge. Therefore, knowledge must be provided by the user of the tree.
This will guide you to participate in the event. Let the tree provide events for which the user can provide handlers. The type looks like this:
type
PTreeNodeUserData = type Pointer;
TTreeNodeCreateUserDataEvent = fun ction: PTreeNodeUserData of object;
TTreeNodeDestroyUserDataEvent = procedure(Data: PTreeNodeUserData) of object;
TTreeNodeCopyUserDataEvent = procedure(Source, Dest: PTreeNodeUserData) of object;
Then you can arrange Tree publishing has these types of events that users can subscribe to.
The key is that this allows users of the tree to provide missing knowledge about the types of user data.
I am trying to get rid of short strings.
One of the many places currently used in our plan is records.
Many of these records are stored in the AVL tree.
Use The AVL tree is universal, it contains a pointer to multiple bytes (ElemSize), these pointers have worked well so far.
The memory of each record in the AVL tree is allocated using GetMem and copied using Move.< br>However, if the string is a pointer to a reference counting structure, copying the memory back to the record is no longer valid, because the referenced sting is often released (automatically by reference counting).
There is only one pointer and “data block” Size, I think it is impossible to increase the reference count of the string.
I am looking for a way to get the reference count of the bite to be considered when storing records in the AVL tree.
Can I pass the record type to the tree constructor and then cast the pointer to this type to increase the reference? Or a similar fix, I can isolate the changes mainly in the AVL unit and call its constructor.
Current code used to allocate space for storing AVL records; XData points to the record to be stored Pointer:
New(RootPtr); {create new memory space }
GetMem(RootPtr^.TreeData, ElemSize);
WITH RootPtr^ DO BEGIN
{copy data }
Move(XData^, RootPtr^.TreeData^, ElemSize);
In essence, you The question to ask is:
How can I allocate, copy and deallocate a record when all I know about its type is its size?
The simple answer is that if the record does not contain managed types, you can use GetMem, Move, and FreeMem. You want to use records that contain Delphi strings, which are managed. Therefore, use The current methods of GetMem and Move are not enough.
There are many ways to solve this problem. You can write your own code to do reference counting, as long as you know where the managed type is in the record. I This is not recommended. You can set your user data as a class and use polymorphism to help.
The options I want to discuss continue to support records, and indeed allow users to choose any type they like The reason is as follows:
If the type contains managed types, you need to understand the type to operate on it. If the tree is universal, then it does not have this knowledge. Therefore, the knowledge must be provided by the user of the tree .
This will guide you to the event. Let the tree provide events that users can provide handlers for. The type looks like this:
type
PTreeNodeUserData = type Pointer;
TTreeNodeCreateUserDataEvent = function: PTreeNodeUserData of object;
TTreeNodeDestroyUserDa taEvent = procedure(Data: PTreeNodeUserData) of object;
TTreeNodeCopyUserDataEvent = procedure(Source, Dest: PTreeNodeUserData) of object;
Then you can arrange for tree publishing with these types of objects that users can subscribe to Event.
The point is that this allows users of the tree to provide missing knowledge about the type of user data.