numerical equivalent to a map?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

numerical equivalent to a map?

Post by Tenaja »

Is there one? I don't mean an array, I mean a random sized, numerical key-indexed map. For a few items, I have used a Select-Case, but that is cumbersome, not easy to read like a map, and not very suitable for 100's of items. My numbers can be of any size up to 32 bits, and I want to tie a value to them, much like an array or a map. Unfortunately, the array takes up far too much memory, and converting the number to a string is not very efficient. Something like this...

Code: Select all

IntMap(500) = 32
IntMapString(24632) = "my string"
Any suggestions would be appreciated. Thanks in advance...
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: numerical equivalent to a map?

Post by idle »

you can use a BitTrie to do it

There's a generic one in my bitmodule with comparable performance to a pb map
http://www.purebasic.fr/english/viewtop ... 40&t=57409

to use it

Code: Select all

trie.BitModule::IBitTrie 
trie = BitModule::New_BitTrie(size) ; give it a size to pre allocate x number of nodes, defaults at 64 nodes  
trie\Set(key,value)  
trie\Get(key)  
trie\Free() 
or there's a more optimized one for x86 only
http://www.purebasic.fr/english/viewtop ... 12&t=47436
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: numerical equivalent to a map?

Post by Tenaja »

idle wrote:you can use a BitTrie to do it

There's a generic one in my bitmodule with comparable performance to a pb map
http://www.purebasic.fr/english/viewtop ... 40&t=57409

to use it

Code: Select all

trie.BitModule::IBitTrie 
trie = BitModule::New_BitTrie(size) ; give it a size to pre allocate x number of nodes, defaults at 64 nodes  
trie\Set(key,value)  
trie\Get(key)  
trie\Free() 
or there's a more optimized one for x86 only
http://www.purebasic.fr/english/viewtop ... 12&t=47436
Thanks--that does fill the bill syntax-wise, but it is a little heavier than I was hoping for...and I will need a 64-bit version, so the smaller one is not so helpful.

Edit:
I did some searching, and found a few Trie libraries that are smaller; I will likely give a go at translating them to PB. Thanks again.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: numerical equivalent to a map?

Post by Tenaja »

Nevermind...you put a lightweight one here:
http://purebasic.fr/english/viewtopic.p ... ie#p360570
Thanks yet again!
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: numerical equivalent to a map?

Post by idle »

might be better for you to rip the implementation out of the lib
if you don't want the other classes in the module
it'll be a bit faster than the other trie
Windows 11, Manjaro, Raspberry Pi OS
Image
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: numerical equivalent to a map?

Post by davido »

@Tenaja: Great question!
@idle: Thank you for a great answer.

I am going to find this very useful. :D
DE AA EB
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: numerical equivalent to a map?

Post by Tenaja »

Idle,
I stripped it down to four essential functions: Set, Get, ByteCount, and Free. I added your test code from the 2010 Trie, and this one is almost twice as fast.

Is there an easy way to adapt it to strings and random-sized structures? I have not used PB pointers very much. (I have used them more for data sections and procedures than strings or structures...)

Thanks.

Code: Select all

EnableExplicit

DeclareModule TrieModule
	
	; Mar 13, 2014: From BitModule, but reduced to minimal Trie features
	
	;TrieModule
	;Author Idle 17/11/13
	;PB 5.20
	;v1.3.4
	
	;Description
	;
	;BitTrie     ;builds a bit Trie key size determines the maximum number of items to add,  eg 8=256 entries 16= 65596 entries ...
	;stores an integer value with the key 
	
	
	
	Prototype BitTrieCB(value.i)
	
	Interface IBitTrie      ;bit Trie
		Set(key,value)
		Get(key)
		ByteCount()
		Free()
	EndInterface   
	
	
	Declare New_BitTrie(size=64)  ;expected number of items     
EndDeclareModule



; ------
; ------


Module TrieModule
	
	
	Structure BitBufInfo
		Size.q
		Bytesused.q
		Position.q
		Misc.l
	EndStructure 
	
	Structure BitBuffer
		*vt
		inf.bitbufinfo
		*buf
	EndStructure   
	
	Structure node
		inext.i[2] 
		value.i           
	EndStructure       
	
	Structure BitTrie Extends bitBuffer
		avail.i
	EndStructure
	
	
	
	
	Procedure New_BitTrie(size=64)
		Protected *this.BitTrie
		*this = AllocateMemory(SizeOf(bittrie))
		*this\vt = ?vt_BitTrie
		*this\inf\size = Size*SizeOf(node)
		*this\inf\Bytesused = *this\inf\size
		*this\inf\Position=SizeOf(node)
		;*this\inf\misc = Round(Log(size) / Log(2),#PB_Round_Up)  -1   ;not needed v1.3.3
		*this\buf = AllocateMemory(*this\inf\Size)
		*this\avail = *this\inf\size-SizeOf(node)
		ProcedureReturn *this
	EndProcedure
; ------
	
	
	Procedure BitTrie_Add(*this.bittrie,key.i,val.i)
		Protected *node.node,idx,a,lp
		
		CompilerIf SizeOf(Integer) = 8
			!bsr qword rax , qword [p.v_key]   
			!mov [p.v_lp] , rax 
		CompilerElse
			!bsr dword eax , dword [p.v_key]   
			!mov [p.v_lp] , eax   
		CompilerEndIf   
		
		*node = *this\buf
		
		For a = lp To 0 Step -1
			idx = (key >> a) & 1
			
			If *node\inext[idx]     
				tpos =  *node\inext[idx]
				*node = *this\buf + *node\inext[idx] 
			ElseIf *this\avail  > 0
				*node\inext[idx] = *this\inf\Position
				tpos =*this\inf\Position
				*node = *this\buf  +*this\inf\Position
				*this\avail - SizeOf(node)
				*this\inf\Position+SizeOf(node)
				*this\inf\Bytesused = *this\inf\Position 
			Else
				*this\avail = 64*SizeOf(node)
				*this\inf\size + *this\avail
				*this\buf = ReAllocateMemory(*this\buf,*this\inf\size)
				*node = *this\buf+ tpos
				*node\inext[idx] = *this\inf\Position
				*node = *this\buf  +*this\inf\Position
				*this\avail - SizeOf(node)
				*this\inf\Position+SizeOf(node)
				*this\inf\Bytesused = *this\inf\Position
			EndIf
		Next   
		*node\value = val	
	EndProcedure
; ------
	
	
	Procedure BitTrie_Get(*this.bittrie,key.i)
		Protected *node.node,value,a,idx,lp
		
		CompilerIf SizeOf(Integer) = 8
			!bsr qword rax , qword [p.v_key]   
			!mov [p.v_lp] , rax 
		CompilerElse
			!bsr dword eax , dword [p.v_key]   
			!mov [p.v_lp] , eax   
		CompilerEndIf   
		
		*node = *this\buf
		
		For a = lp To 0 Step -1
			idx = (key>>a) & 1
			If *node   
				If *node\inext[idx]     
					*node = *this\buf + *node\inext[idx]
				Else
					Break
				EndIf
			Else
				ProcedureReturn 0 
			EndIf
		Next   
		
		ProcedureReturn *node\value	
	EndProcedure
; ------
	
	
	Procedure BitBuffer_GetByteCount(*this.bitbuffer)
		If *this
			ProcedureReturn *this\inf\BytesUsed
		EndIf
	EndProcedure
; ------
	
	
	Procedure BitBuffer_Free(*this.bitbuffer)
		If *this
			FreeMemory(*this\buf)
			FreeMemory(*this)
		EndIf
	EndProcedure
; ------
	
	
	
	DataSection
		vt_BitTrie:							; Interface IBitTrie:
		Data.i @BitTrie_Add()				;	Set(key,value)
		Data.i @BitTrie_Get()				;	Get(key)
		Data.i @BitBuffer_GetByteCount()	;	ByteCount()
		Data.i @BitBuffer_Free()			;	Free()
	EndDataSection
	
EndModule




;----------------------------------------------------------------------
;-DEMO CODE ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------




CompilerIf 0
	Global.i key, value
	Global trie.TrieModule::IBitTrie
	
	Global x.i
	
	For x = 0 To 256
	
		trie = TrieModule::New_BitTrie() ; give it a size to pre allocate x number of nodes, defaults at 64 nodes
		For value = 0 To 255 Step 8
			key = 8 * value
			trie\Set(key,value) 
			Debug "key="+key+", val=" +  trie\Get(key) 
		Next
		
		Debug "..."
		For key = 0 To 2048
			If trie\Get(key)
				Debug Str(key) + "=" + trie\Get(key)
			EndIf
		Next
		
		trie\Free()
	
	Next x

CompilerEndIf 





CompilerIf 1	
	;-Timed Test code_____________________________________________________________________
	DisableExplicit
	
	Global trie.TrieModule::IBitTrie ;mt.clsTrie = NewTrie(@mt)
	
	;DisableDebugger
	
	Structure pair
		a.i
		b.i
	EndStructure
	
	NewMap a.i()
	
	trie = TrieModule::New_BitTrie()
	
	MessageRequester("INFO", "Filling List and Maps.")
	
	start = ElapsedMilliseconds()
	b=46589
	For a=1 To 10000
		b+1
		a(Str(a)) = b
		a(Str(b)) = a
	Next
	
	stop = ElapsedMilliseconds()
	
	result_trie = stop-start
	
	start = ElapsedMilliseconds()
	
	For a = 1 To 10000
		trie\Set(a,b)	;	mt\Add(a,b)
		trie\Set(b,a) 	;	mt\Add(b,a)
		
	Next
	
	stop = ElapsedMilliseconds()
	
	result_map = stop-start
	MessageRequester("Filling:", "Map: "+Str(result_map)+#CRLF$+"Trie: "+Str(result_Trie))
	
	
	start = ElapsedMilliseconds()
	For b = 1 To 10
		
		For n = 10 To 10000
			temp = trie\Get(n)	;mt\LookUp(n)
		Next
		
		For n = 46599 To 97799
			temp = trie\Get(n)	;mt\LookUp(n)
		Next
		
	Next 
	stop = ElapsedMilliseconds()
	
	result_trie = stop-start
	
	start = ElapsedMilliseconds()
	
	For b = 1 To 10
		
		For n = 10 To 10000
			temp = a(Str(n))
		Next
		
		For n = 46599 To 97799
			temp = a(Str(n))
		Next
		
	Next 
	
	stop = ElapsedMilliseconds()
	
	result_map = stop-start
	
	MessageRequester("", "Map: "+Str(result_map)+#CRLF$+"Trie: "+Str(result_Trie))
	
	; mt\Free()
	trie\Free()
	
	
	; typical output (with Debugger OFF):
	; Map:	563
	; Trie:	98
	
CompilerEndIf
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: numerical equivalent to a map?

Post by idle »

Is there an easy way to adapt it to strings and random-sized structures? I have not used PB pointers very much. (I have used them more for data sections and procedures than strings or structures...)
Yes you just need to set the value of the trie with a pointer to some structure

Code: Select all

Structure UserData                       ;some structure you want to use to store with the trie 
      i.i
      s.s 
EndStructure    

Global *puserdat.userdata 
*puserdat =  AllocateMemory(SizeOf(userdata))    ;make a new userdata item 
*puserdat\i = a               
*puserdat\s = Str(a)
 
Trie\Set(a,*puserdat) ;set the trie value with the pointer to the data 

*puserdat = trie\get(a)      ;get a userdata item 
If *puserdat 
   Debug *puserdat\s 
EndIf 


Additionally you'll need the trie walk procedure so you can have the trie free the memory of your userdata

Regarding the speed it should be fairly close to a map but there are numerous factors to consider
which effect the performance of both.

The amendment with example

Code: Select all

EnableExplicit

DeclareModule TrieModule
   
   ; Mar 13, 2014: From BitModule, but reduced to minimal Trie features
   
   ;TrieModule
   ;Author Idle 17/11/13
   ;PB 5.20
   ;v1.3.4
   
   ;Description
   ;
   ;BitTrie     ;builds a bit Trie key size determines the maximum number of items to add,  eg 8=256 entries 16= 65596 entries ...
   ;stores an integer value with the key 
   
   
   
   Prototype BitTrieCB(value.i)
   
   Interface IBitTrie      ;bit Trie
      Set(key,value)
      Get(key)
      Walk(*cb.bitTrieCB) 
      ByteCount()
      Free()
   EndInterface   
   
   
   Declare New_BitTrie(size=64)  ;expected number of items     
EndDeclareModule



; ------
; ------


Module TrieModule
   
   
   Structure BitBufInfo
      Size.q
      Bytesused.q
      Position.q
      Misc.l
   EndStructure 
   
   Structure BitBuffer
      *vt
      inf.bitbufinfo
      *buf
   EndStructure   
   
   Structure node
      inext.i[2] 
      value.i           
   EndStructure       
   
   Structure BitTrie Extends bitBuffer
      avail.i
   EndStructure
   
   
   
   
   Procedure New_BitTrie(size=64)
      Protected *this.BitTrie
      *this = AllocateMemory(SizeOf(bittrie))
      *this\vt = ?vt_BitTrie
      *this\inf\size = Size*SizeOf(node)
      *this\inf\Bytesused = *this\inf\size
      *this\inf\Position=SizeOf(node)
      ;*this\inf\misc = Round(Log(size) / Log(2),#PB_Round_Up)  -1   ;not needed v1.3.3
      *this\buf = AllocateMemory(*this\inf\Size)
      *this\avail = *this\inf\size-SizeOf(node)
      ProcedureReturn *this
   EndProcedure
; ------
   
   
   Procedure BitTrie_Add(*this.bittrie,key.i,val.i)
      Protected *node.node,idx,a,lp
      
      CompilerIf SizeOf(Integer) = 8
         !bsr qword rax , qword [p.v_key]   
         !mov [p.v_lp] , rax 
      CompilerElse
         !bsr dword eax , dword [p.v_key]   
         !mov [p.v_lp] , eax   
      CompilerEndIf   
      
      *node = *this\buf
      
      For a = lp To 0 Step -1
         idx = (key >> a) & 1
         EnableExplicit

DeclareModule TrieModule
   
   ; Mar 13, 2014: From BitModule, but reduced to minimal Trie features
   
   ;TrieModule
   ;Author Idle 17/11/13
   ;PB 5.20
   ;v1.3.4
   
   ;Description
   ;
   ;BitTrie     ;builds a bit Trie key size determines the maximum number of items to add,  eg 8=256 entries 16= 65596 entries ...
   ;stores an integer value with the key 
   
   
   
   Prototype BitTrieCB(value.i)
   
   Interface IBitTrie      ;bit Trie
      Set(key,value)
      Get(key)
      Walk(*cb.bitTrieCB) 
      ByteCount()
      Free()
   EndInterface   
   
   
   Declare New_BitTrie(size=64)  ;expected number of items     
EndDeclareModule



; ------
; ------


Module TrieModule
   
   
   Structure BitBufInfo
      Size.q
      Bytesused.q
      Position.q
      Misc.l
   EndStructure 
   
   Structure BitBuffer
      *vt
      inf.bitbufinfo
      *buf
   EndStructure   
   
   Structure node
      inext.i[2] 
      value.i           
   EndStructure       
   
   Structure BitTrie Extends bitBuffer
      avail.i
   EndStructure
   
   
   
   
   Procedure New_BitTrie(size=64)
      Protected *this.BitTrie
      *this = AllocateMemory(SizeOf(bittrie))
      *this\vt = ?vt_BitTrie
      *this\inf\size = Size*SizeOf(node)
      *this\inf\Bytesused = *this\inf\size
      *this\inf\Position=SizeOf(node)
      ;*this\inf\misc = Round(Log(size) / Log(2),#PB_Round_Up)  -1   ;not needed v1.3.3
      *this\buf = AllocateMemory(*this\inf\Size)
      *this\avail = *this\inf\size-SizeOf(node)
      ProcedureReturn *this
   EndProcedure
; ------
   
   
   Procedure BitTrie_Add(*this.bittrie,key.i,val.i)
      Protected *node.node,idx,a,lp
      
      CompilerIf SizeOf(Integer) = 8
         !bsr qword rax , qword [p.v_key]   
         !mov [p.v_lp] , rax 
      CompilerElse
         !bsr dword eax , dword [p.v_key]   
         !mov [p.v_lp] , eax   
      CompilerEndIf   
      
      *node = *this\buf
      
      For a = lp To 0 Step -1
         idx = (key >> a) & 1
         
         If *node\inext[idx]     
            tpos =  *node\inext[idx]
            *node = *this\buf + *node\inext[idx] 
         ElseIf *this\avail  > 0
            *node\inext[idx] = *this\inf\Position
            tpos =*this\inf\Position
            *node = *this\buf  +*this\inf\Position
            *this\avail - SizeOf(node)
            *this\inf\Position+SizeOf(node)
            *this\inf\Bytesused = *this\inf\Position 
         Else
            *this\avail = 64*SizeOf(node)
            *this\inf\size + *this\avail
            *this\buf = ReAllocateMemory(*this\buf,*this\inf\size)
            *node = *this\buf+ tpos
            *node\inext[idx] = *this\inf\Position
            *node = *this\buf  +*this\inf\Position
            *this\avail - SizeOf(node)
            *this\inf\Position+SizeOf(node)
            *this\inf\Bytesused = *this\inf\Position
         EndIf
      Next   
      *node\value = val   
   EndProcedure
; ------
   
   
   Procedure BitTrie_Get(*this.bittrie,key.i)
      Protected *node.node,value,a,idx,lp
      
      CompilerIf SizeOf(Integer) = 8
         !bsr qword rax , qword [p.v_key]   
         !mov [p.v_lp] , rax 
      CompilerElse
         !bsr dword eax , dword [p.v_key]   
         !mov [p.v_lp] , eax   
      CompilerEndIf   
      
      *node = *this\buf
      
      For a = lp To 0 Step -1
         idx = (key>>a) & 1
         If *node   
            If *node\inext[idx]     
               *node = *this\buf + *node\inext[idx]
            Else
               Break
            EndIf
         Else
            ProcedureReturn 0 
         EndIf
      Next   
      
      ProcedureReturn *node\value   
   EndProcedure
; ------
   Procedure BitTrie_Walk(*this.bitTrie,*cb.bitTrieCB) 
   Protected *node.node,*stack.Integer, spos,pos 
   *stack = AllocateMemory(*this\inf\size) 
   pos = SizeOf(node)
  *node = *this\buf +pos
   If *cb 
      spos = 0
      While pos < *this\inf\Bytesused 
          *node = *this\buf +pos
          If *node\value 
              *cb(*node\value)          
          EndIf 
          pos + SizeOf(node)      
      Wend     
  EndIf 
EndProcedure    
   
   Procedure BitBuffer_GetByteCount(*this.bitbuffer)
      If *this
         ProcedureReturn *this\inf\BytesUsed
      EndIf
   EndProcedure
; ------
   
   
   Procedure BitBuffer_Free(*this.bitbuffer)
      If *this
         FreeMemory(*this\buf)
         FreeMemory(*this)
      EndIf
   EndProcedure
; ------
   
   
   
   DataSection
      vt_BitTrie:                     ; Interface IBitTrie:
      Data.i @BitTrie_Add()            ;   Set(key,value)
      Data.i @BitTrie_Get()            ;   Get(key)
      Data.i @BitTrie_Walk()
      Data.i @BitBuffer_GetByteCount()   ;   ByteCount()
      Data.i @BitBuffer_Free()         ;   Free()
   EndDataSection
   
   EndModule
   
   
   Structure UserData                       ;some structure you want to use to store with the trie 
      i.i
      s.s 
   EndStructure    
      
   Procedure cbwalk(*puserdat.userdata)       ;use the walk callback to free the userdata 
      Debug *puserdat\s 
      FreeMemory(*puserdat) 
   EndProcedure 
    
   
   Global trie.TrieModule::IBitTrie
   Global *puserdat.userdata 
   Global a 
   
   trie = TrieModule::New_BitTrie(2048)   ;create the trie with the amount of nodes you want 
   
   For a = 1 To 2048 
     *puserdat =  AllocateMemory(SizeOf(userdata))    ;make a new userdata item 
     *puserdat\i = a              ;set it 
     *puserdat\s = Str(a)
     
     Trie\Set(a,*puserdat)  ;add the userdata to the trie 
     
   Next 
   
   For a = 1 To 2048 Step 8 
      *puserdat = trie\get(a)      ;get a userdata item 
      If *puserdat 
         Debug *puserdat\s 
      EndIf 
  Next     
  Debug "=================================="
  trie\Walk(@cbwalk())    ;walk the trie to free the userdata 
  trie\Free()   ;free the trie 
  
         If *node\inext[idx]     
            tpos =  *node\inext[idx]
            *node = *this\buf + *node\inext[idx] 
         ElseIf *this\avail  > 0
            *node\inext[idx] = *this\inf\Position
            tpos =*this\inf\Position
            *node = *this\buf  +*this\inf\Position
            *this\avail - SizeOf(node)
            *this\inf\Position+SizeOf(node)
            *this\inf\Bytesused = *this\inf\Position 
         Else
            *this\avail = 64*SizeOf(node)
            *this\inf\size + *this\avail
            *this\buf = ReAllocateMemory(*this\buf,*this\inf\size)
            *node = *this\buf+ tpos
            *node\inext[idx] = *this\inf\Position
            *node = *this\buf  +*this\inf\Position
            *this\avail - SizeOf(node)
            *this\inf\Position+SizeOf(node)
            *this\inf\Bytesused = *this\inf\Position
         EndIf
      Next   
      *node\value = val   
   EndProcedure
; ------
   
   
   Procedure BitTrie_Get(*this.bittrie,key.i)
      Protected *node.node,value,a,idx,lp
      
      CompilerIf SizeOf(Integer) = 8
         !bsr qword rax , qword [p.v_key]   
         !mov [p.v_lp] , rax 
      CompilerElse
         !bsr dword eax , dword [p.v_key]   
         !mov [p.v_lp] , eax   
      CompilerEndIf   
      
      *node = *this\buf
      
      For a = lp To 0 Step -1
         idx = (key>>a) & 1
         If *node   
            If *node\inext[idx]     
               *node = *this\buf + *node\inext[idx]
            Else
               Break
            EndIf
         Else
            ProcedureReturn 0 
         EndIf
      Next   
      
      ProcedureReturn *node\value   
   EndProcedure
; ------
   Procedure BitTrie_Walk(*this.bitTrie,*cb.bitTrieCB) 
   Protected *node.node,*stack.Integer, spos,pos 
   *stack = AllocateMemory(*this\inf\size) 
   pos = SizeOf(node)
  *node = *this\buf +pos
   If *cb 
      spos = 0
      While pos < *this\inf\Bytesused 
          *node = *this\buf +pos
          If *node\value 
              *cb(*node\value)          
          EndIf 
          pos + SizeOf(node)      
      Wend     
  EndIf 
EndProcedure    
   
   Procedure BitBuffer_GetByteCount(*this.bitbuffer)
      If *this
         ProcedureReturn *this\inf\BytesUsed
      EndIf
   EndProcedure
; ------
   
   
   Procedure BitBuffer_Free(*this.bitbuffer)
      If *this
         FreeMemory(*this\buf)
         FreeMemory(*this)
      EndIf
   EndProcedure
; ------
   
   
   
   DataSection
      vt_BitTrie:                     ; Interface IBitTrie:
      Data.i @BitTrie_Add()            ;   Set(key,value)
      Data.i @BitTrie_Get()            ;   Get(key)
      Data.i @BitTrie_Walk()
      Data.i @BitBuffer_GetByteCount()   ;   ByteCount()
      Data.i @BitBuffer_Free()         ;   Free()
   EndDataSection
   
   EndModule
   
   
   Structure UserData                       ;some structure you want to use to store with the trie 
      i.i
      s.s 
   EndStructure    
      
   Procedure cbwalk(*puserdat.userdata)       ;use the walk callback to free the userdata 
      Debug *puserdat\s 
      FreeMemory(*puserdat) 
   EndProcedure 
    
   
   Global trie.TrieModule::IBitTrie
   Global *puserdat.userdata 
   Global a 
   
   trie = TrieModule::New_BitTrie(2048)   ;create the trie with the amount of nodes you want 
   
   For a = 1 To 2048 
     *puserdat =  AllocateMemory(SizeOf(userdata))    ;make a new userdata item 
     *puserdat\i = a              ;set it 
     *puserdat\s = Str(a)
     
     Trie\Set(a,*puserdat)  ;add the userdata to the trie 
     
   Next 
   
   For a = 1 To 2048 Step 8 
      *puserdat = trie\get(a)      ;get a userdata item 
      If *puserdat 
         Debug *puserdat\s 
      EndIf 
  Next     
  Debug "=================================="
  trie\Walk(@cbwalk())    ;walk the trie to free the userdata 
  trie\Free()   ;free the trie 
  
Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply