
' StandaloneIndex_Huge
' Shows how to use an index without an associated database. This
' allows you to use the index to store keys and "record numbers". 
' Basically, the "record number" can be any 32-bit value that is
' of meaning to the user. This demo creates very large indexes
' in order to benchmark speed of insertion and deletion.

' This code can be used with Cheetah DLL's that have either full
' database support compiled into it, or with DLL's that only have
' the index routines compiled in them.

' This demo uses the PowerBASIC Console compiler.

#Compile Exe

#Include "..\..\include\Cheetah4_PowerBasic.inc"

'JPRO_COMPILER=PB/CC


Function PBMain() As Long
   
   Local idxHandle As Long
   Local tagHandle1 As Long
   
   Local errcode   As Long
   Local sData     As String
   Local sKey      As String
   Local nRecNum   As Long
   Local NumRead   As Long
   Local NumRecs   As Long
   Local x         As Long
   Local StartTime As Single
   Local EndTime   As Single
                            
   Cls
   
   sData = "disk = standalone.btx;"  
   errcode = xdbCreateIndex( sData ) 
   If errcode Then GoTo ExitOut

   ' In order to use the index without an associated database, you
   ' must specify the "NoDatabase" property and set it to "TRUE".
   sData = "disk=standalone.btx; nodatabase=true;" 
   errcode = xdbOpenIndex( sData, 0, idxHandle ) 
   If errcode Then GoTo exitout

   Print "Create/open index. Handle:"; Str$(idxHandle)
   

   '// CREATE AN INDEX TAG
   ' When you create a Tag, it is your responsibility to specify
   ' the size of the keys.
   sData = "TagName=mytag; Size=20; Uppercase=TRUE"
   errcode = xdbCreateTag( sData, idxHandle ) 
   If errcode Then GoTo exitout

   errcode = xdbGetTag( "mytag", idxHandle, tagHandle1 ) 
   If errcode Then GoTo exitout

   Print "GetTag. 'mytag' Handle:"; Str$(tagHandle1)
   
   
   NumRecs = 50000

   Print
   Print "Adding "; Format$(NumRecs); " Index keys and values"

   StartTime = Timer
   
   '// ADD INDEX KEYS //         
   For x = 1 To NumRecs
      sKey    = Format$(Rnd(100000, 999999))
      nRecNum = x
      If xdbAddKey( tagHandle1, sKey, nRecNum ) Then GoTo exitout
   Next
   
   EndTime = Timer
   
   Print Format$(NumRecs); " Index keys and values added. Time: "; Format$(EndTime-StartTime, "0.000"); " seconds."
   Print
   

   '// MOVE THROUGH THE INDEX TAG (USING BOTH MOVE METHODS)
   ' Because there is no database, specify 0 for the database handle.
   NumRead = 0
   StartTime = Timer
   errcode = xdbMove( 0, tagHandle1, %XDB_MOVEFIRST, nRecNum )

   ' Regular XDB_MOVENEXT method
   Do Until errcode <> 0   ' loop until end of file reached
    
      Incr NumRead
      
      errcode = xdbGetKey( tagHandle1, sKey, nRecNum )
      If errcode Then GoTo ExitOut
      
      'Print "Key: "; sKey; "   RecNum: "; Str$(nRecNum)
      
      errcode = xdbMove( 0, tagHandle1, %XDB_MOVENEXT, nRecNum )
   Loop

   EndTime = Timer
   Print "Time to read "; Format$(NumRead); " Index keys (xdb_MoveNext). Time: "; Format$(EndTime-StartTime, "0.000"); " seconds."


   NumRead = 0
   StartTime = Timer
   errcode = xdbMove( 0, tagHandle1, %XDB_MOVEFIRST, nRecNum )

   ' Faster XDB_MOVENEXT_ATOMIC method
   Do Until errcode <> 0   ' loop until end of file reached
    
      Incr NumRead
      
      errcode = xdbGetKey( tagHandle1, sKey, nRecNum )
      If errcode Then GoTo ExitOut
      
      'Print "Key: "; sKey; "   RecNum: "; Str$(nRecNum)
      
      errcode = xdbMove( 0, tagHandle1, %XDB_MOVENEXT_ATOMIC, nRecNum )
   Loop

   EndTime = Timer
   Print "Time to read "; Format$(NumRead); " Index keys (xdb_MoveNext_Atomic). Time: "; Format$(EndTime-StartTime, "0.000"); " seconds."

   
ExitOut:

   
'// CLOSE THE INDEX //                 
   xdbCloseIndex idxHandle

'// SHUTDOWN THE SYSTEM //
   xdbShutdown

   Print
   Print "Completed"
   
   While InKey$ = "": Wend
        
End Function

