
'//
'//  Reindex all indexes/TAGS currently associated with the database.
'//
Function ctx_Reindex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long

   Local pDBF       As DBF_TYPE Ptr
   Local pBTX       As BTX_TYPE Ptr
   Local pTAG       As INDEX_TAG_TYPE_MEMORY Ptr
   Local xdbtemp    As CHEETAH4_TYPE
   Local sIndexKey  As String
   Local nRec       As Long
   
   ' Do some tests to ensure that the parameters were correctly
   ' filled in when the call was made.
   If @xdb.reserved = 0 Then
      @xdb.errcode = %ERR_DATA: GoTo ExitOut
   End If
   
   pDBF = @xdb.reserved   ' pointer to the database

   
   ' Reset the index disk files.
   @xdb.errcode = ctx_ResetIndexFiles_Internal( pDBF )
   If @xdb.errcode Then GoTo ExitOut

   
   ' Iterate the database records and add each key to the TAGS.
   For nRec = 1 To @pDBF.DBH.RecordCount

      @xdb.reserved   = pDBF 
      @xdb.nData      = 0        ' prevent record from being copied to user TYPE
      @xdb.nData4byte = nRec     ' record number to get
      If ctx_GetRecord_Internal( xdb ) Then GoTo ExitOut
      
      ' Add key to any associated TAG indexes
      pBTX = @pDBF.pFirstBTX  ' cycle through the indexes
      Do Until pBTX = 0
          
         ' Iterate all TAGS in the index.
         pTAG = @pBTX.pFirstTAG
         Do Until pTAG = 0  
             
            ' Generate the index key for this Tag.
            sIndexKey = ctx_GenerateIndexKey_Internal( pDBF, pTAG, %FALSE ) 
            
            ' Add the New key
            xdbtemp.nData      = StrPtr( sIndexKey )
            xdbtemp.nlen       = Len( sIndexKey )
            xdbtemp.nData4byte = nRec
            xdbtemp.reserved   = pTAG
            
            @xdb.errcode = ctx_InsertKey_Internal( VarPtr(xdbtemp) )
            If @xdb.errcode Then GoTo ExitOut
               
            pTAG = @pTAG.pNextTAG
         Loop
         
         pBTX = @pBTX.pNextBTX      
      Loop
   
   Next


ExitOut:
   Function= @xdb.errcode  
            
End Function
                                                 
                                                 

'//
'//  Destroy and re-create all indexes associated with the database. 
'//
Function ctx_ResetIndexFiles_Internal( ByVal pDBF As DBF_TYPE Ptr ) As Long

   Local pBTX       As BTX_TYPE Ptr
   Local pTAG       As INDEX_TAG_TYPE_MEMORY Ptr 
   Local LookupNode As INDEX_LOOKUP_NODE_TYPE
   Local errcode    As Long         
   Local nRecOff    As Long
   Local NextNode   As Long

   ' Modify the existing indexes so that all that is left is the index
   ' headers and associated TAG lookup nodes.
   pBTX = @pDBF.pFirstBTX
   Do Until pBTX = 0               

      @pBTX.BTH.Freelist   = 0
      @pBTX.BTH.TotalNodes = @pBTX.BTH.NumTags + 1
      
      ' Reset the Lookup nodes for each TAG in the index
      NextNode = 2

      ' Iterate all TAGS in the index.
      pTAG = @pBTX.pFirstTAG
      Do Until pTAG = 0  
         @pTAG.@pTagDisk.FirstLookupNode = NextNode
         @pTAG.LookupNodeNum   = 0        
         @pTAG.LookupNodePos   = 0        
         @pTAG.RegularNodeNum  = 0        
         @pTAG.RegularNodePos  = 0        
         MemString @pTAG.zLastMoveKey, ""
         @pTAG.nLastMoveRecNum = 0

         errcode = ctx_PutNode_Internal( pBTX, NextNode, VarPtr(LookupNode) ) 
         If errcode Then GoTo ExitOut
         
         Incr NextNode
         
         pTAG = @pTAG.pNextTAG
      Loop
         
      ' Save the modified index header to disk
      errcode = ctx_PutNode_Internal( pBTX, 1, VarPtr(@pBTX.BTH) ) 
      If errcode Then GoTo ExitOut

         
      ' Chop the index off. It should now only have the header node and a
      ' Lookup node for each TAG.
      nRecOff = (@pBTX.BTH.TotalNodes * SizeOf(INDEX_REGULAR_NODE_TYPE)) + 1

      errcode = ctx_SetEndOfFile_Internal( @pBTX.hFile, nRecOff, %FALSE )
      If errcode Then GoTo ExitOut


      pBTX = @pBTX.pNextBTX
      
   Loop

   
ExitOut:
   Function = errcode
   
End Function






