Does anyone know where Heap_Size is stored?
And - probably some changes to await, I guess the variables-"byName" functions could all get prefixed Variable_ - thinking - I'm just not in the mood to update all examples today. See my last blog.
Still on it
This time there are no additional functions but the opposite case: I threw a few out since they were not really needed.
There's no more
Heap_FreeAt:
the same can be achieved a few different ways already
Heap_SetAt position_of_myPtr, ""
Heap_ResizeAt position_of_myPtr, 0
Heap_ElementRemoveAt position_of_myPtr, 1, Heap_Size(value_of_myPtr) ' not made for that purpose, but does it too
Heap_ElementScanIndex/Heap_ElementScanPtr:
both are a little too "special" and I created them before Heap_ElementIDAt - which serves when it comes to indexing unique values as vertices, colors etc.
Functions-Overview
MinVersion 1.9.7.0 - get it here
FileVersion 0.35, 07.08.2013
Last edited by ReneMiner; 08-08-2013 at 13:37.
I think there are missing some Forum-sections as beta-testing and support
Does anyone know where Heap_Size is stored?
And - probably some changes to await, I guess the variables-"byName" functions could all get prefixed Variable_ - thinking - I'm just not in the mood to update all examples today. See my last blog.
Last edited by ReneMiner; 09-08-2013 at 08:52.
I think there are missing some Forum-sections as beta-testing and support
Today I got some bigger example. It contains 3 simple functions to manage HEAP-Nodes and allows to build tree-alike structures. It's just a test, means these functions are not part of LazyFun.tBasicU yet but they show what probably to await in near future. MinVersion 1.9.7.0, use attachement 2 posts above.
And once again the question that busies me: at which position can I find Heap_Size?Uses "console" #INCLUDE "lazyFun.tBasicU" '------------------------------------ ' "root" (1 heap) ' Dword node(...) - contains node-Ptrs in element-order 1,2,3... ' ordinary ptr-array = use Heap_Element...-functionality on it '------------------------------------ ' "node" (2 heaps) ' Dword DataPtr - ptr to second heap containing data ' Dword Flags %Flag_Expanded = &H00000001 As DWord %Flag_Hidden = &H00000002 As DWord 'Flags could be some more f.e. %Flag_Disabled etc. ' Dword Parent - contains element-index '[ Dword Child(...) ] - appended element-indexes if some '------------------------------------ DWord myTree ' holds pointer to root-heap DWord myComputer, myCDrive ' hold index of nodes ' create a few nodes ' pass position where to store/find pointer, data, parent(if one) and flags if desired ' and retrieve the Index of this node myComputer = Heap_NodeAppendAt VarPtr myTree, "my computer",,%Flag_Expanded ' myComputer now holds the Element-Index where the pointer to this node can be stored/found in Heap(myTree) ' since it was the very first node it becomes the top-level-parent of all that's noded to myTree later ' the first node always gets Index 1, so never needed to store this - except to make this example readable myCDrive = Heap_NodeAppendAt VarPtr myTree, "c:", myComputer Heap_NodeAppendAt VarPtr myTree, "d:", myComputer Heap_NodeAppendAt VarPtr myTree, "program files", myCDrive Heap_NodeAppendAt VarPtr myTree, "thinBasic" , myCDrive Heap_NodeAppendAt VarPtr myTree, "hidden folder", myCDrive, %Flag_Hidden Heap_NodeAppendAt VarPtr myTree, "windows xp" , myCDrive ' now retrieve a string of the indexes of all visible ' nodes below myComputer(including) in order String sIndexes = Heap_NodeList$(myTree, myComputer) Long i ' virtual overlay of Dwords there: Dim dIndex(StrLen(sIndexes)/4) As DWord At StrPtr(sIndexes) DWord ppNode, pNode, pData ' now print all: For i = 1 To UBound(dIndex) ' small steps: ppNode = HEAP_ElementGetPtr myTree, dIndex(i), 4 ' ask for the place of pointer-storage-position ' for "node(dIndex(i)) in tree 'myTree'" ' 4 means SizeOf(Dword) = the size of one element/ a pointer in myTree pNode = PeekPtrAt ppNode ' get the actual pointer at this "pointer-storage-position" pData = PeekPtrAt pNode ' get the pointer to data-heap at first position of the "node-heap" ' inset according to depth of the node PrintL Repeat$(Heap_NodeGetDepth(myTree, dIndex(i)), " ") + HEAP_Get$(pData) Next PrintL $CRLF + Repeat$(50,"-") + $CRLF PrintL "key to continue" + $CRLF WaitKey PrintL "now expand 'my c-drive'" + $CRLF ' get the pointer to the noded heap: pNode = PeekPtrAt HEAP_ElementGetPtr myTree, myCDrive, 4 ' the second dword is Flags there: Poke(DWord, pNode + 4, %Flag_Expanded) ' retrieve string of visible indexes in order sIndexes = Heap_NodeList$(myTree, myComputer) ' virtual overlay of Dwords there: ReDim dIndex(StrLen(sIndexes)/4) At StrPtr(sIndexes) ' now print all: For i = 1 To UBound(dIndex) Print Repeat$(Heap_NodeGetDepth(myTree, dIndex(i)), " ") PrintL HEAP_Get$ PeekPtrAt PeekPtrAt HEAP_ElementGetPtr myTree, dIndex(i), 4 Next PrintL $CRLF + Repeat$(50,"-") + $CRLF PrintL "key to continue" + $CRLF WaitKey PrintL "now change data at some node in line 5 displayed" pNode = PeekPtrAt HEAP_ElementGetPtr myTree, dIndex(5), 4 HEAP_SetAt pNode, "windows 8" PrintL "or at some Index we know:" pNode = PeekPtrAt HEAP_ElementGetPtr myTree, myCDrive, 4 HEAP_SetAt pNode, "volume C" ' now print again - order has not changed: For i = 1 To UBound(dIndex) Print i + Repeat$(Heap_NodeGetDepth(myTree, dIndex(i)), " ") PrintL HEAP_Get$ PeekPtrAt PeekPtrAt HEAP_ElementGetPtr myTree, dIndex(i), 4 Next PrintL $CRLF + Repeat$(50,"-") + $CRLF PrintL "key to end" + $CRLF WaitKey ' ----------------------------------------------------------------- Function HEAP_NodeAppendAt( ByVal rootPos As DWord, _ ByVal sData As String, _ Optional Parent As DWord, _ Flags As DWord _ ) As DWord ' rootPos awaits a position where the pointer to the root to be found/stored ' sData the data to set at this node ' only the first node of a tree can be without parent ' use flags as %Flag_Expanded, %Flag_Hidden or create own, additional flags If rootPos < 1 Then Return 0 ' invalid pointer-position Local pData, pNode, ppParent, Index As DWord If StrLen(sData) Then pData = HEAP_AllocByStr(sData) If pData = 0 Then Return 0 ' probably out of memory... EndIf ' new nodes Index would be: Index = HEAP_Size(PeekPtrAt rootpos)/4 + 1 ' the node consists of DataPtr + Flags + ParentIndex [ + ChildIndex(...) ] If Index = 1 Then ' this is the first node then HEAP_SetAt rootpos, MKDWD$( HEAP_AllocByStr( MKDWD$(pData, Flags, 0) ) ) Return 1 EndIf If Parent < 1 Or Parent >= Index Then ' impossible- that index does not exist If HEAP_Size(pData) Then HEAP_Free(pData) Return 0 EndIf ' find out pointer-position of the parent that's Index we have here ppParent = HEAP_ElementGetPtr( PeekPtrAt rootpos, Parent, 4 ) ' append the new childs Index at the parent If Not HEAP_AppendAt ppParent, MKDWD$(Index) Then ' something went wrong - release garbage: If HEAP_Size(pData) Then HEAP_Free(pData) Return 0 EndIf ' create the new node since we got all needed data now pNode = HEAP_AllocByStr( MKDWD$(pData, Flags, Parent) ) If HEAP_Size(pNode) < 12 Then ' something went wrong - release garbage: If HEAP_Size(pData) Then HEAP_Free(pData) If HEAP_Size(pNode) Then HEAP_Free(pNode) Return 0 EndIf ' append the new nodes pointer as new index-element finally If Not HEAP_AppendAt rootPos, MKDWD$(pNode) Then ' probably out of memory or amount of nodes*4 exceeds max heap-size... If HEAP_Size(pData) Then HEAP_Free(pData) If HEAP_Size(pNode) Then HEAP_Free(pNode) Return 0 EndIf Function = Index End Function ' ----------------------------------------------------------------- Function HEAP_NodeGetDepth(ByVal pRoot As DWord, _ ByVal Index As DWord _ ) As DWord ' retrieve depth of a node passing it's root-pointer and index ' will return 1 for the first -(top-level-parent)- node, 2 for a child of first, 3 for grandchild etc. If Index > HEAP_Size(pRoot)/4 Then Return 0 Local dResult, pNode As DWord While Index > 0 dResult += 1 pNode = PeekPtrAt HEAP_ElementGetPtr( pRoot, Index, 4 ) If HEAP_Size(pNode) < 12 Then Exit While Index = Peek(DWord, pNode + 8) Wend Function = dResult End Function ' ----------------------------------------------------------------- Function HEAP_NodeList$(ByVal pRoot As DWord, _ ByVal Index As DWord _ ) As String Local i As Long Local pNode As DWord Local sResult As String ' recursive build a string together ' so this will build a list of indexes of visible/expanded nodes ' and return them in a string finally ' pRoot awaits the pointer to root-heap ' as Index pass the Index of the node to start with pNode = PeekPtrAt HEAP_ElementGetPtr( pRoot, Index, 4 ) If Peek(DWord, pNode + 4) And %Flag_Hidden Then Return "" sResult = MKDWD$(Index) If HEAP_Size(pNode) > 12 Then ' this one has children If Peek(DWord, pNode + 4) And %Flag_Expanded Then For i = 3 To HEAP_Size(pNode)/4 - 1 sResult += HEAP_NodeList$(pRoot, Peek(DWord, pNode + i * 4 )) Next EndIf EndIf Function = sResult ' on exit this returns a string with all visible below Index (incl.Index!) End Function
Last edited by ReneMiner; 10-08-2013 at 15:21.
I think there are missing some Forum-sections as beta-testing and support
for a string you find strings length just 4 bytes in front of the string. sadly not at heap...but maybe somewhere else or just in another format (ascii?)
and b.t.w. you told me in the oxygen-thread that heap would not be exclusively belong to tB - now what shall I believe?
Last edited by ReneMiner; 10-08-2013 at 19:23.
I think there are missing some Forum-sections as beta-testing and support
Hi Rene,
Heap in ThinBASIC is not implemented via PB commands, it is done via Win32 - HeapAlloc, HeapFree, HeapRealloc, HeapSize... sounds similar, doesn't it
There is a Win32 function which could be useful for your hacking, it is called HeapWalk. It is placed in Kernel32.dll, the second parameter it has is a bit hardcore , but if you manage to translate the PROCESS_HEAP_ENTRY to TB, you should be able to reach information you need.
On the other (dark ) side. You need to call HeapWalk to get the pointer to data structure somewhere. You will most probably end up at same speed calling just Heap_Size directly...
Petr
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
It's not a speed issue in that matter: I think about let oxygen make the calculating - but I need the heap-size urgently to get into oxygen somehow without passing it in each call which would be kind'a stupid because the condition Heap_Size(x) > 0 has to be given - so I could do the whole formula in tb if I had to ask it in advance then. And also would slow down the operation because the function always would have an additional byval-parameter - the other way would be if oxgen would have some own heap- i could let it return the needed stuff if as pointers or data there were some o2-heap - not limited to 512 elements as memory.
John, no quote but a link - did I understand wrong?
Last edited by ReneMiner; 10-08-2013 at 21:08.
I think there are missing some Forum-sections as beta-testing and support
New functions - new version. More Examples may follow later - I leave old version attached at previous page to run the older examples. I changed parameters order for Heap_NodeAppendAt, changed vartypes used for Indexes from long to dword - since all happens above 0... and also added a few more functions. So this is the arsenal at the time:
functions to variables passed "byName"
VARIABLE_Get$ get string-data from any variable passed "byName"
VARIABLE_GetDataPtr get pointer to data of a certain element of any variable
VARIABLE_GetPtr get pointer to any variable
VARIABLE_SetStr set string-data to any variable
VARIABLE_SetUdtStr set string-data to dynamic string in udts
VARIABLE_GetInfoEx Lib "thinCore.DLL" Alias "thinBasic_VariableGetInfoEX"
restrictions:
=============
for multidimensional arrays
just the first elements pointer can be returned
only first or all elements capture is possible
functions to manage Heap-memory
common:
HEAP_AppendAt append some data to heap and store pointer at specified position
HEAP_Copy create copy of existing heap and return new pointer
HEAP_Fill fills/overwrites heap with some string-data
HEAP_Get$ get entire heap in up to 5 dimensions
HEAP_InsertAt insert data at absolute position
HEAP_Instr retrieve position of a string to find
HEAP_Left$ get left part/get string of desired length with heap content left
HEAP_Mid$ get mid part/get string of desired length and heap within
HEAP_ResizeAt resizes heap, preserving data, resize to 0 will free data
HEAP_Right$ get right part/string of desired lenght with heap-content right
HEAP_SetAt set data to heap and get/store pointer at the specified position
elements stored in "1-dimensional, fixed size heap-array":
HEAP_ElementGet$ returns data of one element
HEAP_ElementGetIndex returns index of data or 0 if not found
HEAP_ElementGetPtr returns pointer to element
HEAP_ElementIDAt returns index of data, creates it if not exists
HEAP_ElementInsertAt insert data as new element
HEAP_ElementRemoveAt will remove one element
HEAP_ElementSet set data of existing element to new content
stored in a tree-structure as nodes
HEAP_NodeAppendAt creates a new node
HEAP_NodeCountChildren returns count of children at this node
HEAP_NodeGetDepth will return "distance" of node from root
HEAP_NodeList$ lists indexes of all visible & expanded nodes
HEAP_NodeSetFlag manipulate a nodes "Flags-property"
deprecated:
HEAP_NodeGet$ retrieve data noded at node - HEAP_Get$(pRoot, Index, 1) to read out data here
HEAP_ElementPeekPtr peek a pointer that is stored as element : replaced/improved by HEAP_GetPtr
HEAP_NodeGetChildPtr retrieve pointer to the first childs index of Node(Index): use Heap_GetPtr(pRoot, Index) + 12
HEAP_NodeGetParentIndex returns index of a nodes parent-node : abuse HEAP_GetPtr(pRoot, Index, 3)
HEAP_NodeGetParentPtr returns pointer to a nodes parent-node: abuse HEAP_GetPtr(pRoot, HEAP_GetPtr(pRoot, Index, 3))
HEAP_NodeGetDataPtr retrieve pointer to noded data-heap : use HEAP_GetPtr(pRoot, Index, 1)
HEAP_ElementFreePtrAt removes a pointer-element and free sub-heap: use HEAP_FreeAt + HEAP_ElementRemoveAt
HEAP_NodeFreeTreeAt free all data noded at the specified root- just use HEAP_FreeAt(pRoot)
NEW:
HEAP_DimAt setup dynamic heap up to 5 base-dimensions
HEAP_FreeAt free all dimensioned and normal heap and update pointer-position
HEAP_GetPos get position in 5 dimensions where to store/find pointer
HEAP_GetPtr get pointer in 5 dimensions -replaces HEAP_ElementPeekPtr
organized in multidimensional storage:
HEAP_OrganizeAddress will return an address where to find/store data
HEAP_OrganizeAt will create organized heap with at least 2 dimensions
HEAP_OrganizerFreeAt will free heap + organized Sub-heap
HEAP_OrganizerGetDim$ returns information about organized heap dimensions
functions to dynamic strings
Dictionary_Len returns size of dictionary-buckets
StrAtPtr$ returns string found at passed position
StrLen limited usage since not works on udt-substrings, shortens StrPtrLen(StrPtr())
pointer-functions
PeekPtrAt safe way to Peek pointers without risk to Peek At 0
Functions theirs names end with "At" await an address where to find a valid pointer and/or to store the new pointer at
Functions theirs names end with "$" return strings
find it HERE
Last edited by ReneMiner; 19-08-2013 at 15:05.
I think there are missing some Forum-sections as beta-testing and support
Noding heap -
EDIT: Example removed because of some changes: find a Nodes-example on the next page.
The image below is to illustrate how those nodes work.
The root-heap is some row of pointers-elements. At position 1 is stored the pointer to "node 1", at position 2 will the pointer to "node 2" be stored etc.
The node heap consists of at least 3 Dwords. At the first position the pointer to the data can be stored.
The second dword is to hold some flags, f.e. is that node expanded etc.
The third dword will hold the position (Index) where to find the parents-pointer in root-heap. The first node does not have a parent...
All following dwords (if some) will hold the Indexes of noded children.
So green numerals in root show the Index - which holds a pointer.
All what's named "...Index" holds an Index = the (element-)position where to find pointer to parent or children in root-heap.
Last edited by ReneMiner; 19-08-2013 at 15:07.
I think there are missing some Forum-sections as beta-testing and support
Hi Rene,
looking at the code, what is faster in you experience:
orPeek(Dword, ... )
DWord something At 0 SetAt(something, ...)
Petr
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
There are a couple of reasons:
1. I just want to have be the best basic available in this corner of the milky way on my drive...
2. Look here! Its possible that easy - even someone like me can do it!
3. Nananananana
Back to serious: I made some test to compare speed of virtual read-out and Peek-methods. Be surprised about the result!
Now - who would have thought how clear without ambiguity that result would be...Uses "Console" %MAX_Tests = 100000 DWord testfield = HEAP_AllocByStr(Repeat$(%MAX_Tests, MKDWD$(1234))) DWord dRead DWord X At 0 Quad tStart,tEnd Double tTime 'for obtain elapsed time Long i ' -- Initialize high precision timer HiResTimer_Init '--------------------------------------------------------------------- PrintL "Peek-speed test" + Str$(%Max_Tests) + " of executions:" PrintL PrintL "Press a Key to start" WaitKey tStart = HiResTimer_Get For i = 0 To %Max_Tests - 1 dRead = TestPeek( testField + i * 4 ) Next tEnd = HiResTimer_Get : tTime = (tEnd-tStart)/1000000 PrintL CRLF & "Executed in " & Format$(tTime, "#.00") & " seconds" & CRLF '--------------------------------------------------------------------- PrintL "Press a Key to start virtual method" WaitKey tStart = HiResTimer_Get For i = 0 To %Max_Tests - 1 dRead = TestVirtual( testField + i * 4 ) Next tEnd = HiResTimer_Get : tTime = (tEnd-tStart)/1000000 PrintL CRLF & "Executed in " & Format$(tTime, "#.00") & " seconds" & CRLF PrintL "Press a Key to exit" WaitKey '--------------------------------------------------------------------- Function TestPeek(ByVal pos As DWord) As DWord Return Peek(DWord, pos) End Function '--------------------------------------------------------------------- Function TestVirtual(ByVal pos As DWord) As DWord ' Dword x At pos = MUCHO SLOWLY SetAt( x, Pos ) Return x End Function
Yesterday I feared I had to rewrite lots of code. Today I know...
If use the result just once - stick to peek. Else use the other way so not needed to store result locally. If x wouldn't have been defined at 0 in advance it would need almost double the time.
Last edited by ReneMiner; 13-08-2013 at 09:27.
I think there are missing some Forum-sections as beta-testing and support
Bookmarks