LZLE List Engine with user friendly powerfull syntax - BETA 0.997a

User projects written in or related to FreeBASIC.
Post Reply
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha1 Frozen (Latest FIX 30/04)

Post by Lost Zergling »

New release Alpha 2 is ready, updated here https://freebasic.net/forum/viewtopic.php?f=8&t=26533
Alpha 1 is now outdated. This post is an archive of previous code. 1/2.
Alpha 1 Bugged on an optimization algo : keys not properly set in some cases.
Replace "If pFirstNode<>pFirstFIRSTNode Then" by "If pFirstNode<>pFirstFIRSTNode And 1=0 Then" to desactivate optimization algo

Code: Select all

' NOTICE : Thank you to remove first single quote on the line below once you accepted the licence.
' /'   In case redistribution of SOURCES you may ensure to reactivate the acceptance of the license. This notice may be anywhere in source code till licensed user is aware it exists.
CONST PRODUCT_LIC =_
"_______________________________________________________________________________" & chr(10) &_
"  LZListsEngine/ListsVM by Etienne Carfagnini - contact:etienne.carfa@gmail.com" & chr(10) &_
"  Bd Henri Barbusse 92700 Colombes France 01 46 49 99 02" & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  This Freeware/Openware licence specify the rights to use the software" & chr(10) &_
"* Distribution of derivating software : " & chr(10) & "  The information access to the original software must be guaranteed to" & chr(10) & "  developers and users (https://freebasic.net/forum/ or alternative mentionned)" & chr(10) &_
"* Right to use the software and its derivating : 2 options : " & chr(10) & " >OPTION 1 (Openware) :"  & chr(10) & "  The software is free for any use." & chr(10) &_
"  'LZLE Openware licence' is mentionned in licence contributors." & chr(10) &_
"  The software must be compiled using any official GPL FreeBasic Compiler." & chr(10) & "  (https://freebasic.net/forum/viewforum.php?f=1)" & chr(10) &_
"  Plattform (or virtual) using the software is open & compliant with FreeBasic." & chr(10) &_
" >OPTION 2 (Freeware):"  & chr(10) & "  The software is free for any use except the following limitation as to its"  & chr(10) & "  fields of application : not for use on virtual machine or on virtual server." & chr(10) &_
"  'LZLE Freeware licence' is mentionned in licence contributors." & chr(10) &_
"* Apart from the restrictions of use (options 1 and 2) which are not compatible"  & chr(10) & "  with the rights of uses specified in clause 5.1, the legal clauses whenever"  & chr(10) &_
"  compatible will be those specified by the CeCILL-C license"  & chr(10) & "  ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )" & chr(10) &_
"  Disclaimer :"  & chr(10) & "  This licence refers to CeCILL-C but is NOT a CeCILL-C because the right to"  & chr(10) & "  use the software with no restriction is limited to the FreeBasic ecosystem." & chr(10) &_
"  This because it aims to be an extension of the language instructions set."  & chr(10) &_
"  LZLE (instruction set architecture,coding style) is dedicated to FreeBasic."  & chr(10) &_
"  This notice constitutes a whole that must be present in the source code." & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  Cette licence Freeware/Openware precise les droits a utiliser le logiciel" & chr(10) &_
"* Distribution de logiciels derives :" & chr(10) & "  L'acces informatif au logiciel original doit etre garanti aux" & chr(10) & "  developpeurs et aux utilisateurs (https://freebasic.net/forum/ ou autre)." & chr(10) &_
"* Droit d'utiliser le logiciel et ses derives : 2 options : " & chr(10) & " >OPTION 1 (Libre) :"  & chr(10) & "  Le logiciel est gratuit pour toute utilisation." & chr(10) &_
"  'LZLE licence Openware' est mentionne dans les contributions." & chr(10) &_
"  Le logiciel doit etre compile en utilisant n'importe quel compilateur GPL" & chr(10) & "  FreeBasic 'officiel' (https://freebasic.net/forum/viewforum.php?f=1)" & chr(10) &_
"  La plate-forme d'execution du logiciel est ouverte et compatible FreeBasic." & chr(10) &_
" >OPTION 2 (Gratuiciel) :"  & chr(10) & "  Le logiciel est gratuit pour tout usage sauf la limitation suivante quant a"  & chr(10) & "  son champs d'application : pas d'utilisation sur machine ou serveur virtuel." & chr(10) &_
"  'LZLE licence Freeware' est mentionne dans les contributions." & chr(10) &_
"* En dehors des restrictions d'utilisation (options 1 et 2) lesquelles ne sont "  & chr(10) & "  pas compatibles avec les droits d'utilisation prevus a la clause 5.1, les"  & chr(10) &_
"  clauses applicables seront celles compatibles specifiees par la licence"  & chr(10) & "  CeCILL-C ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-fr.txt )" & chr(10) &_
"  Avertissement :"  & chr(10) & "  Cette licence fait reference a la licence CeCILL-C mais n'en est PAS une car"  & chr(10) & "  le droit a utiliser librement le logiciel est limite a l'ecosysteme FreeBasic" & chr(10) &_
"  Ce moteur de liste a jeu d'instructions est dedie au langage FreeBasic" & chr(10) &_
"  Cette notice constitue un tout lequel doit etre present dans le code source." & chr(10) &_
"_______________________________________________________________________________"
Dim k As String
Print PRODUCT_LIC : Print
Print "Please press 'Y' (Yes) to accept the licence or Esc to abort"
Print "Merci d'appuyer sur 'O' (Oui) pour accepter la licence ou echap pour annuler"
Do : k = Inkey : Select Case k : Case "Y" : Exit Do : Case "y" : Exit Do : Case "O" : Exit Do : Case "o" : Exit Do : Case Chr(27) : System : End Select : Loop
Print "Removing first single quote on line 2 in source code will activate the licence" : Print "Retirer la premiere simple quote en ligne 2 du code source activera la licence" : Print "Thank you for chosing this software - Merci d'avoir choisi ce logiciel" : Print
'/ ' END NOTICE

CONST RUP_COLS=1 : CONST MAX_COLS=5 ' Le nombre maximal de clefs pouvant être utilisées sur la MEME liste start=0
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4)

Type ListContainer 'Data Segment Level
    Dim str_tag_C(RUP_COLS+1 to MAX_COLS-1) As String
    Dim str_item as String : Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag(0 to RUP_COLS) As String : Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode : Dim BranchCount As uInteger=0
End Type
Type ListContext ' Branch context Level   
    Dim  As ListNode Ptr pNode, pFirstNode, pLastNode : Dim As String LcHashTag : Dim  As uInteger  uCount : Dim As uByte bLcHashLen
End Type

Type List
    Declare Constructor() : Declare Destructor()     
    Private:
    Dim  As ListContext Lcontext(0 to MAX_COLS-1), Tracks(0 to MAX_COLS-1)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake   
    Dim As String sSearchTag, sLatestHTag
    Dim As uLONG uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt : Dim zStringLen as uByte=80
    Dim uTag As Byte=0 : Dim bSearchRes As Byte=0 : Dim bRHByPass As Byte=0 : Dim bHashStepRev As Byte=0 : Dim bfStepZero As Byte=0 : Dim bTrackingMethod As Byte=0 : Dim bTracking As Byte=0 : Dim bHTMethod As Byte=0
    Dim bNFmethod As Byte=1 : Dim bRHmethod As Byte=-1 : Dim bHashLen As uByte=1  : Dim bAutoCursor As Byte=1 : Dim bSeekMethod As Byte=2 : Dim bBranchCountDown As Byte=0 : Dim  bPickReduce As Byte=0
    Declare Property AllowCake() As ListNode Ptr                      ' Cooking here
    Declare Property AllowPanCake() As ListContainer Ptr          ' No comment
    Declare Property Flat() As uByte                                            ' Détruit une arborescence à partir du pointeur courant (pNode)
    Declare Property AllFlat() As uByte                                        ' Destroy a hierarhical list to a flat list
    Declare Property GarbageCollector() As uInteger                  ' All elements in root list (except garbaged & Flat List entry are send to GarbageCollector
    Declare Property Branch() As Byte                                        ' Descend dans la liste enfants, creation de nouvelles entrées
    Declare Property UpLevel() As Byte                                      ' Revient à la liste parente   
    Declare Property NodeRecycle() as Byte                              ' Supression en décalé (NodeFlat)
    Declare Property NodeRecycle2() as Byte                            ' Supression en décalé (RestoreHash)
    Declare Property RootPrivate As Byte                                   ' Accès direct rapide à la racine
    Declare Property AllOfPrivate As uInteger
    Declare Property FlatStack(uB as uByte) As Byte                 ' Construction de la Flat List avec retour à la racine(0) ou accès à la flat liste (1)
    Declare Property BCountDown(i As Byte) As Byte                ' CountDown calculation   
    Declare Property TrackCompute As Byte
    Declare Property ValPrivate(str_Value As String) As Byte
    Declare Property ValPrivate As String
    Public:
    'Special features - Private declared Public   
    Declare Property GiveBranch As ListNode Ptr
    Declare Property GiveFlat As ListNode Ptr
    Declare Property GiveGarbage As ListNode Ptr
    Declare Property GivePanCake As ListContainer Ptr
    Declare Property GiveLastPanCake As ListContainer Ptr
    Declare Property GivePanCakeCount As uInteger
    'Flat control
    Declare Property Tag(str_Tag As String) As Byte                 ' Create a new ListNode with Key=str_Tag OR retrieve position of an existing Tag
    Declare Property Tag As String                                            ' Return current Tag value in a list =Tag(0)
    Declare Property Tag(iTag As Integer) As String                  ' Return current Tag value of the specified entry in array
    Declare Property HasTag(str_Tag As String) As Byte           ' Return 1 if Tag exists
    Declare Property BlindTag(str_Tag As String) As Byte          ' Create a new ListNode with Key=str_Tag at end of the list
    Declare Property RwTag(s_Tag As String) As Byte               ' Rewrite Tag Value of current Node : if current node is Hashed, just rewrite HashTag Value not effective Key value
    Declare Property RwTag1(s_Tag As String) As Byte                ' Rewrite Tag Value(1)
    Declare Property RwTag2(s_Tag As String) As Byte                ' Rewrite Tag Value(2)
    Declare Property RwTag3(s_Tag As String) As Byte                ' Rewrite Tag Value(3)
    Declare Property RwTag4(s_Tag As String) As Byte                ' Rewrite Tag Value(4)
    Declare Property ColTags As Byte                                       ' Renvoie le numéro de la colonne de tag active   
    Declare Property SeekMethod(i as Byte) As Byte                 ' Method for Tag(string), HasTag(string), HashTag(string), HasHashTag and HasKey: 1(default)=seek from First to Last | 2: seek from Lastnode to firstNode | 0 :seek from currentnode to last node (Flat multikeys)
    Declare Property ColTags(i as Byte) As Byte                        ' Définie la colonne de tag active de 0 à MAX_COLS, par défaut 0
    Declare Property AllOf As uInteger                                       ' Return number of node in  considered Flat List (root or branch), set position to the first node of current branch
    Declare Property Count As uInteger                                     ' Return current node Count of considered Flat List
    Declare Property First As Byte                                              'Set current node to first node considering flat list (root or branch)   
    Declare Property Last As Byte                                              'Set current node to Last node considering flat list (root or branch)       
    Declare Property Val(str_value As String) As Byte                ' Assign a string (+50 len) to the current node that is identified by a Tag
    Declare Property Val As String                                             ' Return current node string datas   
    Declare Property ValTag(str_value As String) As String        ' Considering current Flat list (root or branch as a flat list) return string data identified by Key=str_Tag
    Declare Property fStep As Byte                                            ' FOR EACH - While MyList.fStep : .. : Wend Jump to next node till current flat list end
    Declare Property fStepRev As Byte                                     ' FOR EACH - Idem fStep Jump to previous node till current flat list reach firstnode
    Declare Property bStep As Byte                                           ' FOR NEXT - For i=1 to MyList.AllOf : MyList.bStep : ..... : Next i    -> Jump to next node (NO CHECK)
    Declare Property BlindStep As Byte                                     ' FOR EACH - While MyList.BlindStep : .. : Wend -And- FOR NEXT - For i=1 to MyList.AllOf : MyList.BlindStep : ..... : Next i  Jump to next node  (check)   
    Declare Property BlindStep(i As Integer) As Byte                  ' Jump to +/-n nodes BlindStep(0) equiv Last : goto LastNode  (NO CHECK)
    Declare Property fMove(i As Integer) As Byte                      ' Move a node +/- n positions
    'Hash control handling
    Declare Property Root As Byte                                           ' Check/Restore List integrity & set cursor to First node of root flat list - Shall be called before HashStep or After NodeFlat or RestoreHash
    Declare Property FlatStack As Byte                                    ' Flat List Access : use it before RestoreHash
    Declare Property RootNode As Byte                                  ' Set cursor to Root node of root flat list
    Declare Property EndNode As Byte                                   ' Set cursor to the last logical node  ( = While MyList.HashStep : Wend ) which is the last node of the last branch of last root flat node
    Declare Property HashStep As Byte                                   ' FOR EACH - recursive  parse property : syntax : While MyList.HashStep=1 : ... : Wend
    Declare Property HashStepRev As Byte                            ' FOR EACH - idem HashStep
    Declare Property KeyStep As Byte                                      ' FOR EACH - While MyList.KeyStep=1 : ... : Wend idem HashStep but show only Keys tagged by user, not the tree structure
    Declare Property KeyStepRev As Byte                               ' FOR EACH - idem KeyStep
    Declare Property HashTag(str_Tag As String) As Byte       ' Build a hash Key on str_Tag, Return 1 if already exits otherwise return 0
    Declare Property HashSort(ub as Byte) as Byte
    Declare Property HashTag As String                                  ' Return Hash key value of current node
    Declare Property HasHashTag(str_Tag As String) As Byte ' Return 1 if str_Tag is a hash key otherwise return 0
    Declare Property HasKey(str_Tag As String) As Byte          ' Idem HasHashTag Return 1 only for values specified with HashTag (not all cascaded index values)
    Declare Property HashLen(bHashLen As uByte) As Byte  ' Longueur des clefs en cascade
    Declare Property NFmethod(i As Byte) As Byte                  ' Determine le fonctionnement de NodeFlat : NFmethod=-1 node=>GarbageCollector  NFmethod=0 node=>FlatList sauf parents reliquataires NFmethod=1 node=>FlatList même les nodes parents contenant toujours des dépendances
    Declare Property NFrecursive(i As Byte) As Byte
    Declare Property NodeFlat As Byte                                   ' Déréférence une arborescence de clefs (un HashTag), et traite les données en conséquence
    Declare Property RHmethod(i As Byte) As Byte                 ' Determine le fonctionnement de RestoreHash par rapport aux doublons : RHmethod=-1 : Hashnode->GarbageCollector  / RHmethod=0 : no swap / RHmethod=1 : Hashnode->FlatList
    Declare Property RestoreHash As Byte                             ' Envoi un node de la Flat List en Hash List (réindexation)
    'Hash Control - special
  '  Declare Property HashMap(str_Tag() As String Ptr) As Byte ' to do
  '  Declare Property HashMap As Byte  ' to do
    'Flow control
    Declare Property BranchCountDown(i As Byte) As Byte     ' 1/0 Activate(1) or desactivate(0) BranchCountDown, default 0
    Declare Property BranchCount As uInteger                        'Return Branch Count
    Declare Property Up As Byte                                              'idem UpLevel
    Declare Property Down As Byte                                         'idem Branch but prevent from creating an orphan sublist entry
    Declare Property AutoCursor(i As Byte) As Byte                 'Method for HasTag(string), HasHashTag and HasKey:  1(default)=move current to found on success (HasHashTag), 0=do nothing current node is unchanged, 2=move current to found on success (HasKey), 3=move on partial success
    Declare Property HoldBack As Byte
    Declare Property HoldBack(i As Byte) As Byte
    Declare Property TrackStep As Byte                                ' -SELECTIVE- FOR EACH - While MyList.TrackStep=1 : ... : Wend : selective PARSE only Keys marked for tracking by HoldBack
    Declare Property Track As Byte
    Declare Property Track(i As Byte) As Byte
    Declare Property TrackSet As Byte
    Declare Property TrackSet(i As Byte) As Byte
    Declare Property IsTracked As Byte
    Declare Property TrackMethod(by As Byte) As Byte       ' MyList.TrackMethod(0)=might be faster / MyList.TrackMethod(1)=more secure
    Declare Property Aside As Byte                                      ' Memorise ListNode ptr dans le pointeur n°0
    Declare Property Aside(i As Byte) As Byte                       ' Memorise ListNode ptr dans le pointeur n°i
    Declare Property Recover As Byte                                 ' Repositionne l'élément courant de la liste sur celui mémorisé par Take, si cet élément existe toujours, sinon renvoie False
    Declare Property Recover(i As Byte) As Byte                  ' Repositionne l'élément courant de la liste sur celui mémorisé par Take(i)
    'Memory management
    Declare Property FlatCount As uInteger                         ' Return number of values stored in Flat List
    Declare Property GarbageCount As uInteger                 ' Return number of nodes available in garbage collector
    Declare Property ContainerCount As uInteger                ' Return number of nodes container available in hidden garbage collector
    Declare Property NodeCount As uInteger                      ' Return number of nodes including not visible ones
    Declare Property GarbageFlat As Byte                            'Send all Flat List to GarbageCollector
    Declare Property Recycle As uInteger                            'AllFlat+GarbageCollector : détruit une arborescence et envoi tout en GarabgeCollector - do NOT garbage protected flat list
    Declare Property DropAll As uInteger                              'Remove all elements in list   
    Declare Property Destroy As Byte                                   'Manual destructor
    'List Data Exchange
    Declare Property SnatchBelow(pList As List) As Byte        'Snatch a whole branch from another List Below current node
    Declare Property Snatch(pList As List) As Byte                 ' Snatch a whole branch from another List to next node
    Declare Property FlatSnatch(pList As List) As Byte            'Target's Flat list is transfered to current list
    Declare Property GarbageSnatch(pList As List) As Byte    'Target's Garbage Collector is transfered to current list
    'Debug
    Declare Property NextNode As String
  '  Declare Property PrevNode As String
End Type
' to do : HashMap / Tris / SmartPatterns (?)  /
' to do : test++%TrackSet / BranchUp /
' BUGs :
Property List.NextNode As String : Dim str_tmp as string="-" : If pNode->pNext<>0 Then : this.Aside : pNode=pNode->pNext : str_tmp= "next tag=" & pNode->Tag(0) & " & next hashtag=" & this.HashTag : this.Recover : Return str_tmp : End If : End Property
'Property List.PrevNode As String : Dim str_tmp as string="-" : If pNode->pPrev<>0 Then : this.Aside : pNode=pNode->pPrev : str_tmp= " prev tag=" & pNode->Tag(0) & " & prev hashtag=" & this.HashTag  & "  branch=" & Str(pNode->pBranch) : this.Recover : Return str_tmp : End If : End Property

'==========================================================================================CONSTRUCTOR & DESTRUCTOR  :  this.pFirstNode->pBranch->pBranchLastNode=0
Constructor List
    pFlatRoot = CAllocate(Len(ListNode)) : pNode = CAllocate(Len(ListNode)) ' Moment angulaire(petite masse)
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 : this.pPanCakeGarbage=cAllocate(Len(ListContainer)) : pPanCakeGarbage->pNextContainer=pPanCakeGarbage ' Moment Angulaire(petite masse)
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag(0) = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT
    this.uNodeCOUNT+=2 : this.Root
End Constructor
Destructor List : this.Destroy : End Destructor

'==========================================================================================TYPE LIST PRIVATE PROPERTIES
Property List.AllowCake As ListNode Ptr ' This.Vralloc
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext ' uGarbCt>1 ' If pTemp<>0 Then : If pTemp->pNext=0  Then  : pTemp=pGarbage : pTemp=CAllocate(Len(ListNode)) : this.uNodeCOUNT+=1 :  Return pTemp : End If  : End If
    If pTemp<>pGarbage And pTemp<>0  Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : pTemp->pBranch=0 : This.uGarbCt-=1 : 'pTemp->pNext=0 : pTemp->pPrev=0 :
    Else : pTemp=CAllocate(Len(ListNode)) : this.uNodeCOUNT+=1 : this.pLastLASTNode=pTemp ' Moment Angulaire(petite masse)         
    End If : Return pTemp
End Property
Property List.AllowPanCake As ListContainer Ptr
    Dim pPanTemp As ListContainer Ptr : dim uB As uByte
    If pPanCakeGarbage->pNextContainer<>pPanCakeGarbage Then
        pPanTemp=pPanCakeGarbage->pNextContainer : pPanTemp->str_item="" : For uB=RUP_COLS+1 To MAX_COLS-1 : pPanTemp->str_tag_C(uB)="" : Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else : pPanTemp=cAllocate(Len(ListContainer)) ' : pPanTemp->str_item=""  ' Moment Angulaire(petite masse)
    End If : Return pPanTemp
End Property

Property List.Flat As uByte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext       
    If pLocalMove=pLastLASTNode Then : pLastLASTNode=pLastLASTNode->pPrev : End If : this.NodeRecycle
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode= this.pGarbage->pNext : Else : pNode= this.pFirstNode->pNext : End If
    If pNode <>0 Then
        Do
            If pNode->Tag(0)<>LIST_RES And pNode->pBranch<>0 Then   
                pNode->pNext->pPrev=pNode->pBranch->pBranchLastNode : pNode->pBranch->pBranchLastNode->pNext=pNode->pNext
                pNode->pNext=pNode->pBranch : pNode->pBranch->pBranch=0 : pNode->pBranch=0
                pNode->pNext->pPrev=pNode : pNode->pNext->Tag(0)=LIST_DEL : pNode->pNext->pBranchLastNode=0
            Else : If this.pNode->pNext<>0 Then : this.pNode=this.pNode->pNext : End If
            End If
        Loop Until pNode=this.pLastLASTNode Or pNode=pWhyteMove
    End If : this.RootPrivate
    Return 1
End Property
Property List.AllFlat As uByte : this.Root : Return this.Flat : End Property
Property List.GarbageCollector As uInteger
    Dim pTemp1 as ListNode Ptr : Dim pTemp2 as ListNode Ptr : Dim NbCollected As uInteger=0 : Dim iLong As uInteger=0
    If pGarbage->ListData<>0 Then : pGarbage->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pGarbage->ListData : pGarbage->ListData=0 : uContainerGarbCt+=1 : End If
    This.RootPrivate : pTemp1=this.pGarbage->pNext : If pTemp1=0 Then : Return 0 : End If
    While pTemp1->pNext<>0       
        pTemp1->Tag(0) = LIST_DEL : pTemp1->Tag(1)=""
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If       
        NbCollected +=1 : pTemp1=pTemp1->pNext : iLong+=1
    Wend
    If NbCollected>0 Then : This.uGarbCt+=NbCollected : uCount=2 : this.pFirstNode->BranchCount=this.uCount : pLastNode=pTemp1 : If pFirstNode=pFirstFIRSTNode Then : pLastLASTNODE=pTemp1 : End If : End If   
    This.RootPrivate : pGarbage=pLastNode->pPrev : pTemp1=pNode : pNode=pGarbage : this.Val(LIST_DEL) : pNode=pTemp1 :       
    Return NbCollected
End Property

Property List.Branch As Byte
    Dim pTemp As ListNode Ptr :  Dim pTemp1 As ListNode Ptr   
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp = this.pNode
    If this.pNode->pBranch=0 Then ' this.NewHash(this.pNode)
        pTemp1 = this.pLastNode : this.uCount+=1 : pTemp1->pNext = this.AllowCake 'And eat it
        pTemp1->pNext->pPrev = pTemp1 : pTemp1->pNext->Tag(uTag) = LIST_RES
        pTemp1 = pTemp1->pNext : this.pLastNode = pTemp1 : pNode=pTemp1  ' this.BlindTag(LIST_RES) :
        this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp
        pTemp->pBranch=this.pNode : pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
        this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : this.bSearchRes = 0 : Return 0
    Else 'Branche déjà créée
        this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
        this.pLastNode = this.pNode->pBranch->pBranchLastNode         
        this.pNode = this.pNode->pBranch : this.bSearchRes = 0 : Return 1
    End If   
End Property

Property List.UpLevel As Byte   
    If this.pFirstNode->pPrev = 0 Then : Return 0 : End If
    If this.pFirstNode->pBranch <> 0 Then ' Retour node de départ pour faciliter un parcours éventuel
        this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        this.pFirstNode = this.pFirstNode->pPrev : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode         
        this.bSearchRes = 0 ': this.sSearchTag = ""
        Return 1
    Else : Return 0
    End If               
End Property

Property List.NodeRecycle as Byte
    If pLocalMove<>0 Then 'pLocalMove est un node à suppression décalée       
        pLocalMove->pPrev=this.pFlatRoot : pLocalMove->pNext=this.pFlatRoot->pNext : pLocalMove->Tag(0)=LIST_DEL : pLocalMove->pBranch=0 : pLocalMove->Tag(1)=""
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pLocalMove->ListData : pLocalMove->ListData=0 : uContainerGarbCt+=1 : End If
        this.pFlatRoot->pNext->pPrev=pLocalMove : this.pFlatRoot->pNext=pLocalMove : this.uGarbCt+=1
        pLocalMove = 0       
    End If
    Return 1
End Property
Property List.NodeRecycle2 as Byte
    If pLocalRoot<>0 Then 'pLocalRoot est un node LIST_RES             
        pLocalRoot->pPrev=this.pFlatRoot : pLocalRoot->pNext=this.pFlatRoot->pNext : pLocalRoot->Tag(0)=LIST_DEL
        this.pFlatRoot->pNext->pPrev=pLocalRoot : this.pFlatRoot->pNext=pLocalRoot : This.uGarbCt+=1
        pLocalRoot->pBranch->pBranch=0 : pLocalRoot->pBranch->pBranchLastNode=0 : pLocalRoot->pBranch->BranchCount=0 :
        pLocalRoot->BranchCount=0 : pLocalRoot->pBranch=0 : pLocalRoot = 0
    End If
    Return 1
End Property

Property List.RootPrivate As Byte   
    this.AllOfPrivate : While this.pFirstNode->pBranch <> 0  : this.UpLevel : Wend   
    this.pFirstNode = this.pFirstFIRSTNode : this.bSearchRes = 0 : this.sSearchTag = ""
    this.pNode = this.pGarbage
    Return 1   
End Property
Property List.AllOfPrivate As uInteger
    this.pNode = this.pFirstNode
    If this.pFirstNode=this.pFirstFIRSTNode Then           
        this.pNode = this.pGarbage
        If pWhyteMove<>0 And pWhyteMove<>pLastNode Then  'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc
            If pWhyteMove->pNext<>0 Then : pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode :  End If     
            pLastNode=pWhyteMove : pLastNode->pNext=pFirstFIRSTNode '0
        End If   
    End If : Return this.Count
End Property

Property List.FlatStack(uB As Ubyte) As Byte
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    Dim pTemp1 As ListNode Ptr
    This.RootPrivate : this.pNode=this.pFlatRoot : this.Branch
    If this.pLastNode=this.pFlatRoot->pBranch Then
        If this.pEndFlat<>0 Then : this.pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=this.pFlatRoot->pBranch : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If
    ElseIf this.pLastNode<>this.pEndFlat Then           
        If this.pEndFlat<>0 Then
            this.pEndFlat->pPrev->pNext=this.pEndFlat->pNext : this.pEndFlat->pNext->pPrev=this.pEndFlat->pPrev
            this.pEndFlat->pPrev=this.pLastNode : this.pLastNode->pNext=this.pEndFlat : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If                       
    End If     
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If uB=0 Then : this.UpLevel : End If : this.AllOfPrivate
    Return 1
End Property
Property List.BCountDown(i As Byte) As Byte : Dim pTemp As ListNode Ptr=pFirstNode : While pTemp->pPrev<>0 : If pTemp->pBranch<>0 Then : pTemp->pBranch->BranchCount+=i : End If : pTemp=pTemp->pPrev : Wend : Return 1 : End Property
Property List.TrackCompute As Byte
    Dim As ListNode Ptr pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
    pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : Return 1
End Property
Property List.ValPrivate(str_value As String) As Byte : If this.pValTmp->ListData=0 Then : this.pValTmp->ListData=this.AllowPanCake : End If : this.pValTmp->ListData->str_item=str_value : Return 1 : End Property
Property List.ValPrivate As String : If this.pValTmp->ListData=0 Then : Return "" : End If : Return this.pValTmp->ListData->str_item : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES destination is PRIVATE USE
Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2, pTemp3
    bfStepZero=0
    If pNode=pLocalMove And pLocalMove->Tag(0)=LIST_RES Then : pNode=pNode->pNext
    ElseIf pNode=pWhyteMove Then : If pNode=pLastNode Then : Return 0 : Else : pTemp1=pNode->pNext : This.Root : pNode=pTemp1 : End If
    ElseIf pNode->Tag(0)=LIST_DEL Or pNode=pFlatRoot Then : Return 0 ' : End If
    ElseIf pNode=pFirstNode And pNode->pBranch<>0 Then : this.BlindStep : this.UpLevel : bfStepZero=1 : End If
    If bBranchCountDown=1 Then : this.BCountDown(-pNode->BranchCount) : End If : This.NodeRecycle
    pTemp1=pNode : pTemp2=pNode->pPrev : pTemp3=pNode->pNext
    If pLastNode=pFirstNode->pNext And pFirstNode<>pFirstFIRSTNode Then
        this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : this.UpLevel : this.NodeRecycle2 : bfStepZero=1 : Return pTemp1
    Else : pNode->pPrev->pNext=pNode->pNext : pNode->pNext->pPrev=pNode->pPrev : uCount-=1 : pFirstNode->BranchCount-=1
    End If
    If pTemp1=pLastNode Then : pLastNode=pTemp1->pPrev : pTemp1->pNext=0 : End If
    pNode=AllowCake : pLocalMove=pNode : pLocalMove->pPrev=pTemp2  : pLocalMove->pNext=pTemp3 : pLocalMove->Tag(0)=LIST_RES
    Return pTemp1
End Property

Property List.GiveFlat As ListNode Ptr   
    Dim As ListNode Ptr pTemp1, pTemp2
    If pFlatRoot->pBranch=0 Then : Return 0 : End If         
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Or pFlatRoot->pBranch->pNext=pFlatRoot->pBranch  Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev : If pTemp2=0 Or pTemp1=pTemp2 Then : Return 0 : End If
    pTemp1->pBranch=pTemp2 : pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=pFlatRoot->pBranch
    pTemp1->BranchCount=pFlatRoot->pBranch->BranchCount : uNodeCOUNT-=pFlatRoot->pBranch->BranchCount 'this.FlatCount :
    this.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If  ' this.FlatStack : uCount=0
    Return pTemp1   
End Property

Property List.GiveGarbage As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2
    If uGarbCt<2 Then : Return 0 : End If : pTemp1=pFlatRoot->pNext : pTemp2=pGarbage->pPrev : If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext=pGarbage : pGarbage->pPrev=pFlatRoot : pTemp1->pBranch=pTemp2 : pTemp1->BranchCount=uGarbCt
    uNodeCOUNT-= uGarbCt : uGarbCt=0
    Return pTemp1
End Property
Property List.GivePanCake As ListContainer Ptr
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2
    If uContainerGarbCt<2 Then : Return 0 : End If : pLastPanCake=0
    pPanTemp1=pPanCakeGarbage->pNextContainer : pPanTemp2=pPanTemp1
    While pPanTemp2->pNextContainer<>pPanCakeGarbage : pPanTemp2=pPanTemp2->pNextContainer : Wend : pPanTemp2->pNextContainer=0 : pLastPanCake=pPanTemp2
    pPanCakeGarbage->pNextContainer=pPanCakeGarbage : uContainerGivenCt=uContainerGarbCt : uContainerGarbCt=0
    Return pPanTemp1
End Property
Property List.GiveLastPanCake As ListContainer Ptr : Return pLastPanCake : End Property
Property List.GivePanCakeCount As uInteger : Return this.uContainerGivenCt : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLAT CONTROL
Property List.Tag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer Ptr
    If this.sSearchTag = str_Tag Then
        If this.bSearchRes=1 Then
            this.pNode = this.pSearchNode : Return 1 'pNode
        Else
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->Tag(uTag) = str_Tag ' pTemp->pNext->ListData = item :
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            this.pNode = pTemp : Return 0
        End If       
    Else
        If this.bSeekMethod=1 Then : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then : pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
        Else
            pTemp = this.pNode : If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        End If
        If pTemp->Tag(uTag)<>str_Tag then ' New node
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->ListData = item : pTemp->pNext->Tag(uTag) = str_Tag
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            If pFirstNode=pFirstFIRSTNode And pWhyteMove<>0 And pWhyteMove<>pLastNode Then
                If pWhyteMove->pNext<>0 Then   'Changement de fonctionnement - Patch de compatibilité - dernier node logique à blanc
                    pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode : pLastNode=pWhyteMove : pLastNode->pNext=0
                End If
            End If : this.pNode = pTemp : Return 0
        End If   
    End If
    this.pNode = pTemp : Return 1 'pTemp
End Property

Property List.Tag As String
    If uTag<=RUP_COLS Then : Return this.pNode->Tag(uTag)
    ElseIf pNode->ListData=0 Then : Return ""
    Else : Return pNode->ListData->str_tag_C(uTag)
    End If
End Property
Property List.Tag(i As Integer) As String
    If i<=RUP_COLS Then : Return this.pNode->tag(i) : Else : If pNode->ListData<>0 Then : Return pNode->ListData->str_tag_C(i) : Else : Return "" : End If : End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag   
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
    Else
        pTemp = this.pNode : If pTemp=0 Then :  pTemp = this.pFirstNode : End If
        If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag(uTag) = str_Tag Then
        this.pSearchNode=pTemp : this.bSearchRes=1 : If this.bAutoCursor=1 Then : pNode=pTemp : End If : Return 1
    Else : this.bSearchRes = 0 : Return 0 : End If   
End Property

Property List.BlindTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = str_Tag
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte : If uTag<=RUP_COLS Then : this.pNode->tag(this.uTag)=s_Tag : Return 1 : Else : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(uTag)=s_Tag : Return 1 : End If : End Property
Property List.RwTag1(s_Tag As String) As Byte : this.pNode->tag(1)=s_Tag : Return 1 : End Property
Property List.RwTag2(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(2)=s_Tag : Return 1 : End Property
Property List.RwTag3(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(3)=s_Tag : Return 1 : End Property
Property List.RwTag4(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(4)=s_Tag : Return 1 : End Property

Property List.ColTags As Byte : Return(this.uTag) : End Property
'Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > ubound(this.pNode->Tag) then : this.uTag=Ubound(this.pNode->Tag) : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property
Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property

Property List.SeekMethod(i as Byte) As Byte : If i=0 Or i=1 Or i=2 Then : this.bSeekMethod=i : Return 1 : Else : Return 0 : End If : End Property
Property List.AllOf As uInteger
    Dim pContextRetour As ListContext   
    Dim  As ListNode Ptr pTemp, pTemp2 : If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If
    If pFirstNode=pFIRSTFIRSTNode Then : If pLastNode<>pWhyteMove Then : this.Root : End If : End If
    this.NodeRecycle : this.NodeRecycle2
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.AllOfPrivate
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : uCount=pContextRetour.uCount
    pNode=AllowCake : pLocalMove=pNode
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode->pNext=pGarbage->pNext : Else : pNode->pNext=pFirstNode->pNext : End If
    If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    Return this.Count
End Property
Property List.Count As uInteger : If pWhyteMove=pLastNode And pFirstNode=this.pFirstFIRSTNode Then : Return this.uCount-1 : End If : Return this.uCount : End Property
Property List.First As Byte : If pFirstNode=pFirstFIRSTNode Then : pNode=pGarbage : Else : this.pNode=This.pFirstNode->pNext : End If : Return 1 : End Property
Property List.Last As Byte : this.pNode=This.pLastNode : Return 1 : End Property

Property List.Val(str_value As String) As Byte : this.pValTmp=this.pNode : this.ValPrivate(str_value) : Return 1 : End Property
Property List.Val As String : pValTmp=pNode : Return this.ValPrivate : End Property
Property List.ValTag(str_value As String) As String
    If bSearchRes=1 Then : If str_value=this.Tag(0) Then : pValTmp=pSearchNode : Return this.ValPrivate : End If
    ElseIf this.HasTag(str_value)=1 Then : pValTmp=pSearchNode : Return this.ValPrivate
    End If : Return("")
End Property

Property List.fStep As Byte : If pNode=pLastNode Or bfStepZero=1 Or pNode->pNext=pWhyteMove Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pNext : Return 1 : End If : End Property '
Property List.fStepRev As Byte : If pNode->pPrev=pFirstNode Or pNode->pPrev=pGarbage Or bfStepZero=1 Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pPrev : Return 1 : End If : End Property
Property List.bStep As Byte : this.pNode = this.pNode->pNext : Return 1 : End Property
Property List.BlindStep As Byte : If this.pNode->pNext<>0 Then : this.pNode = this.pNode->pNext : Return 1 : Else   : Return 0 : End If : End Property ' : Print "*Warning : list parse or count down error"
Property List.BlindStep(top As Integer) As Byte
    Dim As Integer i : Dim As Byte istep
    If top>0 Then : istep=1 : For i=1 To top step istep : this.pNode = this.pNode->pNext : Next i : ElseIf top = 0 Then : this.pNode = this.pLastNode : Return 1 : Else : istep=-1 : For i=-1 To top step istep : this.pNode = this.pNode->pPrev : Next i : End If
    Return 1
End Property
Property List.fMove(nbMove As Integer) As Byte
    Dim As ListNode Ptr pFirst, pTemp : Dim i As Integer=0
    If pFirstNode=pFirstFIRSTnode Then : pFirst=pGarbage : Else : pFirst=pFirstNode : End If
    If pNode=pLastNode Then : pLastNode=pNode->pPrev : Else : pNode->pNext->pPrev=pNode->pPrev : End If
    pNode->pPrev->pNext=pNode->pNext : pTemp=pNode
    If nbMove>0 Then : For i=0 To nbMove : If pNode<>pLastNode Then : pTemp=pTemp->pNext : End If : Next i     
    Else : For i=nbMove To 0 : If pTemp<>pFirstNode Then : pTemp=pTemp->pPrev : End If : Next i         
    End If
    If pTemp<>pLastNode Then : pTemp->pNext->pPrev=pNode : pNode->pNext=pTemp->pNext
    Else : If  pTemp->pNext<>0 Then : pNode->pNext=pTemp->pNext : End If : pLastNode=pNode
    End If
    pTemp->pNext=pNode : pNode->pPrev=pTemp
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - HASH CONTROL
Property List.Root As Byte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext   
    If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If :' this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    this.NodeRecycle : this.RootPrivate : this.NodeRecycle2 : bSearchRes=0 : pTemp2=0 : this.bHashStepRev=0
    'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc qui ne soit jamais 'flaté'
    If this.pWhyteMove<>0 Then               
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag(0)<>LIST_RES Then
            If pWhyteMove->pPrev<>0 Then : this.pWhyteMove->pPrev->pNext=this.pWhyteMove->pNext : End If
            If pWhyteMove->pNext<>0 Then :this.pWhyteMove->pNext->pPrev=this.pWhyteMove->pPrev : End If         
        End If       
    End If
    If pPanCakeGarbage=0 Then : pPanCakeGarbage=AllowPanCake : pPanCakeGarbage->pNextContainer=pPanCakeGarbage : End If
    If pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : this.Val(LIST_DEL) : pGarbage->pPrev=pFlatRoot
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If : this.pNode = pGarbage
    End If
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    this.FlatStack(0)
    'Corrections  - Patch de compatibilité - : pFlatRoot se balade, il faut le remettre au début -
    If pFlatRoot->pPrev<>0 Then : pFlatRoot->pPrev->pNext=pFlatRoot->pNext : End If : If pFlatRoot->pNext<>0 Then :  pFlatRoot->pNext->pPrev=pFlatRoot->pPrev : End If
    pFlatRoot->pPrev=this.pFirstFIRSTNode : pFlatRoot->pNext=this.pFirstFIRSTNode->pNext : If this.pFirstFIRSTNode->pNext<>0 Then : this.pFirstFIRSTNode->pNext->pPrev=pFlatRoot : End If : this.pFirstFIRSTNode->pNext=pFlatRoot
    'Changement de fonctionnement - Patch de compatibilité - pLastLAST devient dernier node LOGIQUE : on le remet à jour
    If this.pFirstFIRSTNode->pBranchLastNode<>0 Then
        pTemp=this.pFirstFIRSTNode->pBranchLastNode : While pTemp->pBranchLastNode<>0 And pTemp<>pTemp2 : pTemp2=pTemp : pTemp=pTemp->pBranchLastNode : Wend : this.pLastLASTNode=pTemp
    End If
    'NodeFlat+Restorehash nécessite la présence d'un dernier node fictif
    If this.pLastNode->Tag(0)<>"" Then : If pWhyteMove<>0 Then : this.AllOf  : Else : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : End If
  '  If this.pLastNode->Tag(0)<>"" Then : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If
    this.pNode=pGarbage : this.uCount=this.pFirstFIRSTNode->BranchCount : this.pLastLASTNode->pPrev->pNext=this.pLastLASTNode
    If this.pLastLASTNode->pNext->Tag(0)=LIST_RES Then : this.pLastLASTNode->pNext=0 : End If
  ' Option for .Root become compatible with Rev parse with no need to jump to Last node (List.Last)
    this.pNode=AllowCake : pNode->Tag(0)="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext
    If pLastNode=pWhyteMove Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    this.NodeRecycle2 : this.pFirstNode->BranchCount=this.uCount : this.pFirstNode->pBranchLastNode=this.pLastNode
    Return 1   
End Property

Property List.FlatStack As Byte : this.FlatStack(1) : this.AllOf : bSearchRes=0 : Return 1 : End Property
Property List.RootNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pFirstFIRSTNode : Return 1 : End Property
Property List.EndNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pLastLASTNode : Return 1 : End Property

Property List.HashStep As Byte
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount '
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If ' If pNode=pWhyteMove Then : Return 0 : Else : Return 1 : End If
    Wend : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

Property List.HashStepRev As Byte
    this.bHashStepRev=1   
    While this.pnode->pBranch <> 0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.AllOf : If this.pnode <> this.pFirstNode->pNext And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    While pFirstNode->pBranch<> 0
        pNode=pFirstNode->pBranch :' pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode :
        pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext  And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If
    Wend : Return 0
End Property
Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property

Last edited by Lost Zergling on Jun 11, 2018 14:10, edited 1 time in total.
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha1 Frozen (Latest FIX 30/04)

Post by Lost Zergling »

New release Alpha 2 is ready, updated here viewtopic.php?f=8&t=26533
Alpha 1 is now outdated. This post is an archive of previous code. 2/2.

Code: Select all

Property List.HashTag(str_Tag As String) As Byte
    Dim As ListNode Ptr pTemp,  pTemp02, pTemp03, pTemp04 : Dim Str_tmp As String
    Dim As uByte HadHashTag=1, istep=this.bHashLen, i=0, iLen=Len(str_tag), iLenStrTmp, iLenpNode, iLenCumul, IsLast=0       
    Dim As zString Ptr Listptemp=cAllocate(iLen+1), Listptemp2=Allocate(iLen+1), zp1, zp2, zp3=Allocate(1) ' * Alternative to Mid, left & right ==>+20-25% speed tested
    If bTracking=1 And bTrackingMethod=0 Then '  This.TrackCompute()       
        pTemp=pNode : While pTemp->Tag(0)<>LIST_RES And pTemp<>pGarbage : pTemp=pTemp->pPrev : Wend : If pTemp=pGarbage Then : pTemp=pFirstFIRSTNode : End If
        pFirstNode=pTemp : pLastNode=pTemp->pBranchLastNode : uCount=pTemp->BranchCount
    End If
    If pFirstNode<>pFirstFIRSTNode Then
        If pLatestHTag=pNode Then : Str_tmp=sLatestHTag
        Else
            pNode=pFirstNode->pNext : Str_tmp=this.HashTag :
            If Len(Str_tmp)>iLen+1 Then : Deallocate(Listptemp) : Listptemp=cAllocate(Len(Str_tmp)+1) : End If ': zp1=Listptemp+Len(Str_tmp)+1 : (*zp1)[0]=0 :
        End If
        *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
        *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=istep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
        If *Listptemp=*Listptemp2 Then' Very few fistfull of seconds / ' If Left(Str_tmp,istep)=Left(str_tag,istep) Then
       '    iLenpNode=iLen : While Len(str_tag)<Len(Str_tmp) : this.UpLevel : Str_tmp=Left(Str_tmp, Len(Str_tmp)-iLenpNode) : iLenpNode=Len(pNode->Tag(uTag)) : Wend       
            While Len(str_tag)<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag : Wend
            pNode=pFirstNode->pNext : iLenpNode=Len(pNode->Tag(uTag)) : iLenStrTmp=Len(Str_tmp) : i=1
            zp2=Listptemp2 : zp2+=iLenStrTmp : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,iLenStrTmp)
            While *Listptemp2<>Str_tmp ' Very few fistfull of seconds / ' While Left(str_tag, iLenStrTmp)<>Str_tmp
                zp1=Listptemp : zp1+=iLenStrTmp-iLenpNode : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,iLenStrTmp-iLenpNode)
                Str_tmp=*Listptemp ' Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode->BranchCount=uCount
                pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount : iLenpNode=istep
                zp2=Listptemp2 : zp2+=iLenStrTmp : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
            Wend : iLen=iLenCumul+istep : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode         
       End If
    End If
    If i=0 Then  '---------------- this.RootPrivate / this.AllOfPrivate
        While this.pFirstNode->pPrev<>0
            this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount
            this.pFirstNode->pBranchLastNode = this.pLastNode : this.pFirstNode = this.pFirstNode->pPrev       
            this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode                 
        Wend : this.pNode = this.pGarbage :
        pTemp02=pGarbage
    End If : iLenCumul=0
    *Listptemp=str_Tag : zp1=Listptemp ' * Alternative to Mid   
    For i=1 to Len(str_Tag) step istep
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid :  Str_tmp=Mid(str_Tag,i, istep)
        iLenCumul+=iStep
        If bHTmethod=0 Then
            If bSeekMethod=2 Then : pTemp = this.pLastNode : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
            Else : pTemp = pTemp02 : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
            End If       
        Else
            If bSeekMethod=2 Then
                pTemp = this.pLastNode : While ( pTemp->Tag(uTag)>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                If pTemp=pLastNode Then : IsLast=1 : End If
            Else           
                pTemp=pTemp02 : While (pTemp->Tag(uTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend
                If pTemp->Tag(uTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
            End If
        End If       
        If pTemp->Tag(uTag)=Str_tmp Then : this.pNode = pTemp
        ElseIf bHTmethod=1 AndAlso IsLast=0 Then
            pTemp04=pLastNode : pTemp03=AllowCake : this.uCount+=1 : pLastNode=pTemp04
            If pTemp<>pTemp02 Then : pTemp03->pNext=pTemp : pTemp03->pPrev=pTemp->pPrev : pTemp->pPrev->pNext=pTemp03 : pTemp->pPrev=pTemp03 :
            Else : pTemp03->pNext=0 : pTemp03->pPrev=pTemp : pTemp->pNext=pTemp03 : pLastNode=pTemp03
            End If  : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pTemp03->Tag(uTag) = Str_tmp : HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03
        Else ' If pTemp=pTemp02 Then : this.BlindTag(Str_tmp)
            pTemp03 = this.pLastNode : this.uCount+=1 :
            pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode : pTemp03->pNext->Tag(uTag) = Str_tmp '  : pTemp03->pNext->ListData = item
            pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : this.pNode = pTemp03 : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            HadHashTag=0 : pFirstNode->BranchCount+=1           
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system
        End If                   
        If iLenCumul<iLen Then  '  If u*istep<iLen Then   ' this.Branch
            pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : pTemp=pNode
            If this.pNode->pBranch=0 Then ' New 'Hash' : this.BlindTag(LIST_RES) :
                pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
                pTemp03->pNext->pPrev = pTemp03 : pTemp03->pNext->Tag(uTag) = LIST_RES
                pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : pNode=pTemp03
                this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp : pTemp->pBranch=this.pNode
                pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
                this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode
            Else 'Branche déjà créée
                this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
                this.pLastNode = this.pNode->pBranch->pBranchLastNode : this.pNode = this.pNode->pBranch
            End If
        End If : pTemp02=pFirstNode
    Next i
    pLatestHTag=pNode : sLatestHTag=str_Tag
    If this.pNode->Tag(1)="" And bRHByPass=0 Then : this.pNode->Tag(1)=" " : End If
    Deallocate(Listptemp) : Deallocate(Listptemp2) : Deallocate(zp3)
    Return HadHashTag
End Property
Property List.HashSort(ub as Byte) As Byte : If ub=0 Or ub=1 Then : bHTmethod=ub : Return 1 : Else : Return 0 : End If : End Property

Property List.HashTag As String
    Dim pTemp01 As ListNode Ptr : Dim pTemp02 As ListNode Ptr : Dim Str_tmp As String : Dim pTemp1 As ListNode Ptr
    Dim str_arbo As String = ""  : Dim iB As Byte : Dim str_res01 As String = "" : Dim istep as Byte = this.bHashLen : Dim u as byte=0   
    If bTracking=1 And bTrackingMethod=0 Then '  This.TrackCompute()       
        pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
        pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount ': pLastNode->pNext=0
    End If : pTemp01 = this.pFirstNode : pTemp02 = this.pNode :
    str_arbo = this.pnode->Tag(uTag)       
    While pTemp01->pPrev <>0       
        If pTemp01->pBranch <> 0 Then
            pTemp02 = pTemp01->pBranch
            str_arbo = pTemp02->Tag(uTag)  + str_arbo           
        End If
        pTemp01 = pTemp01->pPrev
    Wend   
    Return str_arbo
End Property

Property List.HasHashTag(str_Tag As String) As Byte
    Dim As zString Ptr Listptemp=Allocate(Len(str_Tag)+1), zp1, zp2, zp3=Allocate(1)
    Dim Str_tmp As String : Dim pContextRetour As ListContext
    Dim HadHashTag As Byte=0 : Dim IsEtoile As Byte=0 : Dim i as uByte=1 : Dim t as uByte=Len(str_Tag) : Dim istep As uByte=this.bHashLen
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.RootPrivate
    zp1=Listptemp+Len(str_Tag)+1 : (*zp1)[0]=0 :
    *Listptemp=str_Tag : zp1=Listptemp' * Alternative to Mid
    Do
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid : Str_tmp=Mid(str_Tag,i, istep)
        If this.HasTag(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            If this.pNode->Tag(1)="*" Then : HadHashTag=1 : IsEtoile=1
            ElseIf this.pNode->Tag(1)="!*" Then : HadHashTag=0 : i=t
            ElseIf this.pNode->Tag(1)="!" And i=t Then : HadHashTag=0
            ElseIf i>=t Then : HadHashTag=1
            Else :  HadHashTag=0 : End If   
        ElseIf IsEtoile=0 Then : HadHashTag=0 : i=t
        End If
        If i<t Then
            If this.pNode->pBranch=0 Then
                If bAutoCursor<3 Then : pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount : End If
                Deallocate(Listptemp) : Deallocate(zp3) : Return -1
            Else : this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode : this.pNode = this.pFirstNode
            End If : this.bSearchRes = 0
        End If
        i+=istep
    Loop Until i>t
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode : If bAutoCursor=1 Then : Deallocate(Listptemp) : Deallocate(zp3) :  Return 1
    ElseIf bAutoCursor=2 Then : If pNode->Tag(1)="" Then : HadHashTag=0 : Else : Deallocate(Listptemp) : Deallocate(zp3) :  Return 1 : End If : End If : End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
    Deallocate(Listptemp) : Deallocate(zp3) : Return HadHashTag
End Property

Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : Else : Return 0 : End If : Else : Return -1 : End If : End Property
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>0 And bHashLen<255 Then : this.bHashLen = bHashLen : Return 1 : Else : Return 0 : End If : End Property
Property List.BranchCountDown(i as Byte) As Byte : If i=0 Or i=1 Then : bBranchCountDown=i : Return 1 : Else : Return 0 : End If : End Property
Property List.BranchCount As uInteger : If this.pNode->pBranch<>0 Then : Return pNode->BranchCount : Else : Return 0 : End If : End Property ' Return this.pNode->BranchCount

Property List.NFmethod(i As Byte) As Byte : this.bNFmethod=i : Return 1 : End Property
Property List.NFrecursive(i As Byte) As Byte : If i=1 Then : this.bPickReduce=1 : Else : this.bPickReduce=0 : End If : Return 1 : End Property

Property List.NodeFlat As Byte 'Réallocation sélective dynamique multimodes rétro-récursive (virtuelle/reelle glissante 0/-n) de la structure de l'index en memoire virtuelle (Reduce) - Compatible HashStep, HashStepRev(?), KeyStep, KeyStepRev(?), fStep, TrackStep
    Dim As ListContext pContext, pContextRetour : Dim  As ListNode Ptr pTemp1, pTemp2, pTemp3, pTemp4, pTemp5, pTemp6 : Dim as string str_Tag : Dim IsLastNode As uByte=0
    this.NodeRecycle : NodeRecycle2
    'Contrôle multimode en entrée + contrôle du Token de fin de liste + gestion continuité des ptr
    If pNode->Tag(0)=LIST_RES OrElse pNode->Tag(0)=LIST_DEL OrElse pNode=pWhyteMove OrElse pNode=pGarbage Then : Return 0
    ElseIf bTracking=1 Then
        If pFirstNode->pBranch=pFlatRoot Then : Return 0 : End If
        If bTrackingMethod=0 Then
            pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
            pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : pLastNode->pNext=0
        End If : pTemp6=pNode->pBranchLastNode
    End If : pTemp5=pFirstNode : pTemp2 = this.pNode : str_Tag=this.HashTag : pLatestHTag=0 ': If Right(str_Tag,1)=LIST_DEL Then : Return 0 : End If
    'Gestion (swapping) des nodes parents                                                   ---------------------------------------------------------------------------
    If this.pNode->pBranch<>0 Then           
        'Validation du mouvement mémoire : ' Fonctionnalité Tree List =>FlatList / ByPass Garbage ou 'Déjà swappé
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag(1)=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag(0)=LIST_DEL Then : Return 0 : End If  ' PATCHED !!
        pTemp1=AllowCake : pTemp4=this.pFlatRoot->pBranch : If this.pNode->pPrev<>0 Then : this.pNode->pPrev->pNext=pTemp1 : End If ': End If  If this.pNode->pPrev->Tag(0)<>LIST_DEL Then :
        If this.pNode->pNext->pPrev=this.pNode Then this.pNode->pNext->pPrev=pTemp1 : End If       
        pTemp1->pPrev=this.pNode->pPrev : pTemp1->pNext=this.pNode->pNext : pTemp1->pBranch=this.pNode->pBranch
        pTemp1->BranchCount=this.pNode->BranchCount : pTemp1->Tag(0)=this.pNode->Tag(0) : pTemp1->Tag(1)=LIST_DEL
        pTemp1->pBranch=this.pNode->pBranch : pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If ' ElseIf pTemp2->pPrev=pFirstNode Then : pTemp2->pNext=0 : End If '
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0 : this.pNode->Tag(0) = str_Tag
        this.pNode->pPrev=pTemp4 : pTemp4->pNext->pPrev=this.pNode : this.pNode->pNext=pTemp4->pNext : pTemp4->pNext=this.pNode : this.pNode=pTemp1         
    Else : this.uCount-=1 : pFirstNode->BranchCount-=1 :  If bBranchCountDown=1 Then : this.BCountDown(-1) : End If
    End If   
    'Gestion (/optimisation) du parsing (rétro-récursivité) ds le HashStep       ---------------------------------------------------------------------------       
    If pNode->pPrev<>pFirstNode Then
        If this.pNode->pNext->Tag(0)=LIST_DEL Then : This.pLastNode=this.pNode->pPrev : This.pFirstNode->pBranchLastNode=this.pNode->pPrev : End If ' this.pNode->pPrev->pNext=0 :
        If bHashStepRev=1 Then : pContextRetour.pNode=pNode->pNext : Else : pContextRetour.pNode=pNode->pPrev : End If
        pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount   
    Else
        pContext.pNode=This.pNode ': If bHashStepRev=1 And pNode<>pLastNode Then : pContext.pNode=This.pNode->pNext : End If
        pContext.pFirstNode=This.pFirstNode : pContext.pLastNode=This.pLastNode : pContext.uCount=This.uCount       
        If pNode=pLastNode Then : pTemp3=this.pFirstNode->pBranch->pPrev
        Else : pTemp3=this.pFirstNode->pBranch :
        End If
        If pTemp3->Tag(0)=LIST_RES Then
            If pNode=pLastNode Then : this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : End If
            pTemp3=this.pFirstNode->pBranch
        End If
        this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount ' This.UpLevel         
        pContextRetour.pNode = pTemp3 : pContextRetour.pFirstNode = This.pFirstNode : pContextRetour.pLastNode = This.pLastNode : pContextRetour.uCount=This.uCount
        This.pNode=pContext.pNode : This.pFirstNode=pContext.pFirstNode : This.pLastNode=pContext.pLastNode : this.uCount=pContext.uCount                 
    End If
    If this.pNode->pNext=0 And this.pNode->pPrev->Tag(0)=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag(0)=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
  ' Swapping / MAJ des pointeurs - depend de IsLastNode                        --------------------------------------------------------------------------     
  ' Envoi d'un ancien node parent déjà swappé vers le garbage collector OU envoi d'un node non parent vers le GarbageCollector (si NFmethod=-1)
    If (pTemp2->Tag(1)=LIST_DEL Or this.bNFmethod=-1) And pTemp2->pBranch=0  Then
        If IsLastNode=0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext : End If
   '     If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If    If pTemp2->pPrev<>0 Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag(0)=LIST_DEL : pTemp2->Tag(1)=""  : pTemp2->pBranchLastNode=0 : uGarbCt+=1
        If pTemp2->ListData<>0 Then : pTemp2->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp2->ListData : pTemp2->ListData=0 : uContainerGarbCt+=1 : End If
        This.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
        If IsLastNode=0 And  bHashStepRev=1 Then : If this.Up=0 Then : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext  : End If : End If
        ElseIf IsLastNode=1 Then
            this.pNode=pTemp5->pBranch : this.uCount=pTemp5->pPrev->BranchCount : pLastNode=pTemp5->pPrev->pBranchLastNode : this.pFirstNode = pTemp5->pPrev
            If bTracking=1 Or bPickReduce=1 Then : If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If : '  this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    Else ' Envoi vers la Flat list - Optimisation, à voir                                      --------------------------------------------------------------------------                 
        pFlatRoot->pBranch->BranchCount+=1         
        pNode=pFirstNode->pNext : this.UpLevel
        this.pFirstNode = this.pFirstFIRSTNode : this.pLastNode = this.pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
        this.pNode=this.pFlatRoot : this.Branch ' this.FlatStack
        If pFlatRoot->pBranch->BranchCount=0 Then : pFlatRoot->pBranch->BranchCount=1 : this.uCount=1 :  End If
        pTemp1 = this.pLastNode
        If IsLastNode=0 Then
            If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If
            If pTemp2->pPrev<>0 And pTemp2->Tag(0)<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            pTemp2->pPrev= this.pLastNode : pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2 : pTemp2->pBranch=0
            this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->Tag(uTag) = str_Tag : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            this.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount     
            If bHashStepRev=1 Then : If this.Up=0 Then : this.BlindStep : End If : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If : Return 1 :  End If             
        Else
            pTemp1->pNext=pTemp2  : pTemp2->pNext=0 : this.pLastNode=pTemp2 :  pTemp2->pBranch=0 : this.pFirstNode->pBranchLastNode = pTemp2  : pTemp2->Tag(uTag)=str_Tag : pTemp2->pPrev=pTemp1  '
            this.pNode=pTemp5->pBranch : this.pFirstNode = pTemp5->pPrev : pLastNode=pTemp5->pPrev->pBranchLastNode : this.uCount=pTemp5->pPrev->BranchCount           
            If bTracking=1 Or bPickReduce=1 Then :  If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL  Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If  : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If ' this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : Return 1 : End If
    Return 1
End Property

Property List.RHmethod(i As Byte) As Byte : If -2<i<2 Then : this.bRHmethod=i : Return 1 : Else : this.bRHmethod=-1 : Return 0 : End If : End Property
Property List.RestoreHash As Byte
    Dim As ListNode Ptr pTemp,  pTmpPrev, pTmpNext, pMove
    Dim str_tmp as string=this.Tag : Dim bTagExists As Byte
    pTemp=this.pnode : str_tmp=this.Tag : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : Return 0 : End If
    'HashTagging   
    bRHByPass=1 : bTagExists=this.HashTag(str_tmp) : bRHByPass=0
    'Gestion des modes (RHmethod)
    If bTagExists=1 And pNode->Tag(1)<>""  Then ' tag deja existant et "vraie" clef
        If bRHmethod=-1 Then : pTemp->Tag(0)= this.pnode->Tag(0)  : pLocalMove=this.pnode : this.pFlatRoot->pBranch->BranchCount-=1 'envoi garbage
        ElseIf bRHmethod=1 Then : pTemp->Tag(0)= this.pnode->Tag(0)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
        Else : If pNode->Tag(1)=LIST_DEL Then : pNode->Tag(1)=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
        End If       
    Else : pTemp->Tag(0)= this.pnode->Tag(0) : pLocalMove=this.pnode : this.pFlatRoot->pBranch->BranchCount-=1 :
    End If
    'Swapping mémoire
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext : pTemp->pBranch=this.pnode->pBranch
    this.pnode->pPrev->pNext=pTemp
    If this.pnode->pNext<>0 Then : If this.pnode->pNext->pPrev=this.pnode Then : this.pnode->pNext->pPrev=pTemp : End If : End If
    pTemp->pBranchLastNode=this.pnode->pBranchLastNode
    If this.pnode=this.pLastNode Then : this.pLastNode=pTemp : End If : If this.pnode=this.pFirstNode Then : this.pFirstNode=pTemp : End If     
    If this.pnode->pBranch<>0 Then
        If this.pnode=this.pFirstNode->pBranchLastNode Then : this.pFirstNode->pBranchLastNode=pTemp : End If
        If this.pnode->pBranch->pBranch=this.pnode Then : this.pnode->pBranch->pBranch=pTemp : End If       
        pTemp->pBranch=this.pnode->pBranch : pTemp->pBranchLastNode=this.pnode->pBranchLastNode : pTemp->BranchCount=this.pnode->BranchCount
    End If
    'Reprise ds Flat List
    this.FlatStack(1)
    If bTagExists<>2 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext : this.pnode->pBranch=0
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext : pNode->pBranch=0
    End If
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLOW CONTROL
Property List.Up As Byte : If pFirstNode=pFirstFIRSTnode Then : Return 0 : Else :  this.UpLevel : Return 1: End If : End Property
Property List.Down As Byte
    If pnode->pBranch=0 Or pNode->Tag(0)=LIST_RES Then  : Return 0 : End If
    If pnode->pBranch->pPrev<>pFirstNode Then : Return 0 :
    Else : pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pNode->pBranch : uCount=pFirstNode->BranchCount : pLastNode=pNode->pBranch->pBranchLastNode : pNode=pNode->pBranch : Return 1
    End If
End Property
Property List.AutoCursor(b As Byte) As Byte : If 0<=b<=3 Then : bAutoCursor=b : Return 1 : End If : Return 0 : End Property

Property List.HoldBack As Byte : Return this.HoldBack(0) : End Property
Property List.HoldBack(by As Byte) As Byte   
    If pNode->Tag(0)=LIST_RES Then : Return 0
    ElseIf TrackTrace(by)<>0 Then : TrackTrace(by)->pBranchLastNode=pNode : TrackTrace(by)=this.pNode : Return 1
    Else : this.TrackSet(by) : pNode->pBranchLastNode=0 : TrackTrace(by)=pNode : Return 1
    End If
End Property
Property List.TrackStep As Byte
    Dim As ListNode Ptr pTemp1
    If pNode->pBranchLastNode->Tag(0)=LIST_DEL Or pNode->pBranchLastNode->Tag(0)=LIST_RES Then : this.RootPrivate : this.TrackCompute :  bTracking=0 : Return 0 : End If '
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag(0)<>LIST_RES Then           
        pNode=pNode->pBranchLastNode : bTracking=1 :
        If bTrackingMethod=1 Then  ' this.TrackCompute
            pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
            pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : pLastNode->pNext=0
        End If : Return 1
    End If : this.TrackCompute : bTracking=0 : Return 0
End Property
Property List.Track As Byte : Return this.Track(0) : End Property
Property List.Track(by As Byte) As Byte
    If pNode->Tag(0)<>LIST_DEL Then : This.TrackCompute : End If : bTracking=1 : this.Root : This.TrackMethod(1)
    If this.Tracks(by).pNode=0 Then : this.TrackSet(by)  : Return 0
    Else
        pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=this.Tracks(by).pNode
        pLocalMove=pNode : pFirstNode=this.Tracks(by).pFirstNode : pLastNode=pFirstNode->pBranchLastNode : bHashLen=this.Tracks(by).bLcHashLen
        pNode->pBranch=0 : pNode->pPrev=0 : pNode->Tag(0)=""
        Return 1
    End If
End Property
Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte : this.Tracks(by).pNode=pNode : this.Tracks(by).pFirstNode=pFirstNode : this.Tracks(by).bLcHashLen=bHashLen : TrackTrace(by)=0 : Return 1 : End Property
Property List.IsTracked As Byte : Dim i As Byte : If pNode->pBranchLastNode<>0 And pNode->Tag(0)<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS-1 : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : End Property
Property List.TrackMethod(by As Byte) As Byte : If by=0 Or by=1 Then : bTrackingMethod=by : Return 1 : Else : Return 0 : End If: End Property

Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    Lcontext(by).pNode=pNode : Lcontext(by).pFirstNode=pFirstNode : Lcontext(by).pLastNode=pLastNode : Lcontext(by).uCount=this.uCount : Lcontext(by).LcHashTag=pNode->Tag(0) : Lcontext(by).bLcHashLen=this.bHashLen
    Return 1
End Property
Property List.Recover As Byte : Return this.Recover(1) : End Property
Property List.Recover(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pNode=Lcontext(by).pNode : pFirstNode=Lcontext(by).pFirstNode : pLastNode=Lcontext(by).pLastNode : this.uCount=Lcontext(by).uCount : this.bHashLen=Lcontext(by).bLcHashLen
    Return 1
End Property


'==========================================================================================MEMORY MANAGEMENT
Property List.FlatCount As uInteger : Return this.pFlatRoot->pBranch->BranchCount : End Property
Property List.GarbageCount As uInteger : Return this.uGarbCt : End Property
Property List.ContainerCount As uInteger : Return this.uContainerGarbCt : End Property
Property List.NodeCount As uInteger : Return this.uNodeCOUNT : End Property

Property List.GarbageFlat As Byte
    Dim L_Context As ListContext : Dim As ListNode Ptr pTemp1, pTemp2, pTemp3 : Dim i as Byte
    If pFlatRoot->pBranch=0 Then : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then : pLocalMove=pFlatRoot->pBranch : this.NodeRecycle : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev
    If pTemp2=0 Then
        L_Context.pNode=pNode : L_Context.pFirstNode=pFirstNode : L_Context.pLastNode=pLastNode : L_Context.uCount=this.uCount
        this.FlatStack : pTemp2=pEndFlat->pPrev
        pNode=L_Context.pNode : pFirstNode=L_Context.pFirstNode : pLastNode=L_Context.pLastNode : this.uCount=L_Context.uCount
    End If :  If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext
    pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot
    Do
        pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If
        pNode=pTemp3
        pTemp1=pTemp1->pNext
    Loop Until pTemp1=pTemp2
    pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ': pTemp1->ListData.sData=""
    pTemp3=pNode : pNode=pTemp1 : this.Val("") : pNode=pTemp3
    uGarbCt+=pFlatRoot->pBranch->BranchCount
    pFlatRoot->pBranch->pNext=pFlatRoot->pBranchLastNode : pFlatRoot->pBranchLastNode->pPrev=pFlatRoot->pBranch : pFlatRoot->pBranch->BranchCount=0
    If pFirstNode=pFlatRoot->pBranch Then : uCount=0 : this.RootPrivate : End If
    Return 1
End Property

Property List.Recycle As uInteger : this.Root : this.Root : this.Flat : Return this.GarbageCollector : End Property

Property List.DropAll As uInteger ' On garde pFirstFIRSTNode et pFlatRoot
    Dim pTemp As ListNode Ptr : Dim iLong As uInteger=0 : Dim i As uByte=0 : Dim zLong As uInteger=0 : Dim SeekMt As Byte=this.bSeekMethod
    Dim pPanTemp As ListContainer Ptr =pPanCakeGarbage : Dim pPanTemp2 As ListContainer Ptr   
    While pPanTemp<>pPanTemp->pNextContainer And pPanTemp->pNextContainer<>pPanCakeGarbage And pPanTemp->pNextContainer<>0
        pPanTemp2=pPanTemp : pPanTemp=pPanTemp->pNextContainer : If pPanTemp2<>pPanCakeGarbage Then : Deallocate(pPanTemp2) : pPanTemp2=0 : uContainerGarbCt-=1 : End If
    Wend : If pPanTemp<>0 And pPanTemp<>pPanCakeGarbage Then : Deallocate(pPanTemp) : pPanTemp=0 : uContainerGarbCt-=1 : End If : pPanCakeGarbage->pNextContainer=pPanCakeGarbage       
    'pRoot principal + pFlatRoot + pFlatRoot->pBranch + pGarbage + pLastLAST/pWhyte = 5 nodes déalloues ds destructor     
    If this.uNodeCount<4 Then : Return 1 : End If   
    this.Root : this.GarbageFlat : this.Flat : this.GarbageCollector : this.NodeRecycle :  this.NodeRecycle2
    pTemp = this.pFlatRoot->pNext
    If this.pFlatRoot->pBranch<>0 Then
        If this.pFlatRoot->pNext<>0 Then
            this.pFlatRoot->pNext->pPrev=this.pFlatRoot->pBranch->pBranchLastNode :
            this.pFlatRoot->pBranchLastNode->pNext=this.pFlatRoot->pNext :
            this.pFlatRoot->pNext->pPrev=this.pFlatRoot->pBranchLastNode
            this.pFlatRoot->pNext=this.pFlatRoot->pBranch
        End If
        If this.pFlatRoot->pBranch<>0 Then
            this.pFlatRoot->pBranch->pPrev=this.pFlatRoot :
            this.pFlatRoot->pBranch->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->pBranch=0  : this.pFlatRoot->pBranch->pBranchLastNode=0
            this.pFlatRoot->pBranch=0 :  this.pFlatRoot->pBranchLastNode=0
        End If       
    End If     
    pTemp = pFlatRoot->pNext
    If pTemp<>0 Then
        While pTemp<>pTemp->pNext And pTemp->pNext<>0 And this.uNodeCOUNT>3
            this.pnode = pTemp : pTemp =  pTemp->pNext   
            If this.pnode<>pTemp And pnode<>pFirstFIRSTNode Then
                If pnode=pGarbage Then : pGarbage=0 : End If :  If pTemp=pWhyteMove Then : pWhyteMove=0 : End If
                If this.pNode->ListData<>0 Then : Deallocate this.pnode->ListData : End If
                Deallocate this.pnode : this.pnode=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 :  iLong+=1 : Else : zLong+=1 : End If
            End If       
        Wend       
    End If
    If this.uNodeCOUNT>0 Then         
        If pTemp<>0 And pnode<>pFirstFIRSTNode Then
            If pTemp=pGarbage Then : pGarbage=0 : End If :  If pTemp=pWhyteMove Then : pWhyteMove=0 : End If
            If pTemp->ListData<>0 Then : Deallocate pTemp->ListData : End If
            Deallocate pTemp : pTemp=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : iLong+=1 : Else : zLong+=1 : End If
        End If         
    End If
    If zLong>1 Then : Print "*Sur-deallocation : " & str(zLong) : sleep : End If
    this.bSeekMethod=1 : This.uCount=0 : This.sSearchTag="" : this.uGarbCt = 1 ' : this.pWhyteMove=0
    If this.pGarbage<>0 Then : Deallocate(this.pGarbage) : pGarbage=0 : If this.uNodeCOUNT>0 Then :  This.uNodeCOUNT-=1 : End If : End If     
    pNode=pFirstFIRSTNode : pFirstNode=pNode : pLastNode=pNode : pLastLASTNode=pNode ' pFirstFIRSTNode = pNode :  bSeekMethod=1
    pNode->Tag(0) = LIST_RES :  uNodeCOUNT=3  : this.Val("")  ' pNode->ListData.sData = ""
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT ': pFlatRoot->ListData.sData="**"   
    pTemp=pNode : pNode=pFlatRoot : this.Val("*") : pNode=pTemp
    If pGarbage=0 Then
        pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = CAllocate(Len(ListNode)) : this.uNodeCOUNT+=1 : this.pLastLASTNode=pTemp ' = This.BlindTag(LIST_DEL) :       
        pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = LIST_DEL : pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp   ' = This.BlindTag(LIST_DEL) :
        This.Tag(LIST_DEL) : pValTmp=pNode ': this.ValPrivate(LIST_DEL)
        pGarbage=this.pNode : pGarbage->pPrev=pFlatRoot
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If
        this.pNode = this.pFirstNode : this.pNode = pGarbage
    End If   
    this.bSeekMethod=SeekMt : uCount=1 : this.pFirstNode->BranchCount=1 : this.RootPrivate : Return iLong
End Property

Property List.Destroy As Byte
    If this.uNodeCount<2 Then : Return 1 : End If   
    this.Root : this.DropAll : If pWhyteMove=pFlatRoot Then : pWhyteMove=0 : End If   
    If this.pFlatRoot<>0 Then
        If this.pFlatRoot->pBranch<>0 Then
            If this.pFlatRoot->pBranch->pNext<>0 Then
                If pWhyteMove=pFlatRoot->pBranch->pNext Then : pWhyteMove=0 : End If
                Deallocate(this.pFlatRoot->pBranch->pNext) : pFlatRoot->pBranch->pNext=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : End If
            End If
            Deallocate(this.pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : End If
        End If
        Deallocate(this.pFlatRoot) : pFlatRoot=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : End If
    End If
    If this.pLastLASTNode<>0 And pLastLASTNode<>pWhyteMove And pLastLASTNode<>pFirstFIRSTNode Then : Deallocate(this.pLastLASTNode) : pLastLASTNode=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : End If : End If
    If this.pGarbage<>0 And pGarbage<>pNode Then : Deallocate(this.pGarbage) : pGarbage=0 :  If this.uNodeCOUNT>0 Then :  This.uNodeCOUNT-=1 : End If : End If
    If this.pWhyteMove<>0 Then : Deallocate(this.pWhyteMove) : pWhyteMove=0 : If this.uNodeCOUNT>0 Then :  This.uNodeCOUNT-=1 : End If : End If
    If this.pFirstFIRSTNode<>0 Then : Deallocate(this.pFirstFIRSTNode) : pFirstFIRSTNode=0 : If this.uNodeCOUNT>0 Then : this.uNodeCOUNT-=1 : End If : End If
    If this.pNode<>0 Then : Deallocate(this.pNode) : pNode=0 : If this.uNodeCOUNT>0 Then :  this.uNodeCOUNT-=1 : End If : End If
    If this.uNodeCount>2 Then : Print "Erreur a reporter : " & Str(this.uNodeCount-2) & " non dealloues !" : sleep : End If
    If pPanCakeGarbage<>0 Then Deallocate(pPanCakeGarbage) : pPanCakeGarbage=0 : End If
    'Deallocate( New(@this) List )
    Return 0
End Property

'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : dim i as byte=0 : dim t as byte=0
    this.NodeRecycle : this.NodeRecycle2 : If pNode->pBranch=0 Then : this.Branch : this.BlindTag("") : pTemp1=pNode : t=1 : Else : this.Down : pNode=pNode->pNext : End If
    i=this.Snatch(pList)
    If i=0 Then : If t=1 Then : pLocalRoot=pFirstNode : pLocalMove=pTemp1 : End If
    ElseIf i=1 Then : If t=1 Then : pTemp1->pPrev->pNext=pTemp1->pNext : pTemp1->pNext->pPrev=pTemp1->pPrev : pLocalMove=pTemp1 : End If
    End If : this.UpLevel : If t=1 Then : this.NodeRecycle : this.NodeRecycle2 : End If : Return i
End Property

Property List.Snatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr
    pTemp1=pList.GiveBranch : If pTemp1=0 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
    If bBranchCountDown=1 Then : this.BCountDown(pTemp1->BranchCount) : End If : uCount+=1 : pFirstNode->BranchCount+=1
    If pNode->Tag(0)=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If : End If
    If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode :  End If
    pTemp1->pNext=pNode->pNext : If pNode->pNext<>0 Then : pNode->pNext->pPrev=pTemp1 : End If
    pNode->pNext=pTemp1 : pTemp1->pPrev=pNode : If pNode=pLastNode Then : pLastNode=pTemp1 : End If         
    pNode=pTemp1 : Return 1
End Property

Property List.FlatSnatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : Dim pTemp2 As ListNode Ptr   
    pTemp1=pList.GiveFlat : If pTemp1=0 Then : Return 0 : End If
    pFlatRoot->pBranch->BranchCount+=pTemp1->BranchCount : uNodeCOUNT+=pTemp1->BranchCount : pTemp1->BranchCount=0
    pTemp2=pTemp1->pBranch : pTemp1->pBranch=0 : pFlatRoot->pBranch->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pBranch->pNext
    pFlatRoot->pBranch->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot->pBranch : Return 1
End Property

Property List.GarbageSnatch(pList As List) As Byte
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2 : Dim As ListNode Ptr pTemp1, pTemp2
    pTemp1=pList.GiveGarbage : If pTemp1=0 Then : Return 0 : End If : uNodeCOUNT+=pTemp1->BranchCount : uGarbCt+=pTemp1->BranchCount
    pTemp2=pTemp1->pBranch : pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext : pTemp1->pBranch=0 : pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot   
    pPanTemp1=pPanCakeGarbage->pNextContainer
    pPanTemp2=pList.GivePanCake : If pPanTemp2=0 Then : Return 0 : End If :  pPanCakeGarbage->pNextContainer=pPanTemp2
    pPanTemp2=pList.GiveLastPanCake : uContainerGarbCt+=pList.GivePanCakeCount : pPanTemp2->pNextContainer=pPanTemp1 : Return 1
End Property


Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - New release Alpha2

Post by Lost Zergling »

This code is showing speed difference between apha1 & alpha2 (in a specific case of mapping sequential keys)(this more practical)
It is also showing the advantages using LZLE recycle/garbagecollector/virtualization layer (vs allocate/deallocate) :
uncomment : Print "Recycle.." & MaListe.Recycle : is re-using nodes
uncomment : Print "Dealloues=" & MaListe.DropAll & " nodecount=" & MaListe.NodeCount : is using allocate/deallocate
First one is a thick faster but using 2 times less memory, this because the size of cakes & pancakes is previously known so it can be better optimized wich means computer needs to manage less memory fragmentation issues.

Code: Select all

#Include once "lzle.bi"

Dim MaListe As List ': MaListe.Root
MaListe.HashLen(1)
MaListe.SeekMethod(2)
MaListe.HashSort(1)
Dim str_tmp As String="ABCDEFGHIJKLMNOPKRSTUVWXYZ"
Dim i as integer : Dim t as integer : Dim k as string
Print time
For t=1 To 6
    Print "Clef ++"
    For i=1000000 To 2000000
       ' MaListe.HashTag( str_tmp & str(i)) : MaListe.ColTags(1) : MaListe.RwTag("#" & str(i))  : MaListe.ColTags(0) ' 
        MaListe.HashTag( str_tmp & str(i)) : MaListe.Val("#" & str(i))
       ' MaListe.HashTag( str_tmp & str(i)) : MaListe.RwTag1("#" & str(i))  
    Next i            
    If str_tmp<>"" Then : Print "Oui" : Else : Print "Non" : End If
    Print "Garbage=" & MaListe.GarbageCount
    Print "Recycle.." & MaListe.Recycle
   ' Print  "Dealloues=" & MaListe.DropAll  & " nodecount=" & MaListe.NodeCount 
  '  Print "Recycle : garbage=" & MaListe.GarbageCount & " container=" & MaListe.ContainerCount
    If str_tmp="" Then : str_tmp="ABCDEFGHIJKLMNOPKRSTUVWXYZ" : Else : str_tmp="" : End If
Next t
Print time
Print "Fin"
'MaListe.DropAll
Print "%?=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount
MaListe.Destroy
Print "%%=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount
sleep
system
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha2.01 - Updt 01/07/2018

Post by Lost Zergling »

"TestSorts" exemples - Updated 13/08/2018 : New Feature : NFMethod(3) fSort, fSortMethod, ColSort, and Sort new Properties
Here some new exemple and one FIX :
Illustrate how to sort & track

Code: Select all

#Include once "D:\Basic\LZLE.bi"

Dim MaListe1 As List
Dim i as integer
'MaListe1.Root
Print "Start"
MaListe1.HashTag("D4") : MaListe1.HoldBack : MaListe1.RwTag1("D4-1")
MaListe1.HashTag("C") : MaListe1.HoldBack : MaListe1.RwTag1("C")
MaListe1.HashTag("A") : MaListe1.HoldBack : MaListe1.RwTag1("A")
MaListe1.HashTag("B") : MaListe1.HoldBack : MaListe1.RwTag1("B")

MaListe1.HashTag("C5") : MaListe1.HoldBack :  MaListe1.RwTag1("C5")
MaListe1.HashTag("C4") : MaListe1.HoldBack :  MaListe1.RwTag1("C4")
MaListe1.HashTag("C3") : MaListe1.HoldBack  : MaListe1.RwTag1("C3")
MaListe1.HashTag("D2") : MaListe1.HoldBack : MaListe1.RwTag1("D4-2")
MaListe1.HashTag("D1") : MaListe1.HoldBack : MaListe1.RwTag1("D4-3")


MaListe1.Root
While MaListe1.KeyStep
    Print MaListe1.HashTag
Wend
Print ' "OK -------------"
Sleep

Print "Liste 1 (...Partial sort on D branch) :"
MaListe1.Root : MaListe1.HashTag("D") : MaListe1.Down
MaListe1.fSort

MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag
Wend
Print "OK -------------"
sleep


Print "Snatching C branch from List 1 to List2 : "
Dim MaListe2 As List
MaListe1.HashTag("C")
MaListe2.Snatch(MaListe1)

Print "Liste 1 :"
MaListe1.Root
While MaListe1.KeyStep
    Print MaListe1.HashTag
Wend
Print ' "OK -------------"
Print "Liste 2 :"
MaListe2.Root
While MaListe2.KeyStep
    Print MaListe2.HashTag
Wend
sleep
Print
Print "Sorting Liste 2 in 2 steps :"
MaListe2.NFMethod(1)
MaListe2.Root
While MaListe2.HashStep
    MaListe2.NodeFlat
Wend
MaListe2.HashSort(1)
MaListe2.FlatStack
While MaListe2.fStep
    MaListe2.RestoreHash
Wend
'Print "OK -------------"
Print "Liste 2 sorted after Reduce+Restore :"
MaListe2.Root
While MaListe2.KeyStep
    Print MaListe2.HashTag
Wend

'MaListe2.Root : MaListe2.fStep
MaListe2.HashTag("C") ' Set cursor to C on liste 2 : snatch entry point
MaListe1.Root
MaListe1.Snatch(MaListe2)
Print "OK -------------"
Print "Liste 1 (partially sorted) :"
MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag
Wend
Print : sleep

MaListe1.fSortMethod(-1)
MaListe1.Root : MaListe1.fSort
Print "Liste 1 : root flat list REV sorted !! ) :"
MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag
Wend
Print "OK -------------"
sleep



Print "Reduce+Restore on Liste1's root flat list"
MaListe1.Root : MaListe1.NFMethod(3)
While MaListe1.fStep
    MaListe1.NodeFlat
Wend
MaListe1.FlatStack
MaListe1.HashSort(1)
While MaListe1.fStep
    Print "Restoring sorted : " & MaListe1.Tag
    MaListe1.RestoreHash
Wend

Print "Liste 1 (...sorted !! ) :"
MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag
Wend
Print "OK -------------"
sleep

MaListe1.fSortMethod(-1)
MaListe1.Sort
Print "WHOLE Liste 1 (...sorted Rev !! ) :"
MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag
Wend
Print "OK -------------"
sleep

Print "Chronological parsing on List1 :"
MaListe1.Root
MaListe1.Track
While MaListe1.TrackStep
    Print MaListe1.HashTag
Wend
Print "Reduce+Restore + HoldBack Tracking - fixed"
Print
sleep

Print "Sorting on Tag1 :"
MaListe1.fSortMethod(1)
MaListe1.ColSort(1)
MaListe1.Sort

MaListe1.Root : MaListe1.RootNode
While MaListe1.HashStep
    Print MaListe1.HashTag & " Tag1= " & MaListe1.Tag(1)
Wend
Print "###############"

Print "Fin"
Sleep
Print "%?=" & AllocateDeallocateCounter & " nodecount=" & MaListe1.NodeCount
MaListe1.Destroy :MaListe2.Destroy
Print "%%=" & AllocateDeallocateCounter & " nodecount=" & MaListe1.NodeCount
sleep
system

Sort speed improvments (compared to previous sorting method)

Code: Select all

#Include once "lzle.bi"

Dim MaListe As List ': MaListe.Root
MaListe.HashLen(1)
MaListe.SeekMethod(2)
'MaListe.HashSort(1)
Dim str_tmp As String="ABCDEFGHIJKLMNOPKRSTUVWXYZ"
Dim i as integer : Dim t as integer : Dim k as string
Print time
For t=1 To 6
    Print "Clef ++"
    For i=2000000 To 1000000 Step -1
        MaListe.HashTag( str_tmp & str(i)) :  MaListe.RwTag1("#" & str(i)) 
    Next i           
    If str_tmp<>"" Then : Print "Oui" : Else : Print "Non" : End If
    Print "Sorting"
    If t=2 or t=3 Then
       Print "Sorting using whole rebuild "
        MaListe.Root
        MaListe.NFMethod(1)
        While MaListe.KeyStep
            MaListe.NodeFlat
        Wend
        MaListe.FlatStack
        While MaListe.fStep
            MaListe.RestoreHash
        Wend
    Else
        Print "Sorting using Sort property "
        MaListe.Sort        
    End If
    Print "Sorting done"
    
    Print "Garbage=" & MaListe.GarbageCount
    Print "Recycle.." & MaListe.Recycle
   ' Print  "Dealloues=" & MaListe.DropAll  & " nodecount=" & MaListe.NodeCount
  '  Print "Recycle : garbage=" & MaListe.GarbageCount & " container=" & MaListe.ContainerCount
    If str_tmp="" Then : str_tmp="ABCDEFGHIJKLMNOPKRSTUVWXYZ" : Else : str_tmp="" : End If
Next t
Print time
Print "Fin"
'MaListe.DropAll
Print "%?=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount
MaListe.Destroy
Print "%%=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount
sleep
system
Reindexing on other column

Code: Select all

#Include once "D:\Basic\LZLE.bi"

Dim MaListe1 As List
Dim i As Integer

For i=110 to 122
    MaListe1.HashTag(str(i)) : MaListe1.RwTag1(str(i-100))
Next i

MaListe1.NFMethod(1)
MaListe1.Root
While MaListe1.HashStep
    MaListe1.NodeFlat
Wend
MaListe1.Recycle

Print "#"
MaListe1.RootNode
While MaListe1.HashStep
    Print MaListe1.HashTag & " - " & MaListe1.Tag(1)
Wend
Print "##"
sleep

MaListe1.ColTags(1)
MaListe1.RHmethod(1)
MaListe1.FlatStack
While MaListe1.fStep
    If MaListe1.Tag<>"" Then
        MaListe1.RestoreHash
    End If    
Wend

Print "*"
MaListe1.ColTags(0)
MaListe1.Root
While MaListe1.HashStep
    Print MaListe1.HashTag & " - " & MaListe1.Tag(0)  & " -" & MaListe1.Tag(1) & "-"
Wend
Print "fin"
Sleep
System
Fast sort - non recursive

Code: Select all

 #Include once "D:\Basic\LZLE.bi"

Dim MaListe As List
Dim MaListe2 As List
Dim i as integer
Dim str_tmp As String
'MaListe.Root
'MaListe.HashLen(3)
' MaListe.HashTag("AB*")
'MaListe.Up : MaListe.Down
For i=250 to 100 step -1
   ' MaListe.HashTag( str(i))
   MaListe.BlindTag(str(i))
Next i
Print "***********"
sleep
' MaListe.fSort
 MaListe.Sort
Print "ok?"
sleep
  MaListe.Root
Print "ok?"


'For i=1 To MaListe.Count : MaListe.fStep
'    Print MaListe.Tag
'Next i

sleep

While MaListe.HashStep
    Print MaListe.HashTag ': sleep
Wend
Print "=========" : sleep
MaListe.Destroy : MaListe2.Destroy
Print "%%=" & AllocateDeallocateCounter

Print "=========" : sleep
system
    
Last edited by Lost Zergling on Oct 02, 2018 23:51, edited 1 time in total.
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha2.04 - Updt 30/08/2018

Post by Lost Zergling »

Test simple Indexes features

Exemple 1 :

Code: Select all

#Include once "D:\Basic\LZLE.bi"

Dim MaListe As List
Dim MaListe2 As List
Dim i as integer

For i=11 to 28
    MaListe.HasHTag(Str(i)) 
    MaListe.RwTag1("ABC"+Str(i)) 
    MaListe.Val("Long string accepted here.. "+Str(i)) 
Next i

MaListe.HasHTag("1") : MaListe.RwTag1("") ' 1 is not a key, so RwTag1("") neutralize HashTag implicit key setting. This way HashTag is used as a if it were a setcursor before copying to List2 
MaListe.CopyCat(MaListe2) 'CopyCat is a special feature wich is copying a branch from a list to another while setting a tracking from List2 to source list : this tracking is used by SourceList.Follow(TargetList)
' It is possible to use destination list (List2) as an index on source list. It is also possible to build several indexes on a single source list.

MaListe2.Root
While MaListe2.KeyStep
    Print MaListe2.HashTag
Wend

sleep
Print "---------------"
MaListe.Root
While MaListe.HashStep
    Print MaListe.HashTag
Wend

sleep

MaListe2.HasHTag("12")
MaListe.Follow(MaListe2)
Print "Following exemple :"
Print "Key=" & MaListe.HasHTag & " val=" & MaListe.Val
sleep
Print
Print "Follow in a loop"
MaListe2.fSortMethod(-1)
MaListe2.Sort
MaListe2.Root
While MaListe2.HashStep   
'While MaListe2.KeyStep   
  ' Print MaListe2.HashTag
    If MaListe.Follow(MaListe2) Then 
        Print MaListe.HashTag & " val=" & MaListe.Val
    End If
Wend
sleep

Print "Now Index rebuild on List 1 col 1 "
MaListe.Root : MaListe.NFMethod(1)
While MaListe.HashStep : MaListe.NodeFlat : Wend
MaListe.FlatStack : MaListe.ColTags(1)
MaListe.RHmethod(1)
While MaListe.fStep 
    If MaListe.Tag<>"" Then
        MaListe.RestoreHash 
    End If    
Wend
MaListe.ColTags(0)
MaListe.Root 
While MaListe.HashStep
    Print MaListe.HashTag
Wend
Print "-----------"
MaListe2.HasHTag("18")
MaListe.Follow(MaListe2)
MaListe.TrackCompute 'This instruction because Liste index has been recomputed AFTER CopyCat, so whenever link remains valid (key to key), the context of tree structure (inherited from List2) is now corrupted after each Follow
Print "Key pos on list 1= " & MaListe.HasHTag & " value=" & MaListe.Val
sleep
MaListe.Destroy : MaListe2.Destroy
Print "??=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount & " container=" & MaListe.ContainerCount
Print "Fin"
sleep
system
Exemple 2

Code: Select all

#Include once "D:\Basic\LZLE.bi"

Dim MaListe As List
Dim MaListe2 As List
Dim i as integer

For i=11 to 28
    MaListe.HasHTag(Str(i)) 
    MaListe.RwTag1("ABC"+Str(i)) 
    MaListe.Val("Long string accepted here.. "+Str(i)) 
Next i

MaListe.HasHTag("1") : MaListe.RwTag1("") ' 1 is not a key, so RwTag1("") neutralize HashTag implicit key setting. This way HashTag is used as a if it were a setcursor before copying to List2 
'***********************
MaListe.ColTags(1) ' The index on list2 will be build from list's tag1 (not from tree hierarchy cascaded keys

MaListe.CopyCat(MaListe2) 'CopyCat is a special feature wich is copying a branch from a list to another while setting a tracking from List2 to source list : this tracking is used by SourceList.Follow(TargetList)
' It is possible to use destination list (List2) as an index on source list. It is also possible to build several indexes on a single source list.
' Optimize mem usage to requirements increasing or decreasing Constants RUP_COLS=1 and  MAX_COLS=5 depending on the number of indexes needed

MaListe.ColTags(0) ' Back to 'Normal' context

Print "List2 : "
MaListe2.Root
While MaListe2.HashStep
    Print "hashtag=" & MaListe2.HashTag
Wend
Print "---------------"
Sleep
Print 
Print "List :"
MaListe.Root
While MaListe.HashStep
    Print "hashtag=" & MaListe.HashTag & " tag1=" & MaListe.Tag(1) & " value=" & MaListe.Val
Wend
Print "---------------"
sleep

MaListe2.HasHTag("12")
MaListe.Follow(MaListe2)
Print "Following exemple :"
Print "Key=" & MaListe.HasHTag & " val=" & MaListe.Val
sleep
Print
Print "Follow in a loop"
MaListe2.fSortMethod(-1)
MaListe2.Sort
MaListe2.Root
While MaListe2.HashStep   
'While MaListe2.KeyStep   
  ' Print MaListe2.HashTag
    If MaListe.Follow(MaListe2) Then 
        Print MaListe.HashTag & " val=" & MaListe.Val
    End If
Wend
sleep

MaListe.Destroy : MaListe2.Destroy
Print "??=" & AllocateDeallocateCounter & " nodecount=" & MaListe.NodeCount & " container=" & MaListe.ContainerCount
Print "Fin"
sleep
system
Fast Sort - non recursive

Code: Select all

 #Include once "D:\Basic\LZLE.bi"

Dim MaListe As List
Dim MaListe2 As List
Dim i as integer
Dim str_tmp As String
'MaListe.Root
'MaListe.HashLen(3)
' MaListe.HashTag("AB*")
'MaListe.Up : MaListe.Down
For i=250 to 100 step -1
   ' MaListe.HashTag( str(i))
   MaListe.BlindTag(str(i))
Next i
Print "***********"
sleep
' MaListe.fSort
 MaListe.Sort
Print "ok?"
sleep
  MaListe.Root
Print "ok?"


'For i=1 To MaListe.Count : MaListe.fStep
'    Print MaListe.Tag
'Next i

sleep

While MaListe.HashStep
    Print MaListe.HashTag ': sleep
Wend
Print "=========" : sleep
MaListe.Destroy : MaListe2.Destroy
Print "%%=" & AllocateDeallocateCounter

Print "=========" : sleep
system
    
Last edited by Lost Zergling on Oct 02, 2018 23:52, edited 1 time in total.
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha2.04 - Imp. BUGFIX 17/09

Post by Lost Zergling »

ARCHIVE 01 - 2018/09/20
This version has major improvements over the previous version:
1. The architecture is functional: the list can be really manipulated both in indexed mode (tree) and in linear mode, to pass from one to the other either by a garbage collector or by "map / reduce" (LZLE version) and without having to encode links.
2. Huge bug fixes. Pretty stable and usable.
3. Major functional improvements without performance losses.
4. Some speed optimizations.
5. Consumes less memory.
6. More intuitive to use and prepared for some future evolutions
7. A clarification about the license: French regulations require that the name of the author be known (that the responsibility of the license is assumed by someone) for the license to be valid, even thought it is opensource. This program was written from the white paper and the open source aspect is recorded. I do not guarantee that other related programs already exist but that this one has been developed without prior knowledge of the operation.
8. A tutorial serving as documentation is coming soon

Product specifications :
1) The goal is to integrate the product via a library as a real extension of the programming language: if it is already difficult to code a set of instructions, it is even more difficult to do it by consuming quite a few resources compared to the same specifically integrated code.
2) Languages ​​like Python or Java use their own syntax to manipulate memory intuitively. It is not a question here of copying the syntax of languages ​​admittedly called free but at the same time competitors, but to try to create our own syntax, original and adapted to the spirit of FB language. The syntax conditions the working method of the programmer while being the tool he uses: creating a set of instructions is also creating a tool and designing the working method (programming style) that goes with it.
3) The product must be written entirely in basic and basic standard instructions without the need for libraries, thus freeing itself from any external license constraints but also and above all from any integration constraints linked to the language (the product is linked to the Basic language because it is designed for it, but it is not necessary to modify the compiler to extend its capabilities) (it is a library but a library of keywords with the ability to integrate naturally the native instructions of the language as if natively coded in). The product can thus be adopted by a developer without constraints of versions, limitations, etc.
4 °) The product is an object architecture whose performances shall be little degraded compared to c language
5 °) The instruction set must be easy enough to understand and use while being able to simply propose extended and complex functionalities, RAD spirit compliant.

LZListsEngine.bi Tutorial (to be updated) : https://freebasic.net/forum/viewtopic.php?f=3&t=26573

Update : 06/04/2018 : https://freebasic.net/forum/viewtopic.p ... 15#p245516
Update 10/04/2018 Sort (ascending) https://freebasic.net/forum/viewtopic.p ... 79#p245779
12/04/2018 : Moved to comment forgotten debug patch "and 1=0" in List.HashTag to activate optimization for big lists
13/04/2018 : List.HashTag : optimization algo does not slow smaller lists (added pLatestHTag and sLatestHTag)
Update 16/04/2018 : Critical BUG FIX on release 13/04 (only)(Sorry) : forgotten pointer in .HashTag Property
==> If pLatestHTag=pNode Then : Str_tmp=sLatestHTag : Else : Str_tmp=this.HashTag : End If
==> If pLatestHTag=pNode Then : Str_tmp=sLatestHTag : Else : pNode=pFirstNode->pNext : Str_tmp=this.HashTag : End If
(Speeds +20% like 13/04 release, no bug.)
Update 19/04/2018 : Alpha 1 Frozen :
- HashTag (mapping) +25% speed (long key)(zString Ptr instead Mid, left & right) : nice optimization
- HashStep doesn't show randomly the end list whyte node
- Fixed a small leak issue (marginal, but not detected before despite node meters)
- HashSort(1) now support RevSeeking
- HasHashTag : added small feature
- New issue : sometimes generate latency on closing (FB 0.23 32 bits), to be tested on FB 1.05 64 bits => Tested 64 KO => Fixed, exit latency fixed as well
Goal is to reach 50% speed of Python's list basis, I think it's rather 25% (not vectorised not multithreaded) - to be checked.
Fast enought for lots of use anyway. Easy and flexible.

Update 27/04/2018 : BUG FIX on all release : changed Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt, uContainerGivenCt to Dim As uLONG uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt, uContainerGivenCt
Update 30/04/2018 : BUG FIX on all release :
HashTag : overflow : => Adde +1 : Dim As zString Ptr Listptemp=cAllocate(iLen+1), Listptemp2=Allocate(iLen+1)
HashTag : overflow : => Added : If Len(Str_tmp)>iLen+1 Then : Deallocate(Listptemp) : Listptemp=cAllocate(Len(Str_tmp)+1) : End If ':
HasHashTag : Leak : => Added 3* Deallocate(Listptemp) : Deallocate(zp3) before Returns
DropAll : Leak : => Added If this.pNode->ListData<>0 Then : Deallocate this.pnode->ListData : End If
DropAll : Leak : => Added If pTemp->ListData<>0 Then : Deallocate pTemp->ListData : End If
Destroy : crash : => Added If this.uNodeCount<2 Then : Return 1 : End If
Update 11/06/2018 : new release (Alpha 2) (not 64 bits fully tested) What's new ?
HashTag : MAJOR bug fix : some cascaded keys were not properly set due to bugs on speed optimization algo
DropAll : MAJOR bug fix : very significative leaks in some cases
Speed improvment : general improvment, very significative speed improvment in some cases.
Minor fixes : should be more stable : some bugs occuring when a specific keyword cinematic was not respected are now fixed
Minor fixes : every "Small leaks" should have been fixed (hope so) : should not leak a single pointer, to be more tested.
Thanks to fxm, AllocationDeallocation counter is included to check deallocations. This can also be very usefull to check alldeallocations on multiple instances. Thus, it appears no significative speed difference using it or not.
* Found bug when using HashSort(1) combined with SeekMethod(2) a fix is on the way.
01/07/2018 : BUG Fixed HashSort(1) combined with SeekMethod(2) : Patched/fixed
08/08/2018 : BUG Fixed HashTag + Tracking losing tracking : Patched/fixed (may need more non regression tests !) : pTemp->pBranchLastNode=this.pNode moved to comment in HashTag and pTemp->pBranchLastNode=this.pnode->pBranchLastNode moved to comment in RestoreHash
Minor Fix Added : pWhyteMove->Tag(0)="" in Root Property (rare Bug Fix whenever pWhyteMove reset by RwTag to non empty value)
09/08/2018 : BUG Fix / new feature : NFMethod(3) send a whole branch to flat list wich enable sort on parent list on restore without generating double key entries. NodeFlat : If this.pNode->pBranch<>0 => If this.pNode->pBranch<>0 And bNFmethod<>3, pTemp2->pBranch=0 (*2) moved to comment. RestoreHash : this.pnode->pBranch=0 (*2) moved to comment and pTemp->pBranch=this.pnode->pBranch changed to If bNFmethod<>3 Then : pTemp->pBranch=this.pnode->pBranch : End If
Next release will/may include a new fSort property using NFMethod(3) for sorting a list in one single instruction in a better optimized way (hope so) than a NodeFlat+HashSort(1)+RestoreHash on the whole list.
13/08/2018 : new features : fSort (Flat Sort) And Sort (tree) - Minor Fix : Recover Property updated to latest implementation specifications
14/08/2018 : new features ; support reindexing on different colomn (restore Hash)
please refers to "TestSorts" exemples on page 6.
30/08/2018 : Minor Fix Cinematic weaknesses on Snatches. New Features : new properties 'CopyCat' and 'Follow' answer the question : how to add indexes features with only two keywords.
SERIOUS FIX in HashTag : iLenpNode=iLen=>iLenpNode=Len(pNode->Tag(uTag)). Sorry for it
New release Beta 1.00 will come soon : it should be significantly better : speeds same or better, more functions, less bugs & more robust (but a thick more heavy).
Code PART 1 :

Code: Select all


' NOTICE : Thank you to remove first single quote on the line below once you accepted the licence.
 /'   In case redistribution of SOURCES you may ensure to reactivate the acceptance of the license. This notice may be anywhere in source code till licensed user is aware it exists.
CONST PRODUCT_LIC =_
"_______________________________________________________________________________" & chr(10) &_
"  LZListsEngine/ListsVM by Etienne Carfagnini - contact:etienne.carfa@gmail.com" & chr(10) &_
"  Bd Henri Barbusse 92700 Colombes France 01 46 49 99 02" & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  This Freeware/Openware licence specify the rights to use the software" & chr(10) &_
"* Distribution of derivating software : " & chr(10) & "  The information access to the original software must be guaranteed to" & chr(10) & "  developers and users (https://freebasic.net/forum/ or alternative mentionned)" & chr(10) &_
"* Right to use the software and its derivating : 2 options : " & chr(10) & " >OPTION 1 (Openware) :"  & chr(10) & "  The software is free for any use." & chr(10) &_
"  'LZLE Openware licence' is mentionned in licence contributors." & chr(10) &_
"  The software must be compiled using any official GPL FreeBasic Compiler." & chr(10) & "  (https://freebasic.net/forum/viewforum.php?f=1)" & chr(10) &_
"  Plattform (or virtual) using the software is open & compliant with FreeBasic." & chr(10) &_
" >OPTION 2 (Freeware) :"  & chr(10) & "  The software is free for any use except the following limitation as to its"  & chr(10) & "  fields of application : not for use on virtual machine or on virtual server." & chr(10) &_
"  'LZLE Freeware licence' is mentionned in licence contributors." & chr(10) &_
"* Apart from the restrictions of use (options 1 and 2) which are not compatible"  & chr(10) & "  with the rights of uses specified in clause 5.1, the legal clauses whenever"  & chr(10) &_
"  compatible will be those specified by the CeCILL-C license"  & chr(10) & "  ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )" & chr(10) &_
"  Disclaimer :"  & chr(10) & "  This licence refers to CeCILL-C but is NOT a CeCILL-C because the right to"  & chr(10) & "  use the software with no restriction is limited to the FreeBasic ecosystem." & chr(10) &_
"  This because it aims to be an extension of the language instructions set."  & chr(10) &_
"  LZLE (instruction set architecture,coding style) is dedicated to FreeBasic."  & chr(10) &_
"  This notice constitutes a whole that must be present in the source code." & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  Cette licence Freeware/Openware precise les droits a utiliser le logiciel" & chr(10) &_
"* Distribution de logiciels derives :" & chr(10) & "  L'acces informatif au logiciel original doit etre garanti aux" & chr(10) & "  developpeurs et aux utilisateurs (https://freebasic.net/forum/ ou autre)." & chr(10) &_
"* Droit d'utiliser le logiciel et ses derives : 2 options : " & chr(10) & " >OPTION 1 (Libre) :"  & chr(10) & "  Le logiciel est gratuit pour toute utilisation." & chr(10) &_
"  'LZLE licence Openware' est mentionne dans les contributions." & chr(10) &_
"  Le logiciel doit etre compile en utilisant n'importe quel compilateur GPL" & chr(10) & "  FreeBasic 'officiel' (https://freebasic.net/forum/viewforum.php?f=1)" & chr(10) &_
"  La plate-forme d'execution du logiciel est ouverte et compatible FreeBasic." & chr(10) &_
" >OPTION 2 (Gratuiciel) :"  & chr(10) & "  Le logiciel est gratuit pour tout usage sauf la limitation suivante quant a"  & chr(10) & "  son champs d'application : pas d'utilisation sur machine ou serveur virtuel." & chr(10) &_
"  'LZLE licence Freeware' est mentionne dans les contributions." & chr(10) &_
"* En dehors des restrictions d'utilisation (options 1 et 2) lesquelles ne sont "  & chr(10) & "  pas compatibles avec les droits d'utilisation prevus a la clause 5.1, les"  & chr(10) &_
"  clauses applicables seront celles compatibles specifiees par la licence"  & chr(10) & "  CeCILL-C ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-fr.txt )" & chr(10) &_
"  Avertissement :"  & chr(10) & "  Cette licence fait reference a la licence CeCILL-C mais n'en est PAS une car"  & chr(10) & "  le droit a utiliser librement le logiciel est limite a l'ecosysteme FreeBasic" & chr(10) &_
"  Ce moteur de liste a jeu d'instructions est dedie au langage FreeBasic" & chr(10) &_
"  Cette notice constitue un tout lequel doit etre present dans le code source." & chr(10) &_
"_______________________________________________________________________________"
Dim k As String
Print PRODUCT_LIC : Print
Print "Please press 'Y' (Yes) to accept the licence or Esc to abort"
Print "Merci d'appuyer sur 'O' (Oui) pour accepter la licence ou echap pour annuler"
Do : k = Inkey : Select Case k : Case "Y" : Exit Do : Case "y" : Exit Do : Case "O" : Exit Do : Case "o" : Exit Do : Case Chr(27) : System : End Select : Loop
Print "Removing first single quote on line 2 in source code will activate the licence" : Print "Retirer la premiere simple quote en ligne 2 du code source activera la licence" : Print "Thank you for chosing this software - Merci d'avoir choisi ce logiciel" : Print
'/ ' END NOTICE

Dim Shared As uInteger AllocateDeallocateCounter=0
Function _Callocate(Byval n As Integer) As Any Ptr
  AllocateDeallocateCounter += 1
  Return Callocate(n)
End Function
Sub _Deallocate(Byval p As Any Ptr)
  AllocateDeallocateCounter -= 1
  Deallocate(p)
End Sub

CONST MAX_KEYLEN=50
CONST RUP_COLS=1 : CONST MAX_COLS=5 ' Le nombre maximal de clefs pouvant être utilisées sur la MEME liste start=0
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4)

Type ListContainer 'Data Segment Level
    Dim str_tag_C(RUP_COLS+1 to MAX_COLS-1) As String
    Dim str_item as String : Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag(0 to RUP_COLS) As String : Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode : Dim BranchCount As uInteger=0
End Type
Type ListContext ' Branch context Level   
    Dim  As ListNode Ptr pNode, pFirstNode, pLastNode : Dim As String LcHashTag : Dim  As uInteger  uCount : Dim As uByte bLcHashLen
End Type

Type List
    Declare Constructor() : Declare Destructor()     
    Private:
    Dim As zString Ptr Listptemp=_Callocate(MAX_KEYLEN), Listptemp2=_Callocate(MAX_KEYLEN), zp3=_Callocate(1) 
    Dim  As ListContext Lcontext(0 to MAX_COLS-1), Tracks(0 to MAX_COLS-1)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake ', pTestContainer, pTestContainer2
    Dim As String sSearchTag, sLatestHTag
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt : Dim IsDestroyed as uByte=0
    Dim uTag As Byte=0 : Dim bSearchRes As Byte=0 : Dim bRHByPass As Byte=0 : Dim bHashStepRev As Byte=0 : Dim bfStepZero As Byte=0 : Dim bTrackingMethod As Byte=0 : Dim bTracking As Byte=0 : Dim bHTMethod As Byte=0
    Dim uSortTag As Byte=0 : Dim bSortMT As Byte=1
    Dim bNFmethod As Byte=1 : Dim bRHmethod As Byte=-1 : Dim bHashLen As uByte=1  : Dim bAutoCursor As Byte=1 : Dim bSeekMethod As Byte=2 : Dim bBranchCountDown As Byte=0 : Dim  bPickReduce As Byte=0
    Dim As String  Str_tmp, Str_tmp2, str_arbo
    Declare Property AllowCake() As ListNode Ptr                      ' Cooking here
    Declare Property AllowPanCake() As ListContainer Ptr          ' No comment
    Declare Property AllRecycle() As uInteger    
    Declare Property Branch() As Byte                                        ' Descend dans la liste enfants, creation de nouvelles entrées
    Declare Property UpLevel() As Byte                                      ' Revient à la liste parente   
    Declare Property NodeRecycle() as Byte                              ' Supression en décalé (NodeFlat)
    Declare Property NodeRecycle2() as Byte                            ' Supression en décalé (RestoreHash)
    Declare Property RootPrivate As Byte                                   ' Accès direct rapide à la racine
  '  Declare Property AllOfPrivate As uInteger
    Declare Property FlatStack(uB as uByte) As Byte                 ' Construction de la Flat List avec retour à la racine(0) ou accès à la flat liste (1)
    Declare Property BCountDown(i As Byte) As Byte                ' CountDown calculation   
 '   Declare Property TrackCompute As Byte
    Declare Property ValPrivate(str_Value As String) As Byte
    Declare Property ValPrivate As String
    Public:    
    'Special features - Private declared Public   
    Declare Property AllOfPrivate As uInteger
    Declare Property TrackCompute As Byte
    Declare Property SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr
    Declare Property SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr 
    Declare Property Relation1 As ListNode Ptr
    Declare Property Relation2 As ListNode Ptr
    Declare Property GiveBranch As ListNode Ptr
    Declare Property GiveFlat As ListNode Ptr
    Declare Property GiveGarbage As ListNode Ptr
    Declare Property GivePanCake As ListContainer Ptr
    Declare Property GiveLastPanCake As ListContainer Ptr
    Declare Property GivePanCakeCount As uInteger
    'Flat control
    Declare Property Tag(str_Tag As String) As Byte                 ' Create a new ListNode with Key=str_Tag OR retrieve position of an existing Tag
    Declare Property Tag As String                                            ' Return current Tag value in a list =Tag(0)
    Declare Property Tag(iTag As Integer) As String                  ' Return current Tag value of the specified entry in array
    Declare Property HasTag(str_Tag As String) As Byte           ' Return 1 if Tag exists
    Declare Property BlindTag(str_Tag As String) As Byte          ' Create a new ListNode with Key=str_Tag at end of the list
    Declare Property RwTag(s_Tag As String) As Byte               ' Rewrite Tag Value of current Node : if current node is Hashed, just rewrite HashTag Value not effective Key value
    Declare Property RwTag1(s_Tag As String) As Byte                ' Rewrite Tag Value(1)
    Declare Property RwTag2(s_Tag As String) As Byte                ' Rewrite Tag Value(2)
    Declare Property RwTag3(s_Tag As String) As Byte                ' Rewrite Tag Value(3)
    Declare Property RwTag4(s_Tag As String) As Byte                ' Rewrite Tag Value(4)
    Declare Property ColTags As Byte                                       ' Renvoie le numéro de la colonne de tag active   
    Declare Property SeekMethod(i as Byte) As Byte                 ' Method for Tag(string), HasTag(string), HashTag(string), HasHashTag and HasKey: 1(default)=seek from First to Last | 2: seek from Lastnode to firstNode | 0 :seek from currentnode to last node (Flat multikeys)
    Declare Property ColTags(i as Byte) As Byte                        ' Définie la colonne de tag active de 0 à MAX_COLS, par défaut 0
    Declare Property ColSort(i as Byte) As Byte                         ' Définie la colonne de tri active de 0 à MAX_COLS, par défaut 0
    Declare Property AllOf As uInteger                                       ' Return number of node in  considered Flat List (root or branch), set position to the first node of current branch
    Declare Property Count As uInteger                                     ' Return current node Count of considered Flat List
    Declare Property First As Byte                                              'Set current node to first node considering flat list (root or branch)   
    Declare Property Last As Byte                                              'Set current node to Last node considering flat list (root or branch)       
    Declare Property Val(str_value As String) As Byte                ' Assign a string (+50 len) to the current node that is identified by a Tag
    Declare Property Val As String                                             ' Return current node string datas   
    Declare Property ValTag(str_value As String) As String        ' Considering current Flat list (root or branch as a flat list) return string data identified by Key=str_Tag
    Declare Property fStep As Byte                                            ' FOR EACH - While MyList.fStep : .. : Wend Jump to next node till current flat list end
    Declare Property fStepRev As Byte                                     ' FOR EACH - Idem fStep Jump to previous node till current flat list reach firstnode
    Declare Property bStep As Byte                                           ' FOR NEXT - For i=1 to MyList.AllOf : MyList.bStep : ..... : Next i    -> Jump to next node (NO CHECK)
    Declare Property BlindStep As Byte                                     ' FOR EACH - While MyList.BlindStep : .. : Wend -And- FOR NEXT - For i=1 to MyList.AllOf : MyList.BlindStep : ..... : Next i  Jump to next node  (check)   
    Declare Property BlindStep(i As Integer) As Byte                  ' Jump to +/-n nodes BlindStep(0) equiv Last : goto LastNode  (NO CHECK)
    Declare Property fMove(i As Integer) As Byte                      ' Move a node +/- n positions
    Declare Property fSortMethod(bsortM As Byte) As Byte       ' 1 or any = ascending / -1=descending
    Declare Property fSort As Byte                                             'Flat sort
    'Hash control handling
    Declare Property Root As Byte                                           ' Check/Restore List integrity & set cursor to First node of root flat list - Shall be called before HashStep or After NodeFlat or RestoreHash
    Declare Property FlatStack As Byte                                    ' Flat List Access : use it before RestoreHash
    Declare Property RootNode As Byte                                  ' Set cursor to Root node of root flat list
    Declare Property EndNode As Byte                                   ' Set cursor to the last logical node  ( = While MyList.HashStep : Wend ) which is the last node of the last branch of last root flat node
    Declare Property HashStep As Byte                                   ' FOR EACH - recursive  parse property : syntax : While MyList.HashStep=1 : ... : Wend
    Declare Property HashStepRev As Byte                            ' FOR EACH - idem HashStep
    Declare Property KeyStep As Byte                                      ' FOR EACH - While MyList.KeyStep=1 : ... : Wend idem HashStep but show only Keys tagged by user, not the tree structure
    Declare Property KeyStepRev As Byte                               ' FOR EACH - idem KeyStep
    Declare Property HashTag(str_Tag As String) As Byte       ' Build a hash Key on str_Tag, Return 1 if already exits otherwise return 0
    Declare Property HashSort(ub as Byte) as Byte                  ' 0=No sort on mapping, 1=sort on mapping or remapping via restorehash
    Declare Property Sort As Byte 
    Declare Property Sort(SessionId As String) As Byte 
    Declare Property HashTag As String                                  ' Return Hash key value of current node
    Declare Property HasHashTag(str_Tag As String) As Byte ' Return 1 if str_Tag is a hash key otherwise return 0
    Declare Property HasKey(str_Tag As String) As Byte          ' Idem HasHashTag Return 1 only for values specified with HashTag (not all cascaded index values)
    Declare Property HashLen(bHashLen As uByte) As Byte  ' Longueur des clefs en cascade
    Declare Property NFmethod(i As Byte) As Byte                  ' Determine le fonctionnement de NodeFlat : NFmethod=-1 node=>GarbageCollector  NFmethod=0 node=>FlatList sauf parents reliquataires NFmethod=1 node=>FlatList même les nodes parents contenant toujours des dépendances NFmethod=3 node+Childrens=>FlatList
    Declare Property NFrecursive(i As Byte) As Byte               ' NFrecursive=0 Standard / NFrecursive=1 parents nodes auto send to garbage collector till no other child and till they are not keys
    Declare Property NodeFlat As Byte                                   ' Déréférence une arborescence de clefs (un HashTag), et traite les données en conséquence
    Declare Property RHmethod(i As Byte) As Byte                 ' Determine le fonctionnement de RestoreHash par rapport aux doublons : RHmethod=-1 : Hashnode->GarbageCollector  / RHmethod=0 : no swap / RHmethod=1 : Hashnode->FlatList
    Declare Property RestoreHash As Byte                             ' Envoi un node de la Flat List en Hash List (réindexation)
    'Hash Control - special
  '  Declare Property HashMap(str_Tag() As String Ptr) As Byte ' to do
  '  Declare Property HashMap As Byte  ' to do
    'Flow control
    Declare Property BranchCountDown(i As Byte) As Byte     ' 1/0 Activate(1) or desactivate(0) BranchCountDown, default 0
    Declare Property BranchCount As uInteger                        'Return Branch Count
    Declare Property Up As Byte                                              'idem UpLevel
    Declare Property Down As Byte                                         'idem Branch but prevent from creating an orphan sublist entry
    Declare Property AutoCursor(i As Byte) As Byte                 'Method for HasTag(string), HasHashTag and HasKey:  1(default)=move current to found on success (HasHashTag), 0=do nothing current node is unchanged, 2=move current to found on success (HasKey), 3=move on partial success
    Declare Property HoldBack As Byte
    Declare Property HoldBack(i As Byte) As Byte
    Declare Property TrackStep As Byte                                ' -SELECTIVE- FOR EACH - While MyList.TrackStep=1 : ... : Wend : selective PARSE only Keys marked for tracking by HoldBack
    Declare Property Track As Byte
    Declare Property Track(i As Byte) As Byte
    Declare Property TrackSet As Byte
    Declare Property TrackSet(i As Byte) As Byte
    Declare Property IsTracked As Byte
    Declare Property TrackMethod(by As Byte) As Byte       ' MyList.TrackMethod(0)=might be faster / MyList.TrackMethod(1)=more secure
    Declare Property Aside As Byte                                      ' Memorise ListNode ptr dans le pointeur n°0
    Declare Property Aside(i As Byte) As Byte                       ' Memorise ListNode ptr dans le pointeur n°i
    Declare Property Recover As Byte                                 ' Repositionne l'élément courant de la liste sur celui mémorisé par Take, si cet élément existe toujours, sinon renvoie False
    Declare Property Recover(i As Byte) As Byte                  ' Repositionne l'élément courant de la liste sur celui mémorisé par Take(i)
    Declare Property Follow(pList As List) As Byte
    'Memory management
    Declare Property FlatCount As uInteger                         ' Return number of values stored in Flat List
    Declare Property GarbageCount As uInteger                 ' Return number of nodes available in garbage collector
    Declare Property ContainerCount As uInteger                ' Return number of nodes container available in hidden garbage collector
    Declare Property NodeCount As uInteger                      ' Return number of nodes including not visible ones
    Declare Property GarbageFlat As Byte                            'Send all Flat List to GarbageCollector
    Declare Property Recycle As uInteger                            'AllFlat+GarbageCollector : détruit une arborescence et envoi tout en GarabgeCollector - do NOT garbage protected flat list
    Declare Property DropAll As uInteger                              'Remove all elements in list, except a 5/6 listnodes subset                         
    Declare Property Destroy As Byte                                   'Manual destructor
    'List Data Exchange
    Declare Property SnatchBelow(pList As List) As Byte        'Snatch a whole branch from another List Below current node
    Declare Property Snatch(pList As List) As Byte                 ' Snatch a whole branch from another List to next node
    Declare Property FlatSnatch(pList As List) As Byte            'Target's Flat list is transfered to current list
    Declare Property GarbageSnatch(pList As List) As Byte    'Target's Garbage Collector is transfered to current list
    Declare Property CopyCat(pList As List) As Byte
    'Debug
    Declare Property NextNode As String        
  '  Declare Property PrevNode As String      
End Type

' to do : HashMap / Tris / SmartPatterns (?)  /
' to do : test++%TrackSet / BranchUp /
' BUGs :
Property List.NextNode As String : Dim str_tmp as string="-" : If pNode->pNext<>0 Then : this.Aside : pNode=pNode->pNext : str_tmp= "next tag=" & pNode->Tag(0) & " & next hashtag=" & this.HashTag : this.Recover : Return str_tmp : End If : End Property
'Property List.PrevNode As String : Dim str_tmp as string="-" : If pNode->pPrev<>0 Then : this.Aside : pNode=pNode->pPrev : str_tmp= " prev tag=" & pNode->Tag(0) & " & prev hashtag=" & this.HashTag  & "  branch=" & Str(pNode->pBranch) : this.Recover : Return str_tmp : End If : End Property

'==========================================================================================CONSTRUCTOR & DESTRUCTOR  :  this.pFirstNode->pBranch->pBranchLastNode=0
Constructor List
    pFlatRoot = _Callocate(Len(ListNode)) : pNode = _Callocate(Len(ListNode)) : this.uNodeCOUNT+=2  ' Moment angulaire(petite masse)
    pPanCakeGarbage=_Callocate(Len(ListContainer)) : pPanCakeGarbage->pNextContainer=pPanCakeGarbage ': pTestContainer=pPanCakeGarbage ' Moment Angulaire(petite masse)
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag(0) = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT
    this.Root : this.AllOf
End Constructor
Destructor List : this.Destroy : End Destructor

'==========================================================================================TYPE LIST PRIVATE PROPERTIES
Property List.AllowCake As ListNode Ptr ' This.Vralloc
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext ' uGarbCt>1 ' If pTemp<>0 Then : If pTemp->pNext=0  Then  : pTemp=pGarbage : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 :  Return pTemp : End If  : End If
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1 : ' And pTemp<>0 ' pTemp->pNext=0 : pTemp->pPrev=0 : pTemp->pBranch=0 : 
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ': this.pLastLASTNode=pTemp ' Moment Angulaire(petite masse)         
    End If : Return pTemp
End Property
Property List.AllowPanCake As ListContainer Ptr
    Dim pPanTemp As ListContainer Ptr : dim uB As uByte
    If pPanCakeGarbage->pNextContainer<>pPanCakeGarbage Then
        pPanTemp=pPanCakeGarbage->pNextContainer : pPanTemp->str_item="" : For uB=RUP_COLS+1 To MAX_COLS-1 : pPanTemp->str_tag_C(uB)="" : Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else : pPanTemp=_Callocate(Len(ListContainer)) ': If pTestContainer2=0 Then : pTestContainer2=pPanTemp : End If  ' : pPanTemp->str_item=""  ' Moment Angulaire(petite masse)
    End If : Return pPanTemp
End Property

Property List.AllRecycle As uInteger
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext       
    Dim NbCollected As uInteger=0 :' Dim iLong As uInteger=0
    If pGarbage->ListData<>0 Then : pGarbage->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pGarbage->ListData : pGarbage->ListData=0 : uContainerGarbCt+=1 : End If
    If pLocalMove=pLastLASTNode Then : pLastLASTNode=pLastLASTNode->pPrev : End If : this.NodeRecycle : This.RootPrivate
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode= this.pGarbage->pNext : Else : pNode= this.pFirstNode->pNext : End If  : If pNode=0 Then : Return 0 : End If
    If pNode <>0 Then
        Do
            If pNode->Tag(0)<>LIST_RES And pNode->pBranch<>0 Then   
                pNode->pNext->pPrev=pNode->pBranch->pBranchLastNode : pNode->pBranch->pBranchLastNode->pNext=pNode->pNext
                pNode->pNext=pNode->pBranch : pNode->pBranch->pBranch=0 : pNode->pBranch=0
                pNode->pNext->pPrev=pNode : pNode->pNext->pBranchLastNode=0 ' pNode->pNext->Tag(0)=LIST_DEL : 
            Else 
                If this.pNode->pNext<>0 Then 
                    pNode->Tag(0) = LIST_DEL : pNode->Tag(1)="" : NbCollected +=1 ': iLong+=1
                    If pNode->ListData<>0 Then : pNode->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pNode->ListData : pNode->ListData=0 : uContainerGarbCt+=1 : End If                           
                    this.pNode=this.pNode->pNext 
                End If                
            End If
        Loop Until pNode->pNext=0 '  pNode=this.pLASTNode Or pNode=pWhyteMove
    End If 
    If NbCollected>0 Then : This.uGarbCt+=NbCollected : uCount=0 : this.pFirstNode->BranchCount=this.uCount : pLastNode=pNode : If pFirstNode=pFirstFIRSTNode Then : pLastLASTNODE=pNode : End If : End If   
    This.RootPrivate : pGarbage=pLastNode->pPrev :pTemp=pNode : pNode=pGarbage : this.Val(LIST_DEL) : pNode=pTemp 
    Return NbCollected
End Property

Property List.Branch As Byte
    Dim pTemp As ListNode Ptr :  Dim pTemp1 As ListNode Ptr   
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp = this.pNode
    If this.pNode->pBranch=0 Then ' this.NewHash(this.pNode)
        pTemp1 = this.pLastNode : this.uCount+=1 : pTemp1->pNext = this.AllowCake 'And eat it
        pTemp1->pNext->pPrev = pTemp1 : pTemp1->pNext->Tag(uTag) = LIST_RES
        pTemp1 = pTemp1->pNext : this.pLastNode = pTemp1 : pNode=pTemp1  ' this.BlindTag(LIST_RES) :
        this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp
        pTemp->pBranch=this.pNode : pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
        this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : this.bSearchRes = 0 : Return 0
    Else 'Branche déjà créée
        this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
        this.pLastNode = this.pNode->pBranch->pBranchLastNode         
        this.pNode = this.pNode->pBranch : this.bSearchRes = 0 : Return 1
    End If   
End Property

Property List.UpLevel As Byte   
    If this.pFirstNode->pPrev = 0 Then : Return 0 : End If
    If this.pFirstNode->pBranch <> 0 Then ' Retour node de départ pour faciliter un parcours éventuel
        this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        this.pFirstNode = this.pFirstNode->pPrev : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode         
        this.bSearchRes = 0 ': this.sSearchTag = ""
        Return 1
    Else : Return 0
    End If               
End Property

Property List.NodeRecycle as Byte
    If pLocalMove<>0 Then 'pLocalMove est un node à suppression décalée       
        pLocalMove->pPrev=this.pFlatRoot : pLocalMove->pNext=this.pFlatRoot->pNext : pLocalMove->Tag(0)=LIST_DEL : pLocalMove->pBranch=0 : pLocalMove->Tag(1)=""
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pLocalMove->ListData : pLocalMove->ListData=0 : uContainerGarbCt+=1 : End If
        this.pFlatRoot->pNext->pPrev=pLocalMove : this.pFlatRoot->pNext=pLocalMove : this.uGarbCt+=1
        pLocalMove = 0       
    End If
    Return 1
End Property
Property List.NodeRecycle2 as Byte
    If pLocalRoot<>0 Then 'pLocalRoot est un node LIST_RES             
        pLocalRoot->pPrev=this.pFlatRoot : pLocalRoot->pNext=this.pFlatRoot->pNext : pLocalRoot->Tag(0)=LIST_DEL
        this.pFlatRoot->pNext->pPrev=pLocalRoot : this.pFlatRoot->pNext=pLocalRoot : This.uGarbCt+=1
        pLocalRoot->pBranch->pBranch=0 : pLocalRoot->pBranch->pBranchLastNode=0 : pLocalRoot->pBranch->BranchCount=0 :
        pLocalRoot->BranchCount=0 : pLocalRoot->pBranch=0 : pLocalRoot = 0
    End If
    Return 1
End Property

Property List.RootPrivate As Byte   
    this.AllOfPrivate : While UpLevel : Wend    ' While this.pFirstNode->pBranch <> 0 : this.UpLevel : Wend   ' 
    this.pFirstNode = this.pFirstFIRSTNode : this.bSearchRes = 0 : this.sSearchTag = ""
    this.pNode = this.pGarbage
    Return 1   
End Property
Property List.AllOfPrivate As uInteger
    this.pNode = this.pFirstNode
    If this.pFirstNode=this.pFirstFIRSTNode Then           
        this.pNode = this.pGarbage
        If pWhyteMove<>0 And pWhyteMove<>pLastNode Then  'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc
            If pWhyteMove->pNext<>0 Then : pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode :  End If     
            pLastNode=pWhyteMove : pLastNode->pNext=pFirstFIRSTNode '0
        End If   
    End If : Return this.Count
End Property

Property List.FlatStack(uB As Ubyte) As Byte
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    Dim pTemp1 As ListNode Ptr
   ' While this.UpLevel : Wend
    This.RootPrivate : 
    this.pNode=this.pFlatRoot : this.Branch
    If this.pLastNode=this.pFlatRoot->pBranch Then
        If this.pEndFlat<>0 Then : this.pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=this.pFlatRoot->pBranch : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1         
        End If
    ElseIf this.pLastNode<>this.pEndFlat Then           
        If this.pEndFlat<>0 Then
            this.pEndFlat->pPrev->pNext=this.pEndFlat->pNext : this.pEndFlat->pNext->pPrev=this.pEndFlat->pPrev
            this.pEndFlat->pPrev=this.pLastNode : this.pLastNode->pNext=this.pEndFlat : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If                       
    End If     
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If uB=0 Then : this.UpLevel : End If : this.AllOfPrivate
    Return 1
End Property
Property List.BCountDown(i As Byte) As Byte : Dim pTemp As ListNode Ptr=pFirstNode : While pTemp->pPrev<>0 : If pTemp->pBranch<>0 Then : pTemp->pBranch->BranchCount+=i : End If : pTemp=pTemp->pPrev : Wend : Return 1 : End Property
Property List.TrackCompute As Byte
    Dim As ListNode Ptr pTemp1=pNode 
    While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage
        If pTemp1->pBranch<>0 Then : pTemp1=pTemp1->pBranch->pPrev : Exit While : End If 
        pTemp1=pTemp1->pPrev        
    Wend 
    If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
    pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : Return 1
End Property
Property List.ValPrivate(str_value As String) As Byte : If this.pValTmp->ListData=0 Then : this.pValTmp->ListData=this.AllowPanCake : End If : this.pValTmp->ListData->str_item=str_value : Return 1 : End Property
Property List.ValPrivate As String : If this.pValTmp->ListData=0 Then : Return "" : End If : Return this.pValTmp->ListData->str_item : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES destination is PRIVATE USE
Property List.SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr    
    pNode->pBranchLastNode=pRelNode 
    Return pNode 
End Property
Property List.SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr 
    this.pNode->BranchCount=CuInt(pRelFirstNode)
    Return pFirstNode 
End Property

Property List.Relation1 As ListNode Ptr : Return pNode->pBranchLastNode : End Property
Property List.Relation2 As ListNode Ptr : Return Cast(ListNode Ptr, pNode->BranchCount) : End Property

Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp4 , pTemp2, pTemp3 '
    If pNode->pPrev<>pFirstNode Then : pTemp4=pNode->pPrev : Else : pTemp4=pFirstNode->pBranch : End If
    bfStepZero=0
    If pNode=pLocalMove And pLocalMove->Tag(0)=LIST_RES Then : pNode=pNode->pNext
    ElseIf pNode=pWhyteMove Then : If pNode=pLastNode Then : Return 0 : Else : pTemp1=pNode->pNext : This.Root : pNode=pTemp1 : End If
    ElseIf pNode->Tag(0)=LIST_DEL Or pNode=pFlatRoot Then : Return 0 ' : End If
    ElseIf pNode=pFirstNode And pNode->pBranch<>0 Then : this.BlindStep : this.UpLevel : bfStepZero=1 : End If
    If bBranchCountDown=1 Then : this.BCountDown(-pNode->BranchCount) : End If : This.NodeRecycle
    pTemp1=pNode ' : pTemp2=pNode->pPrev : pTemp3=pNode->pNext
    If pLastNode=pFirstNode->pNext And pFirstNode<>pFirstFIRSTNode Then
        this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : this.UpLevel : this.NodeRecycle2 : bfStepZero=1 : Return pTemp1
    Else : pNode->pPrev->pNext=pNode->pNext : pNode->pNext->pPrev=pNode->pPrev : uCount-=1 : pFirstNode->BranchCount-=1
    End If
    If pTemp1=pLastNode Then : pLastNode=pTemp1->pPrev : pTemp1->pNext=0 : End If
    pNode=AllowCake : pLocalMove=pNode : pLocalMove->pPrev=pTemp2  : pLocalMove->pNext=pTemp3 : pLocalMove->Tag(0)=LIST_RES   
   ' pNode=pTemp4
    Return pTemp1
End Property

Property List.GiveFlat As ListNode Ptr   
    Dim As ListNode Ptr pTemp1, pTemp2
    If pFlatRoot->pBranch=0 Then : Return 0 : End If         
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Or pFlatRoot->pBranch->pNext=pFlatRoot->pBranch  Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev : If pTemp2=0 Or pTemp1=pTemp2 Then : Return 0 : End If
    pTemp1->pBranch=pTemp2 : pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=pFlatRoot->pBranch
    pTemp1->BranchCount=pFlatRoot->pBranch->BranchCount : uNodeCOUNT-=pFlatRoot->pBranch->BranchCount 'this.FlatCount :
    this.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If  ' this.FlatStack : uCount=0
    Return pTemp1   
End Property

Property List.GiveGarbage As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2
    If uGarbCt<2 Then : Return 0 : End If : pTemp1=pFlatRoot->pNext : pTemp2=pGarbage->pPrev : If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext=pGarbage : pGarbage->pPrev=pFlatRoot : pTemp1->pBranch=pTemp2 : pTemp1->BranchCount=uGarbCt
    uNodeCOUNT-= uGarbCt : uGarbCt=0
    Return pTemp1
End Property
Property List.GivePanCake As ListContainer Ptr
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2
    If uContainerGarbCt<2 Then : Return 0 : End If : pLastPanCake=0
    pPanTemp1=pPanCakeGarbage->pNextContainer : pPanTemp2=pPanTemp1
    While pPanTemp2->pNextContainer<>pPanCakeGarbage : pPanTemp2=pPanTemp2->pNextContainer : Wend : pPanTemp2->pNextContainer=0 : pLastPanCake=pPanTemp2
    pPanCakeGarbage->pNextContainer=pPanCakeGarbage : uContainerGivenCt=uContainerGarbCt : uContainerGarbCt=0
    Return pPanTemp1
End Property
Property List.GiveLastPanCake As ListContainer Ptr : Return pLastPanCake : End Property
Property List.GivePanCakeCount As uInteger : Return this.uContainerGivenCt : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLAT CONTROL
Property List.Tag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer Ptr
    If this.sSearchTag = str_Tag Then
        If this.bSearchRes=1 Then
            this.pNode = this.pSearchNode : Return 1 'pNode
        Else
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->Tag(uTag) = str_Tag ' pTemp->pNext->ListData = item :
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            this.pNode = pTemp : Return 0
        End If
    Else
        If this.bSeekMethod=1 Then : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then : pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
        Else
            pTemp = this.pNode : If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        End If
        If pTemp->Tag(uTag)<>str_Tag then ' New node
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->ListData = item : pTemp->pNext->Tag(uTag) = str_Tag
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If            
            If pFirstNode=pFirstFIRSTNode And pWhyteMove<>pLastNode Then ' And pWhyteMove<>0
            '    If pWhyteMove->pNext<>0 Then   'Changement de fonctionnement - Patch de compatibilité - dernier node logique à blanc/liste racine
                pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode : pLastNode=pWhyteMove : pLastNode->pNext=0
            '    End If
            End If : this.pNode = pTemp : Return 0
        End If   
    End If
    this.pNode = pTemp : Return 1 'pTemp
End Property

Property List.Tag As String
    If uTag<=RUP_COLS Then : Return this.pNode->Tag(uTag)
    ElseIf pNode->ListData=0 Then : Return ""
    Else : Return pNode->ListData->str_tag_C(uTag)
    End If
End Property
Property List.Tag(i As Integer) As String
    If i<=RUP_COLS Then : Return this.pNode->tag(i) : Else : If pNode->ListData<>0 Then : Return pNode->ListData->str_tag_C(i) : Else : Return "" : End If : End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag   
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
    Else
        pTemp = this.pNode : If pTemp=0 Then :  pTemp = this.pFirstNode : End If
        If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag(uTag) = str_Tag Then
        this.pSearchNode=pTemp : this.bSearchRes=1 : If this.bAutoCursor=1 Then : pNode=pTemp : End If : Return 1
    Else : this.bSearchRes = 0 : Return 0 : End If   
End Property

Property List.BlindTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = str_Tag
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte : If uTag<=RUP_COLS Then : this.pNode->tag(this.uTag)=s_Tag : Return 1 : Else : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(uTag)=s_Tag : Return 1 : End If : End Property
Property List.RwTag1(s_Tag As String) As Byte : this.pNode->tag(1)=s_Tag : Return 1 : End Property
Property List.RwTag2(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(2)=s_Tag : Return 1 : End Property
Property List.RwTag3(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(3)=s_Tag : Return 1 : End Property
Property List.RwTag4(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(4)=s_Tag : Return 1 : End Property

Property List.ColTags As Byte : Return(this.uTag) : End Property
Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uSortTag=i : Return 1 : End If : End Property


Property List.SeekMethod(i as Byte) As Byte : If i=0 Or i=1 Or i=2 Then : this.bSeekMethod=i : Return 1 : Else : Return 0 : End If : End Property
Property List.AllOf As uInteger
    Dim pContextRetour As ListContext
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Return 0 : End If :
    Dim  As ListNode Ptr pTemp, pTemp2 : If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If
    If pFirstNode=pFIRSTFIRSTNode Then : If pLastNode<>pWhyteMove Then : this.Root : End If : End If
    this.NodeRecycle : this.NodeRecycle2
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.AllOfPrivate
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : uCount=pContextRetour.uCount
    pNode=AllowCake : pLocalMove=pNode 
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode->pNext=pGarbage->pNext : Else : pNode->pNext=pFirstNode->pNext : End If
    If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    Return this.Count
End Property
'Property List.Count As uInteger : If pWhyteMove=pLastNode And pFirstNode=this.pFirstFIRSTNode Then : Return this.uCount-1 : End If : Return this.uCount : End Property
Property List.Count As uInteger 
    Dim pTemp As ListNode Ptr 
    If pWhyteMove=0 And pFirstNode=pFIRSTFIRSTNode Then : pTemp=this.pNode : this.uCount-=2 : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : Return this.uCount 'And this.pLastNode->Tag(0)<>""
End Property

Property List.First As Byte : If pFirstNode=pFirstFIRSTNode Then : pNode=pGarbage : Else : this.pNode=This.pFirstNode->pNext : End If : Return 1 : End Property
Property List.Last As Byte : this.pNode=This.pLastNode : Return 1 : End Property

Property List.Val(str_value As String) As Byte : this.pValTmp=this.pNode : this.ValPrivate(str_value) : Return 1 : End Property
Property List.Val As String : pValTmp=pNode : Return this.ValPrivate : End Property
Property List.ValTag(str_value As String) As String
    If bSearchRes=1 Then : If str_value=this.Tag(0) Then : pValTmp=pSearchNode : Return this.ValPrivate : End If
    ElseIf this.HasTag(str_value)=1 Then : pValTmp=pSearchNode : Return this.ValPrivate
    End If : Return("")
End Property

Property List.fStep As Byte : If pNode=pLastNode Or bfStepZero=1 Or pNode->pNext=pWhyteMove Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pNext : Return 1 : End If : End Property '
Property List.fStepRev As Byte : If pNode->pPrev=pFirstNode Or pNode->pPrev=pGarbage Or bfStepZero=1 Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pPrev : Return 1 : End If : End Property
Property List.bStep As Byte : this.pNode = this.pNode->pNext : Return 1 : End Property
Property List.BlindStep As Byte : If this.pNode->pNext<>0 Then : this.pNode = this.pNode->pNext : Return 1 : Else   : Return 0 : End If : End Property ' : Print "*Warning : list parse or count down error"
Property List.BlindStep(top As Integer) As Byte
    Dim As Integer i : Dim As Byte istep
    If top>0 Then : istep=1 : For i=1 To top step istep : this.pNode = this.pNode->pNext : Next i : ElseIf top = 0 Then : this.pNode = this.pLastNode : Return 1 : Else : istep=-1 : For i=-1 To top step istep : this.pNode = this.pNode->pPrev : Next i : End If
    Return 1
End Property

Property List.fSortMethod(bsortM As Byte) As Byte : If bsortM=-1 Then : this.bSortMT=-1 : Else : this.bSortMT=1 : End If : Return 1 : End Property
Property List.fSort As Byte
    Dim As ListNode Ptr pTemp1=pFirstNode, pTemp2, pTemp3, pTemp4
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If
    pTemp4=pTemp1: pTemp1=pTemp1->pNext 
    If pTemp1=pLastNode Then : Return 1 : End If
    If  this.bSortMT=1 Then
        While pTemp1->pNext<>pLastNode
            pTemp2=pTemp1->pNext        
            If pTemp2->Tag(uSortTag) < pTemp1->Tag(uSortTag) Then    
                pTemp3=pTemp1
                While pTemp2->Tag(uSortTag) < pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                    pTemp3=pTemp3->pPrev
                Wend
                pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext
                pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
                pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
                pTemp2=pTemp1'->pNext 
            End If
            pTemp1=pTemp2
        Wend
    Else
        While pTemp1->pNext<>pLastNode
            pTemp2=pTemp1->pNext        
            If pTemp2->Tag(uSortTag) > pTemp1->Tag(uSortTag) Then    
                pTemp3=pTemp1
                While pTemp2->Tag(uSortTag) > pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                    pTemp3=pTemp3->pPrev
                Wend
                pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext
                pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
                pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
                pTemp2=pTemp1'->pNext 
            End If
            pTemp1=pTemp2
        Wend
    End If
    
    If pFirstNode<>pFirstFIRSTnode Then 
        If pLastNode->Tag(uSortTag) < pTemp1->Tag(uSortTag) And this.bSortMT=1 Then
           pTemp2=pLastNode
           pTemp3=pTemp1
            While pTemp2->Tag(uSortTag) < pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                pTemp3=pTemp3->pPrev
            Wend
            pTemp2->pPrev->pNext=pTemp2->pNext : pTemp2->pNext=0
            pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
            pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
            pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pLastNode
        ElseIf pLastNode->Tag(uSortTag) > pTemp1->Tag(uSortTag) And this.bSortMT=-1 Then
           pTemp2=pLastNode
           pTemp3=pTemp1
            While pTemp2->Tag(uSortTag) > pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                pTemp3=pTemp3->pPrev
            Wend        
            pTemp2->pPrev->pNext=pTemp2->pNext : pTemp2->pNext=0
            pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
            pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
            pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pLastNode
        End If
    End If
    Return 1
End Property

Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - Alpha2.04 - Imp. BUGFIX 17/09

Post by Lost Zergling »

ARCHIVE 02 - 2018/09/20
Code PART 2 :

Code: Select all

Property List.fMove(nbMove As Integer) As Byte
    Dim As ListNode Ptr pFirst, pTemp : Dim i As Integer=0
    If pFirstNode=pFirstFIRSTnode Then : pFirst=pGarbage : Else : pFirst=pFirstNode : End If
    If pNode=pLastNode Then : pLastNode=pNode->pPrev : Else : pNode->pNext->pPrev=pNode->pPrev : End If
    pNode->pPrev->pNext=pNode->pNext : pTemp=pNode
    If nbMove>0 Then : For i=0 To nbMove : If pNode<>pLastNode Then : pTemp=pTemp->pNext : End If : Next i     
    Else : For i=nbMove To 0 : If pTemp<>pFirstNode Then : pTemp=pTemp->pPrev : End If : Next i         
    End If
    If pTemp<>pLastNode Then : pTemp->pNext->pPrev=pNode : pNode->pNext=pTemp->pNext
    Else : If  pTemp->pNext<>0 Then : pNode->pNext=pTemp->pNext : End If : pLastNode=pNode
    End If
    pTemp->pNext=pNode : pNode->pPrev=pTemp
    Return 1
End Property


'==========================================================================================TYPE LIST PUBLIC PROPERTIES - HASH CONTROL
Property List.Root As Byte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext   
    If bTracking=1 Or pFirstNode->Tag(0)<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If :' this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode    
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Beep : Return 0 : End If 
     this.RootPrivate : this.NodeRecycle : this.NodeRecycle2 : bSearchRes=0 : pTemp2=0 : this.bHashStepRev=0
    'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc qui ne soit jamais 'flaté'
    If this.pWhyteMove<>0 Then
        pWhyteMove->Tag(0)=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag(0)<>LIST_RES Then            
            If pWhyteMove->pPrev<>0 Then : this.pWhyteMove->pPrev->pNext=this.pWhyteMove->pNext : End If
            If pWhyteMove->pNext<>0 Then :this.pWhyteMove->pNext->pPrev=this.pWhyteMove->pPrev : End If         
        End If       
    End If ' If pPanCakeGarbage=0 Then : pPanCakeGarbage=AllowPanCake : pPanCakeGarbage->pNextContainer=pPanCakeGarbage : End If
    If pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : this.Val(LIST_DEL) : pGarbage->pPrev=pFlatRoot 
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If : this.pNode = pGarbage
    End If
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    this.FlatStack(0)
    'Corrections  - Patch de compatibilité - : pFlatRoot se balade, il faut le remettre au début -
    If pFlatRoot->pPrev<>0 Then : pFlatRoot->pPrev->pNext=pFlatRoot->pNext : End If : If pFlatRoot->pNext<>0 Then :  pFlatRoot->pNext->pPrev=pFlatRoot->pPrev : End If
    pFlatRoot->pPrev=this.pFirstFIRSTNode : pFlatRoot->pNext=this.pFirstFIRSTNode->pNext : If this.pFirstFIRSTNode->pNext<>0 Then : this.pFirstFIRSTNode->pNext->pPrev=pFlatRoot : End If : this.pFirstFIRSTNode->pNext=pFlatRoot
    'Changement de fonctionnement - Patch de compatibilité - pLastLAST devient dernier node LOGIQUE : on le remet à jour
    If this.pFirstFIRSTNode->pBranchLastNode<>0 Then
        pTemp=this.pFirstFIRSTNode->pBranchLastNode : While pTemp->pBranchLastNode<>0 And pTemp<>pTemp2 : pTemp2=pTemp : pTemp=pTemp->pBranchLastNode : Wend : this.pLastLASTNode=pTemp        
    End If
    'NodeFlat+Restorehash nécessite la présence d'un dernier node fictif
    If this.pLastNode->Tag(0)<>"" Then : If pWhyteMove<>0 Then : this.AllOf  : Else : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : End If
  '  If this.pLastNode->Tag(0)<>"" Then : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If
    this.pNode=pGarbage : this.uCount=this.pFirstFIRSTNode->BranchCount : this.pLastLASTNode->pPrev->pNext=this.pLastLASTNode
    If this.pLastLASTNode->pNext->Tag(0)=LIST_RES Then : this.pLastLASTNode->pNext=0 : End If
  ' Option for .Root become compatible with Rev parse with no need to jump to Last node (List.Last)
  '  If pLocalMove=pNode And pNode->pNext=pGarbage->pNext Then : Return 1 : End If
    this.pNode=AllowCake : pNode->Tag(0)="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext
    If pLastNode=pWhyteMove Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If 
    this.NodeRecycle2 : this.pFirstNode->BranchCount=this.uCount : this.pFirstNode->pBranchLastNode=this.pLastNode
    Return 1   
End Property

Property List.FlatStack As Byte : this.FlatStack(1) : this.AllOf : bSearchRes=0 : Return 1 : End Property
Property List.RootNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pFirstFIRSTNode : Return 1 : End Property
Property List.EndNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pLastLASTNode : Return 1 : End Property

Property List.HashStep As Byte
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount '
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If ' If pNode=pWhyteMove Then : Return 0 : Else : Return 1 : End If
    Wend : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

Property List.HashStepRev As Byte
    this.bHashStepRev=1   
    While this.pnode->pBranch <> 0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.AllOf : If this.pnode <> this.pFirstNode->pNext And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    While pFirstNode->pBranch<> 0
        pNode=pFirstNode->pBranch :' pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode :
        pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext  And pnode->pPrev->Tag(0)<>LIST_RES Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If
    Wend : Return 0
End Property
Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property

Property List.HashTag(str_Tag As String) As Byte    
    Dim As ListNode Ptr pTemp,  pTemp02, pTemp03 ', pTemp04 
    Dim As uInteger i=0, iLen=Len(str_tag), iLenStrTmp, iLenpNode, iLenCumul, iLenDiff
    Dim As uByte HadHashTag=1, istep=this.bHashLen, IsLast=0, IsPt2Swp=0, IsPtSwp=0, ByPass=0, bSeekMethod_TMP=bSeekMethod
    Dim As zString Ptr zp1, zp2, Listptemp2_b, Listptemp_b
    If iLen>MAX_KEYLEN Then : Listptemp2_b=_CAllocate(iLen+1) : Swap Listptemp2,Listptemp2_b : IsPt2Swp=1 : End If
    Str_tmp2 = str_Tag
    If bTracking=1 And bTrackingMethod=0 Then '  This.TrackCompute()       
        pTemp=pNode : While pTemp->Tag(0)<>LIST_RES And pTemp<>pGarbage : pTemp=pTemp->pPrev : Wend : If pTemp=pGarbage Then : pTemp=pFirstFIRSTNode : End If
        pFirstNode=pTemp : pLastNode=pTemp->pBranchLastNode : uCount=pTemp->BranchCount
    End If
    If pFirstNode<>pFirstFIRSTNode Then
        If pLatestHTag=pNode Then : Str_tmp=sLatestHTag
        Else : pNode=pFirstNode->pNext : Str_tmp=this.HashTag
        End If : iLenStrTmp=Len(Str_tmp) : If iLenStrTmp>MAX_KEYLEN Then : Listptemp_b=_CAllocate(iLenStrTmp+1) : Swap Listptemp,Listptemp_b : IsPtSwp=1 : End If
        If iLen>iLenStrTmp Then : iLenDiff=iLen-iLenStrTmp : End If
        *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
        *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=istep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
        If *Listptemp=*Listptemp2 Then' *Alternative to If Left(Str_tmp,istep)=Left(str_tag,istep) Then
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            iLenpNode=Len(pNode->Tag(uTag)) : While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) : Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount 
       '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext : 
            iLenpNode=Len(pNode->Tag(uTag)) : iLenStrTmp=Len(Str_tmp) : i=1
          '  zp2=Listptemp2 : zp2+=iLenStrTmp : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,iLenStrTmp)
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            While Left(str_tag, iLenStrTmp)<>Str_tmp
                Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
            Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount             
            iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode 
            If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode 
       End If
    End If
    If i=0 Then  '---------------- this.RootPrivate / this.AllOfPrivate
        pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode
        While this.pFirstNode->pPrev<>0
            this.pNode = this.pFirstNode->pBranch : this.pFirstNode = this.pFirstNode->pPrev
        Wend : this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode  ' this.pNode = this.pGarbage : 
        pTemp02=pGarbage : bSeekMethod_TMP=1
    End If : iLenCumul=0
    *Listptemp2=str_Tag : zp1=Listptemp2 ' * Alternative to Mid   
    For i=1 to Len(str_Tag) step istep
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid :  Str_tmp=Mid(str_Tag,i, istep)
        iLenCumul+=iStep
        If bHTmethod=0 Then
            If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
            Else : pTemp = pTemp02 : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
            End If
        Else
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                While ( pTemp->Tag(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else
                pTemp=pTemp02 : While (pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend                
                If pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
            End If
        End If       
        If pTemp->Tag(uTag)=Str_tmp Then : this.pNode = pTemp
        ElseIf bHTmethod=1 And IsLast=0 Then
             pTemp03=AllowCake : this.uCount+=1
            pTemp03->pNext=pTemp : pTemp03->pPrev=pTemp->pPrev : pTemp->pPrev->pNext=pTemp03 : pTemp->pPrev=pTemp03          
            If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pTemp03->Tag(uTag) = Str_tmp : HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03
        Else ' If pTemp=pTemp02 Then : this.BlindTag(Str_tmp)
            pTemp03 = this.pLastNode : this.uCount+=1 :
            pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode : pTemp03->pNext->Tag(uTag) = Str_tmp
            this.pLastNode = pTemp03->pNext : this.pNode = pTemp03->pNext : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pLastNode->pPrev = pTemp03
            HadHashTag=0 : pFirstNode->BranchCount+=1
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system
        End If
        If iLenCumul<iLen Then  '  If u*istep<iLen Then   ' this.Branch
            pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : pTemp=pNode
            If this.pNode->pBranch=0 Then ' New 'Hash' : this.BlindTag(LIST_RES) :
                pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
                pTemp03->pNext->pPrev = pTemp03 : pTemp03->pNext->Tag(uTag) = LIST_RES
                pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : pNode=pTemp03
                this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp : pTemp->pBranch=this.pNode
                pTemp->BranchCount=0 : this.uCount=0 :' pTemp->pBranchLastNode=this.pNode     
                this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode
            Else 'Branche déjà créée
                this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
                this.pLastNode = this.pNode->pBranch->pBranchLastNode : this.pNode = this.pNode->pBranch
            End If
        End If : pTemp02=pFirstNode
    Next i
    this.pLatestHTag=this.pNode : this.sLatestHTag=Str_tmp2
    If this.pNode->Tag(1)="" And bRHByPass=0 Then : this.pNode->Tag(1)=" " : End If
    If IsPt2Swp=1 Then : Swap Listptemp2,Listptemp2_b : _Deallocate(Listptemp2_b) : End If : If IsPtSwp=1 Then : Swap Listptemp,Listptemp_b : _Deallocate(Listptemp_b) : End If
  '  If this.HashTag<>Str_tmp2 Then : Print "Erreur sur " & this.HashTag & " <> " & Str_tmp2 : beep : sleep : End If ' Debug & tests
    Return HadHashTag
End Property
Property List.HashSort(ub as Byte) As Byte : If ub=0 Or ub=1 Then : bHTmethod=ub : uSortTag=uTag : Return 1 : Else : Return 0 : End If : End Property

Property List.Sort as Byte : If this.pFirstNode->Tag(1)<>"0" Then : this.Sort("0") : Else : this.Sort("1") : End If : Return 1 : End Property
Property List.Sort(SessionId As String) as Byte
    Dim As ListNode Ptr s_pNode=pNode, s_pFirstNode=pFirstNode
    Dim As uInteger s_uCount=uCount
     If Val(SessionId)<0 Then : this.fSortMethod(-1) : End If
    this.Root : this.pFirstNode->Tag(1)=SessionId : this.fSort : this.pNode=pGarbage
    While this.HashStep 
        If this.pFirstNode->Tag(1) <> SessionId Then : this.pFirstNode->Tag(1)=SessionId : this.fSort : pNode=this.pFirstNode->pNext : End If       
    Wend
    pNode=s_pNode : pFirstNode=s_pFirstNode : pLastNode=pFirstNode->pBranchLastNode : uCount=s_uCount
    Return 1
End Property

Property List.HashTag As String
    Dim pTemp01 As ListNode Ptr : Dim pTemp02 As ListNode Ptr
    If bTracking=1 And bTrackingMethod=0 Then '  This.TrackCompute()       
        pTemp01=pNode : While pTemp01->Tag(0)<>LIST_RES And pTemp01<>pGarbage : pTemp01=pTemp01->pPrev : Wend : If pTemp01=pGarbage Then : pTemp01=pFirstFIRSTNode : End If
        pFirstNode=pTemp01 : pLastNode=pTemp01->pBranchLastNode : uCount=pTemp01->BranchCount ': pLastNode->pNext=0
    End If : pTemp01 = this.pFirstNode : pTemp02 = this.pNode
    Str_tmp = this.pnode->Tag(uTag)       
    While pTemp01->pPrev <>0
   '     If pTemp01->pBranch <> 0 Then
            pTemp02 = pTemp01->pBranch
            Str_tmp = pTemp02->Tag(0)  + Str_tmp           
   '     End If
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasHashTag(str_Tag As String) As Byte
  '  Dim As zString Ptr Listptemp=Allocate(Len(str_Tag)+1), zp1, zp2, zp3=Allocate(1)
    Dim As zString Ptr  zp1, zp2
    Dim pContextRetour As ListContext
    Dim HadHashTag As Byte=0 : Dim IsEtoile As Byte=0 : Dim i as uByte=1 : Dim t as uByte=Len(str_Tag) : Dim istep As uByte=this.bHashLen
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.RootPrivate
    zp1=Listptemp+Len(str_Tag)+1 : (*zp1)[0]=0 : 
    *Listptemp=str_Tag : zp1=Listptemp' * Alternative to Mid
    Do
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid : Str_tmp=Mid(str_Tag,i, istep)
        If this.HasTag(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            If this.pNode->Tag(1)="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf this.pNode->Tag(1)="!*" Then : HadHashTag=0 : i=t
            ElseIf this.pNode->Tag(1)="!" And i=t Then : HadHashTag=0
            ElseIf i>=t Then : HadHashTag=1
            Else :  HadHashTag=0 : End If   
        ElseIf IsEtoile=0 Then : HadHashTag=0 : i=t
        End If
        If i<t Then
            If this.pNode->pBranch=0 Then 
                If bAutoCursor<3 Then : pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount : End If 
                Return -1    '        _Deallocate(Listptemp) : _Deallocate(zp3) : Return -1
            Else : this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode : this.pNode = this.pFirstNode
            End If : this.bSearchRes = 0
        End If
        i+=istep
    Loop Until i>t
 '   _Deallocate(Listptemp) : _Deallocate(zp3) 
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode 
        If bAutoCursor=1 Then : Return 1 
        ElseIf bAutoCursor=2 Then : If pNode->Tag(1)="" Then : HadHashTag=0 : Else : Return 1 : End If 
        End If 
    End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
   Return HadHashTag
End Property

Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : Else : Return 0 : End If : Else : Return -1 : End If : End Property
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>0 And bHashLen<255 Then : this.bHashLen = bHashLen : Return 1 : Else : Return 0 : End If : End Property
Property List.BranchCountDown(i as Byte) As Byte : If i=0 Or i=1 Then : bBranchCountDown=i : Return 1 : Else : Return 0 : End If : End Property
Property List.BranchCount As uInteger : If this.pNode->pBranch<>0 Then : Return pNode->BranchCount : Else : Return 0 : End If : End Property ' Return this.pNode->BranchCount

Property List.NFmethod(i As Byte) As Byte : this.bNFmethod=i : Return 1 : End Property
Property List.NFrecursive(i As Byte) As Byte : If i=1 Then : this.bPickReduce=1 : Else : this.bPickReduce=0 : End If : Return 1 : End Property

Property List.NodeFlat As Byte 'Réallocation sélective dynamique multimodes rétro-récursive (virtuelle/reelle glissante 0/-n) de la structure de l'index en memoire virtuelle (Reduce) - Compatible HashStep, HashStepRev(?), KeyStep, KeyStepRev(?), fStep, TrackStep
    Dim As ListContext pContext, pContextRetour : Dim  As ListNode Ptr pTemp1, pTemp2, pTemp3, pTemp4, pTemp5, pTemp6 : Dim IsLastNode As uByte=0 ' : Dim as string str_Tag
    this.NodeRecycle : NodeRecycle2
    'Contrôle multimode en entrée + contrôle du Token de fin de liste + gestion continuité des ptr
    If pNode->Tag(0)=LIST_RES OrElse pNode->Tag(0)=LIST_DEL OrElse pNode=pWhyteMove OrElse pNode=pGarbage Then : Return 0
    ElseIf bTracking=1 Then
        If pFirstNode->pBranch=pFlatRoot Then : Return 0 : End If
        If bTrackingMethod=0 Then
            pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
            pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : pLastNode->pNext=0
        End If : pTemp6=pNode->pBranchLastNode
    End If : pTemp5=pFirstNode : pTemp2 = this.pNode : Str_tmp=this.HashTag : pLatestHTag=0 ': If Right(Str_tmp,1)=LIST_DEL Then : Return 0 : End If
    'Gestion (swapping) des nodes parents                                                   ---------------------------------------------------------------------------
    If this.pNode->pBranch<>0 And bNFmethod<>3 Then           
        'Validation du mouvement mémoire : ' Fonctionnalité Tree List =>FlatList / ByPass Garbage ou 'Déjà swappé
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag(1)=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag(0)=LIST_DEL Then : Return 0 : End If  ' PATCHED !!
        pTemp1=AllowCake : pTemp4=this.pFlatRoot->pBranch : If this.pNode->pPrev<>0 Then : this.pNode->pPrev->pNext=pTemp1 : End If ': End If  If this.pNode->pPrev->Tag(0)<>LIST_DEL Then :
        If this.pNode->pNext->pPrev=this.pNode Then this.pNode->pNext->pPrev=pTemp1 : End If       
        pTemp1->pPrev=this.pNode->pPrev : pTemp1->pNext=this.pNode->pNext : pTemp1->pBranch=this.pNode->pBranch
        pTemp1->BranchCount=this.pNode->BranchCount : pTemp1->Tag(0)=this.pNode->Tag(0) : pTemp1->Tag(1)=LIST_DEL
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If ' ElseIf pTemp2->pPrev=pFirstNode Then : pTemp2->pNext=0 : End If '
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0 : this.pNode->Tag(0) = Str_tmp
        this.pNode->pPrev=pTemp4 : pTemp4->pNext->pPrev=this.pNode : this.pNode->pNext=pTemp4->pNext : pTemp4->pNext=this.pNode : this.pNode=pTemp1         
    Else : this.uCount-=1 : pFirstNode->BranchCount-=1 :  If bBranchCountDown=1 Then : this.BCountDown(-1) : End If
    End If   
    'Gestion (/optimisation) du parsing (rétro-récursivité) ds le HashStep       ---------------------------------------------------------------------------       
    If pNode->pPrev<>pFirstNode Then
        If this.pNode->pNext->Tag(0)=LIST_DEL Then : This.pLastNode=this.pNode->pPrev : This.pFirstNode->pBranchLastNode=this.pNode->pPrev : End If ' this.pNode->pPrev->pNext=0 :
        If bHashStepRev=1 Then : pContextRetour.pNode=pNode->pNext : Else : pContextRetour.pNode=pNode->pPrev : End If
        pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount   
    Else
        pContext.pNode=This.pNode ': If bHashStepRev=1 And pNode<>pLastNode Then : pContext.pNode=This.pNode->pNext : End If
        pContext.pFirstNode=This.pFirstNode : pContext.pLastNode=This.pLastNode : pContext.uCount=This.uCount       
        If pNode=pLastNode Then : pTemp3=this.pFirstNode->pBranch->pPrev
        Else : pTemp3=this.pFirstNode->pBranch :
        End If
        If pTemp3->Tag(0)=LIST_RES Then
            If pNode=pLastNode Then : this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : End If
            pTemp3=this.pFirstNode->pBranch
        End If
        this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount ' This.UpLevel         
        pContextRetour.pNode = pTemp3 : pContextRetour.pFirstNode = This.pFirstNode : pContextRetour.pLastNode = This.pLastNode : pContextRetour.uCount=This.uCount
        This.pNode=pContext.pNode : This.pFirstNode=pContext.pFirstNode : This.pLastNode=pContext.pLastNode : this.uCount=pContext.uCount                 
    End If
    If this.pNode->pNext=0 And this.pNode->pPrev->Tag(0)=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag(0)=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
  ' Swapping / MAJ des pointeurs - depend de IsLastNode                        --------------------------------------------------------------------------     
  ' Envoi d'un ancien node parent déjà swappé vers le garbage collector OU envoi d'un node non parent vers le GarbageCollector (si NFmethod=-1)
    If (pTemp2->Tag(1)=LIST_DEL Or this.bNFmethod=-1) And pTemp2->pBranch=0  Then
        If IsLastNode=0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext : End If
   '     If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If    If pTemp2->pPrev<>0 Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag(0)=LIST_DEL : pTemp2->Tag(1)=""  : pTemp2->pBranchLastNode=0 : uGarbCt+=1
        If pTemp2->ListData<>0 Then : pTemp2->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp2->ListData : pTemp2->ListData=0 : uContainerGarbCt+=1 : End If
        This.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
        If IsLastNode=0 And  bHashStepRev=1 Then : If this.Up=0 Then : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext  : End If : End If
        ElseIf IsLastNode=1 Then
            this.pNode=pTemp5->pBranch : this.uCount=pTemp5->pPrev->BranchCount : pLastNode=pTemp5->pPrev->pBranchLastNode : this.pFirstNode = pTemp5->pPrev
            If bTracking=1 Or bPickReduce=1 Then : If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If : '  this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    Else ' Envoi vers la Flat list - Optimisation, à voir                                      --------------------------------------------------------------------------                 
        pFlatRoot->pBranch->BranchCount+=1         
        pNode=pFirstNode->pNext : this.UpLevel
        this.pFirstNode = this.pFirstFIRSTNode : this.pLastNode = this.pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
        this.pNode=this.pFlatRoot : this.Branch ' this.FlatStack
        If pFlatRoot->pBranch->BranchCount=0 Then : pFlatRoot->pBranch->BranchCount=1 : this.uCount=1 :  End If
        pTemp1 = this.pLastNode
        If IsLastNode=0 Then
            If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If
            If pTemp2->pPrev<>0 And pTemp2->Tag(0)<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            pTemp2->pPrev= this.pLastNode : pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2 :' pTemp2->pBranch=0
            this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->Tag(uTag) = Str_tmp : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            this.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount     
            If bHashStepRev=1 Then : If this.Up=0 Then : this.BlindStep : End If : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If : Return 1 :  End If             
        Else
            pTemp1->pNext=pTemp2  : pTemp2->pNext=0 : this.pLastNode=pTemp2 :'  pTemp2->pBranch=0 : 
            this.pFirstNode->pBranchLastNode = pTemp2  : pTemp2->Tag(uTag)=Str_tmp : pTemp2->pPrev=pTemp1  '
            this.pNode=pTemp5->pBranch : this.pFirstNode = pTemp5->pPrev : pLastNode=pTemp5->pPrev->pBranchLastNode : this.uCount=pTemp5->pPrev->BranchCount           
            If bTracking=1 Or bPickReduce=1 Then :  If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL  Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If  : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If ' this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : Return 1 : End If
    Return 1
End Property

Property List.RHmethod(i As Byte) As Byte : If -2<i<2 Then : this.bRHmethod=i : Return 1 : Else : this.bRHmethod=-1 : Return 0 : End If : End Property
Property List.RestoreHash As Byte
    Dim As ListNode Ptr pTemp,  pTmpPrev, pTmpNext, pMove
    Dim str_tmp as string=this.Tag : Dim bTagExists As Byte : Dim uTagTmp As Byte=uTag
    pTemp=this.pnode : str_tmp=this.Tag(uTag) : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : Return 0 : End If
    'HashTagging
    uTag=0 : bRHByPass=1 : bTagExists=this.HashTag(str_tmp) : bRHByPass=0 : 
    'Gestion des modes (RHmethod)
    If bTagExists=1 And pNode->Tag(1)<>""  Then ' tag deja existant et "vraie" clef
        If bRHmethod=-1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pLocalMove=this.pnode : this.pFlatRoot->pBranch->BranchCount-=1 'envoi garbage
        ElseIf bRHmethod=1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
        Else : If pNode->Tag(1)=LIST_DEL Then : pNode->Tag(1)=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
        End If       
    Else : pTemp->Tag(0)= this.pnode->Tag(uTag) : pLocalMove=this.pnode : this.pFlatRoot->pBranch->BranchCount-=1 :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext : 
    If bNFmethod<>3 Then : pTemp->pBranch=this.pnode->pBranch : End If
    this.pnode->pPrev->pNext=pTemp
    If this.pnode->pNext<>0 Then : If this.pnode->pNext->pPrev=this.pnode Then : this.pnode->pNext->pPrev=pTemp : End If : End If
   ' pTemp->pBranchLastNode=this.pnode->pBranchLastNode
    If this.pnode=this.pLastNode Then : this.pLastNode=pTemp : End If : If this.pnode=this.pFirstNode Then : this.pFirstNode=pTemp : End If     
    If this.pnode->pBranch<>0 Then
        If this.pnode=this.pFirstNode->pBranchLastNode Then : this.pFirstNode->pBranchLastNode=pTemp : End If
        If this.pnode->pBranch->pBranch=this.pnode Then : this.pnode->pBranch->pBranch=pTemp : End If       
        pTemp->pBranch=this.pnode->pBranch : pTemp->pBranchLastNode=this.pnode->pBranchLastNode : pTemp->BranchCount=this.pnode->BranchCount
    End If
    'Reprise ds Flat List
    this.FlatStack(1)
    If bTagExists<>2 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext : ' this.pnode->pBranch=0
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext :' pNode->pBranch=0
    End If
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLOW CONTROL
Property List.Up As Byte : If pFirstNode=pFirstFIRSTnode Then : Return 0 : Else :  this.UpLevel : Return 1: End If : End Property
Property List.Down As Byte
    If pnode->pBranch=0 Or pNode->Tag(0)=LIST_RES Then  : Return 0 : End If
    If pnode->pBranch->pPrev<>pFirstNode Then : Return 0 :
    Else : pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pNode->pBranch : uCount=pFirstNode->BranchCount : pLastNode=pNode->pBranch->pBranchLastNode : pNode=pNode->pBranch : Return 1
    End If
End Property
Property List.AutoCursor(b As Byte) As Byte : If 0<=b<=3 Then : bAutoCursor=b : Return 1 : End If : Return 0 : End Property

Property List.HoldBack As Byte : Return this.HoldBack(0) : End Property
Property List.HoldBack(by As Byte) As Byte   
    If pNode->Tag(0)=LIST_RES Then : Return 0
    ElseIf TrackTrace(by)<>0 Then : TrackTrace(by)->pBranchLastNode=pNode : TrackTrace(by)=this.pNode : Return 1
    Else : this.TrackSet(by) : pNode->pBranchLastNode=0 : TrackTrace(by)=pNode : Return 1
    End If
End Property
Property List.TrackStep As Byte
    Dim As ListNode Ptr pTemp1
    If pNode->pBranchLastNode->Tag(0)=LIST_DEL Or pNode->pBranchLastNode->Tag(0)=LIST_RES Then : this.RootPrivate : this.TrackCompute :  bTracking=0 : Return 0 : End If '
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag(0)<>LIST_RES Then           
        pNode=pNode->pBranchLastNode : bTracking=1 :
        If bTrackingMethod=1 Then  ' this.TrackCompute
            pTemp1=pNode : While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage : pTemp1=pTemp1->pPrev : Wend : If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
            pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : pLastNode->pNext=0
        End If : Return 1
    End If : this.TrackCompute : bTracking=0 : Return 0
End Property
Property List.Track As Byte : Return this.Track(0) : End Property
Property List.Track(by As Byte) As Byte
    If pNode->Tag(0)<>LIST_DEL Then : This.TrackCompute : End If : bTracking=1 : this.Root : This.TrackMethod(1)
    If this.Tracks(by).pNode=0 Then : this.TrackSet(by)  : Return 0
    Else
        pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=this.Tracks(by).pNode
        pLocalMove=pNode : pFirstNode=this.Tracks(by).pFirstNode : pLastNode=pFirstNode->pBranchLastNode : bHashLen=this.Tracks(by).bLcHashLen
        pNode->pBranch=0 : pNode->pPrev=0 : pNode->Tag(0)=""
        Return 1
    End If
End Property
Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte : this.Tracks(by).pNode=pNode : this.Tracks(by).pFirstNode=pFirstNode : this.Tracks(by).bLcHashLen=bHashLen : TrackTrace(by)=0 : Return 1 : End Property
Property List.IsTracked As Byte : Dim i As Byte : If pNode->pBranchLastNode<>0 And pNode->Tag(0)<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS-1 : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : End Property
Property List.TrackMethod(by As Byte) As Byte : If by=0 Or by=1 Then : bTrackingMethod=by : Return 1 : Else : Return 0 : End If: End Property

Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    Lcontext(by).pNode=pNode : Lcontext(by).pFirstNode=pFirstNode : Lcontext(by).pLastNode=pLastNode : Lcontext(by).uCount=this.uCount : Lcontext(by).LcHashTag=pNode->Tag(0) : Lcontext(by).bLcHashLen=this.bHashLen
    Return 1
End Property
Property List.Recover As Byte : Return this.Recover(1) : End Property
Property List.Recover(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pNode=Lcontext(by).pNode : pFirstNode=Lcontext(by).pFirstNode : this.bHashLen=Lcontext(by).bLcHashLen
    pLastNode=pFirstNode->pBranchLastNode : this.uCount= this.pFirstNode->BranchCount : this.bHashLen=Lcontext(by).bLcHashLen
  '  If pLastNode<>Lcontext(by).pLastNode Then : Print "LZLE Aside/Recover possible integrity warning error" : End If
  '  If pFirstNode->BranchCount<>Lcontext(by).uCount Then : Print "LZLE Aside/Recover possible count warning error" : End If
    Return 1
End Property

Property List.Follow(pList As List) As Byte 
    Dim As ListNode Ptr pTemp1=pList.Relation1, pTemp2=pList.Relation2
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    If pTemp1<>0 Then 
        this.pNode=pTemp1 
        If pTemp2=0 Then : this.TrackCompute : Else : this.pFirstNode=pTemp2 : End If
    Else : Return 0 
    End If    
    this.pLastNode=pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
    Return 1 
End Property

'==========================================================================================MEMORY MANAGEMENT
Property List.FlatCount As uInteger : Return this.pFlatRoot->pBranch->BranchCount : End Property
Property List.GarbageCount As uInteger : Return this.uGarbCt : End Property
Property List.ContainerCount As uInteger : Return this.uContainerGarbCt : End Property
Property List.NodeCount As uInteger : Return this.uNodeCOUNT : End Property

Property List.GarbageFlat As Byte
    Dim L_Context As ListContext : Dim As ListNode Ptr pTemp1, pTemp2, pTemp3 : Dim i as Byte
    If pFlatRoot->pBranch=0 Then : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then : pLocalMove=pFlatRoot->pBranch : this.NodeRecycle : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev
    If pTemp2=0 Then
        L_Context.pNode=pNode : L_Context.pFirstNode=pFirstNode : L_Context.pLastNode=pLastNode : L_Context.uCount=this.uCount
        this.FlatStack : pTemp2=pEndFlat->pPrev
        pNode=L_Context.pNode : pFirstNode=L_Context.pFirstNode : pLastNode=L_Context.pLastNode : this.uCount=L_Context.uCount
    End If :  If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext
    pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot
    Do
        pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If
        pNode=pTemp3
        pTemp1=pTemp1->pNext
    Loop Until pTemp1=pTemp2
    pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ': pTemp1->ListData.sData=""
    pTemp3=pNode : pNode=pTemp1 : this.Val("") : pNode=pTemp3
    uGarbCt+=pFlatRoot->pBranch->BranchCount
    pFlatRoot->pBranch->pNext=pFlatRoot->pBranchLastNode : pFlatRoot->pBranchLastNode->pPrev=pFlatRoot->pBranch : pFlatRoot->pBranch->BranchCount=0
    If pFirstNode=pFlatRoot->pBranch Then : uCount=0 : this.RootPrivate : End If
    Return 1
End Property

'Property List.Recycle As uInteger : this.Root : this.Flat : this.AllOf : Return this.GarbageCollector : End Property
Property List.Recycle As uInteger : this.Root : this.AllOf : Return this.AllRecycle : End Property

Property List.DropAll As uInteger  'pRoot principal + pFlatRoot + pFlatRoot->pBranch + pGarbage + pLastLAST/pWhyte = 5 nodes déalloues ds destructor     
    If this.IsDestroyed=1 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
  '  this.Root : this.GarbageFlat : this.Flat : this.GarbageCollector : this.NodeRecycle : this.NodeRecycle2
    this.Root : this.GarbageFlat :  this.AllOf : this.AllRecycle : this.NodeRecycle : this.NodeRecycle2
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext  : Dim iLong As uInteger=0     
    While pTemp<>pGarbage And pTemp<>0 And pTemp<>pFlatRoot
        If pFlatRoot->pNext->ListData<>0 Then : _Deallocate(pFlatRoot->pNext->ListData) : End If
        _Deallocate(AllowCake) : pTemp=pFlatRoot->pNext : this.uNodeCOUNT-=1 : iLong+=1
    Wend
    Dim pPanTemp As ListContainer Ptr =pPanCakeGarbage->pNextContainer : Dim SeekMt As Byte=this.bSeekMethod
    While pPanTemp<>pPanCakeGarbage : _Deallocate(AllowPanCake) : pPanTemp=pPanCakeGarbage->pNextContainer : Wend  ' pPanCakeGarbage->pNextContainer=pPanCakeGarbage       
    this.bSeekMethod=SeekMt : uCount=0 : this.pFirstNode->BranchCount=0   
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then :  _Deallocate(pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1 : iLong+=1 : End If
    this.AllOfPrivate
    Return iLong    
End Property

Property List.Destroy As Byte
    If this.IsDestroyed=1 Then : Return 0 : End If
    this.Root : this.DropAll : IsDestroyed=1
    If pPanCakeGarbage<>0 Then _Deallocate(pPanCakeGarbage) : pPanCakeGarbage=0 : End If  : 
    If this.pFlatRoot<>0 Then
        If this.pFlatRoot->ListData<>0 Then : _Deallocate this.pFlatRoot->ListData : this.pFlatRoot->ListData=0 : End If
        If this.pFlatRoot->pBranch<>0 Then
            If this.pFlatRoot->pBranch->pNext<>0 And pFlatRoot->pBranch->pNext<>pEndFlat Then               
                _Deallocate(this.pFlatRoot->pBranch->pNext) : pFlatRoot->pBranch->pNext=0 :  this.uNodeCOUNT-=1 
            End If
            _Deallocate(this.pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1 
        End If
        _Deallocate(this.pFlatRoot) : pFlatRoot=0 : this.uNodeCOUNT-=1
    End If 
    If this.pGarbage->ListData<>0 Then : _Deallocate this.pGarbage->ListData : this.pGarbage->ListData=0 : End If
    If this.pFirstFIRSTNode->ListData<>0 Then : _Deallocate this.pFirstFIRSTNode->ListData : this.pFirstFIRSTNode->ListData=0 : End If
    If this.pEndFlat<>0 Then : _Deallocate(this.pEndFlat) : pEndFlat=0 : This.uNodeCOUNT-=1 : End If   
    If this.pLastLASTNode<>0 And pLastLASTNode<>pWhyteMove And pLastLASTNode<>pFirstFIRSTNode Then : _Deallocate(this.pLastLASTNode) : pLastLASTNode=0 : this.uNodeCOUNT-=1 : End If
    If this.pGarbage<>0 And pGarbage<>pNode Then : _Deallocate(this.pGarbage) : pGarbage=0 : This.uNodeCOUNT-=1 : End If 
    If this.pWhyteMove<>0 Then : _Deallocate(this.pWhyteMove) : pWhyteMove=0 : This.uNodeCOUNT-=1 : End If 
    If this.pFirstFIRSTNode<>0 Then : _Deallocate(this.pFirstFIRSTNode) : pFirstFIRSTNode=0 :  this.uNodeCOUNT-=1 : End If
    If this.pNode<>0 Then : _Deallocate(this.pNode) : pNode=0 : this.uNodeCOUNT-=1 : End If
    If Listptemp<>0 Then : _Deallocate(Listptemp) : Listptemp=0 : End If : If Listptemp2<>0 Then : _Deallocate(Listptemp2) : Listptemp2=0 : End If : If zp3<>0 Then :  _Deallocate(zp3) : zp3=0 : End If
   ' If this.uNodeCount>2 Then : Print "Erreur a reporter : " & Str(this.uNodeCount-2) & " non dealloues !" : sleep : End If   '_Deallocate( New(@this) List )    
    Return 0
End Property

'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : dim i as byte=0 : dim t as byte=0
    this.NodeRecycle : this.NodeRecycle2 : If pNode->pBranch=0 Then : this.Branch : this.BlindTag("") : pTemp1=pNode : t=1 : Else : this.Down : pNode=pNode->pNext : End If
    i=this.Snatch(pList)
    If i=0 Then : If t=1 Then : pLocalRoot=pFirstNode : pLocalMove=pTemp1 : End If
    ElseIf i=1 Then : If t=1 Then : pTemp1->pPrev->pNext=pTemp1->pNext : pTemp1->pNext->pPrev=pTemp1->pPrev : pLocalMove=pTemp1 : End If
    End If : this.UpLevel : If t=1 Then : this.NodeRecycle : this.NodeRecycle2 : End If : Return i
End Property

Property List.Snatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr
    pTemp1=pList.GiveBranch : If pTemp1=0 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
    If bBranchCountDown=1 Then : this.BCountDown(pTemp1->BranchCount) : End If : uCount+=1 : pFirstNode->BranchCount+=1
    If pNode->Tag(0)=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If : End If
    If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode :  End If
    pTemp1->pNext=pNode->pNext : If pNode->pNext<>0 Then : pNode->pNext->pPrev=pTemp1 : End If
    pNode->pNext=pTemp1 : pTemp1->pPrev=pNode : If pNode=pLastNode Then : pLastNode=pTemp1 : End If 
    pList.AllOfPrivate
    pNode=pTemp1 : Return 1
End Property

Property List.FlatSnatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : Dim pTemp2 As ListNode Ptr   
    pTemp1=pList.GiveFlat : If pTemp1=0 Then : Return 0 : End If
    pFlatRoot->pBranch->BranchCount+=pTemp1->BranchCount : uNodeCOUNT+=pTemp1->BranchCount : pTemp1->BranchCount=0
    pTemp2=pTemp1->pBranch : pTemp1->pBranch=0 : pFlatRoot->pBranch->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pBranch->pNext
    pFlatRoot->pBranch->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot->pBranch : Return 1
End Property

Property List.GarbageSnatch(pList As List) As Byte
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2 : Dim As ListNode Ptr pTemp1, pTemp2
    pTemp1=pList.GiveGarbage : If pTemp1=0 Then : Return 0 : End If : uNodeCOUNT+=pTemp1->BranchCount : uGarbCt+=pTemp1->BranchCount
    pTemp2=pTemp1->pBranch : pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext : pTemp1->pBranch=0 : pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot   
    pPanTemp1=pPanCakeGarbage->pNextContainer
    pPanTemp2=pList.GivePanCake : If pPanTemp2=0 Then : Return 0 : End If :  pPanCakeGarbage->pNextContainer=pPanTemp2
    pPanTemp2=pList.GiveLastPanCake : uContainerGarbCt+=pList.GivePanCakeCount : pPanTemp2->pNextContainer=pPanTemp1 : Return 1
End Property

Property List.CopyCat(pList As List) As Byte
    Dim ub as byte=1
    Dim As ListNode Ptr pTmp1=pNode->pNext, pTmp2=pNode
    pList.BranchCountDown(0)
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.uTag=0 Then
        While pNode<>pTmp1 and ub=1
            pList.HashTag(this.HashTag)
            pList.RwTag1(this.Tag(1))           
            pList.SetRelation1(this.pNode) : pList.SetRelation2(this.pFirstNode)
            ub = this.HashStep
        Wend
    Else
        While pNode<>pTmp1 and ub=1
            pList.HashTag(this.Tag(uTag))
            pList.SetRelation1(this.pNode) : pList.SetRelation2(this.pFirstNode)
            ub = this.HashStep
        Wend
    End If
    pNode=pTmp2
    Return 1
End Property


Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.992 -

Post by Lost Zergling »

Archive 0.992 Part 1/3
New version Beta 0.99 :
Negatives: HashTag ("Key") (mapping) very slightly slower in some frequent cases (<3%), consumes more memory, NodeFlat (3) (bugged) is no longer supported.
Advantages :
- Corrections of several bugs (fmove, tracking, snatch, ..), improvement of the robustness of the kinematics of the set of instructions.
- Multiple key support, easy creation of multiple key linked lists
- Improved usability of tracking
- With the exception of NodeFlat (3) which is no longer supported and TrackSet which has slightly different operation in some cases, backward compatibility is ensured.
- Reorganization and review of the code, additional optimization options (limited efficiency but possible in some cases)
- Improvement of the speed of certain instructions (HashStepRev, HashTag and NodeFlat)
- Improvement of the overall optimization logic (less constraints for the user)
- The set of instructions is a priori almost complete, the logic of implementation and operation is intended to be stable and exhaustive.

Beta 0.991 : minor fixes : Snatch and ValTag + minor fix : a mapping slowdown (-5%) compared to previous release fixed.
Speeds same (or better) again but with more features and optimization options.
Beta 0.992 : added a fast sort feature - automatic (threshold 100) - non-recursive (ex p6)

Code: Select all

' NOTICE : Thank you to remove first single quote on the line below once you accepted the licence.
 /'   In case redistribution of SOURCES you may ensure to reactivate the acceptance of the license. This notice may be anywhere in source code till licensed user is aware it exists.
CONST PRODUCT_LIC =_
"_______________________________________________________________________________" & chr(10) &_
"  LZListsEngine/ListsVM by Etienne Carfagnini - contact:etienne.carfa@gmail.com" & chr(10) &_
"  Bd Henri Barbusse 92700 Colombes France 01 46 49 99 02" & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  This Freeware/Openware licence specify the rights to use the software" & chr(10) &_
"* Distribution of derivating software : " & chr(10) & "  The information access to the original software must be guaranteed to" & chr(10) & "  developers and users (https://freebasic.net/forum/ or alternative mentionned)" & chr(10) &_
"* Right to use the software and its derivating : 2 options : " & chr(10) & " >OPTION 1 (Openware) :"  & chr(10) & "  The software is free for any use (under FreeBasic)." & chr(10) &_
"  'LZLE Openware licence' is mentionned in licence contributors." & chr(10) &_
"  The software must be compiled using any official GPL FreeBasic Compiler." & chr(10) & "  (https://freebasic.net/forum/viewforum.php?f=1) OrAlso http://users.freebasic-portal.de/stw/builds/" & chr(10) &_
"  Clause canceled." & chr(10) &_
" >OPTION 2 (Freeware) (any language) :"  & chr(10) & "  The software is free for any use except the following limitation as to its"  & chr(10) & "  fields of application : not for use on virtual machine or on virtual server." & chr(10) &_
"  'LZLE Freeware licence' is mentionned in licence contributors." & chr(10) &_
"* Apart from the restrictions of use (options 1 and 2) which are not compatible"  & chr(10) & "  with the rights of uses specified in clause 5.1, the legal clauses whenever"  & chr(10) &_
"  compatible will be those specified by the CeCILL-C license"  & chr(10) & "  ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )" & chr(10) &_
"  Disclaimer :"  & chr(10) & "  This licence refers to CeCILL-C but is NOT a CeCILL-C because the right to"  & chr(10) & "  use the software with no restriction is limited to the FreeBasic ecosystem." & chr(10) &_
"  This because it aims to be an extension of the language instructions set."  & chr(10) &_
"  LZLE (instruction set architecture,coding style) is dedicated to FreeBasic."  & chr(10) &_
"  This notice constitutes a whole that must be present in the source code." & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  Cette licence Freeware/Openware precise les droits a utiliser le logiciel" & chr(10) &_
"* Distribution de logiciels derives :" & chr(10) & "  L'acces informatif au logiciel original doit etre garanti aux" & chr(10) & "  developpeurs et aux utilisateurs (https://freebasic.net/forum/ ou autre)." & chr(10) &_
"* Droit d'utiliser le logiciel et ses derives : 2 options : " & chr(10) & " >OPTION 1 (Libre) :"  & chr(10) & "  Le logiciel est gratuit pour toute utilisation (sous FreeBasic)." & chr(10) &_
"  'LZLE licence Openware' est mentionne dans les contributions." & chr(10) &_
"  Le logiciel doit etre compile en utilisant n'importe quel compilateur GPL" & chr(10) & "  FreeBasic 'officiel' (https://freebasic.net/forum/viewforum.php?f=1) OrAlso http://users.freebasic-portal.de/stw/builds/" & chr(10) &_
"  Clause retirée." & chr(10) &_
" >OPTION 2 (Gratuiciel) (tout langage):"  & chr(10) & "  Le logiciel est gratuit pour tout usage sauf la limitation suivante quant a"  & chr(10) & "  son champs d'application : pas d'utilisation sur machine ou serveur virtuel." & chr(10) &_
"  'LZLE licence Freeware' est mentionne dans les contributions." & chr(10) &_
"* En dehors des restrictions d'utilisation (options 1 et 2) lesquelles ne sont "  & chr(10) & "  pas compatibles avec les droits d'utilisation prevus a la clause 5.1, les"  & chr(10) &_
"  clauses applicables seront celles compatibles specifiees par la licence"  & chr(10) & "  CeCILL-C ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-fr.txt )" & chr(10) &_
"  Avertissement :"  & chr(10) & "  Cette licence fait reference a la licence CeCILL-C mais n'en est PAS une car"  & chr(10) & "  le droit a utiliser librement le logiciel est limite a l'ecosysteme FreeBasic" & chr(10) &_
"  Ce moteur de liste a jeu d'instructions est dedie au langage FreeBasic" & chr(10) &_
"  Cette notice constitue un tout lequel doit etre present dans le code source." & chr(10) &_
"_______________________________________________________________________________"
Dim k As String
Print PRODUCT_LIC : Print
Print "Please press 'Y' (Yes) to accept the licence or Esc to abort"
Print "Merci d'appuyer sur 'O' (Oui) pour accepter la licence ou echap pour annuler"
Do : k = Inkey : Select Case k : Case "Y" : Exit Do : Case "y" : Exit Do : Case "O" : Exit Do : Case "o" : Exit Do : Case Chr(27) : System : End Select : Loop
Print "Removing first single quote on line 2 in source code will activate the licence" : Print "Retirer la premiere simple quote en ligne 2 du code source activera la licence" : Print "Thank you for chosing this software - Merci d'avoir choisi ce logiciel" : Print
'/ ' END NOTICE

Dim Shared As uInteger AllocateDeallocateCounter=0
Function _Callocate(Byval n As Integer) As Any Ptr : AllocateDeallocateCounter += 1 : Return Callocate(n) : End Function
Sub _Deallocate(Byval p As Any Ptr) : AllocateDeallocateCounter -= 1 : Deallocate(p) : End Sub

CONST MAX_KEYLEN=50
CONST RUP_COLS=1 : CONST MAX_COLS=5 : CONST MAX_TRACKS=20 ' RUP_COLS = ListNode ArraySize / MAX_COLS = Extended range ListNode ArraySize / MAX_TRACKS = all tracks are on a same single track beware not to overwrite elements otherwise overwritten track will be rerouted
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4)

Type ListContainer 'Data Segment Level
    Dim str_tag_C(RUP_COLS+1 to MAX_COLS-1) As String
    Dim str_item as String : Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag(0 to RUP_COLS) As String : Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode : Dim BranchCount As uInteger=0
End Type
Type ListContext ' Branch context Level   
    Dim  As ListNode Ptr pNode, pFirstNode, pLastNode : Dim As String LcHashTag : Dim  As uInteger  uCount : Dim As uByte bLcHashLen
End Type

Type List
    Declare Constructor() : Declare Destructor()   
   
    Private:
    Dim As zString Ptr Listptemp=_Callocate(MAX_KEYLEN), Listptemp2=_Callocate(MAX_KEYLEN), zp3=_Callocate(1)
    Dim  As ListContext Lcontext(0 to MAX_COLS-1), Tracks(0 to MAX_COLS-1)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt, PVS_Count=0, KR_Count=0 ', iLenDelta  ', iLenStrTmp, iLenpNode, iLenCumul, iLenDiff
    Dim As Byte uTag=0, bSearchRes=0, bRHByPass=0, bHashStepRev=0, bfStepZero=0, bTrackingMethod=0, bTracking=0, bHTMethod=0, bHashKeyUnique=1, uSortTag=0,_
                        bSortMT=1, bNFmethod=1, bRHmethod=-1, bAutoCursor=1, bSeekMethod=2, bBranchCountDown=0, bPickReduce=0, bCopyCatMethod=0, bCopyCatRelation=0,_
                        bColBcountLocked=0, bColTrackLocked=0, bAlrdyTracked=0, bSnatchBLMethod=0, bHStepTrace=0, bTrackMultiKeys=1, bPVSmethod=-1
    Dim As uByte bHashLen=1, IsDestroyed=0, PVS_ratio=3, ubKeysRegister=0
    Dim As String  sSearchTag, sLatestHTag, Str_tmp, str_arbo , Str_tmp2, str_testTMP
    Declare Property AllowCake() As ListNode Ptr                      ' Cooking here
    Declare Property AllowPanCake() As ListContainer Ptr          ' No comment
    Declare Property AllRecycle() As uInteger   
    Declare Property Branch() As Byte                                        ' Descend dans la liste enfants, creation de nouvelles entrées
    Declare Property UpLevel() As Byte                                      ' Revient à la liste parente   
    Declare Property NodeRecycle() as Byte                              ' Supression en décalé (NodeFlat)
    Declare Property NodeRecycle2() as Byte                            ' Supression en décalé (RestoreHash)
    Declare Property RootPrivate As Byte                                   ' Accès direct rapide à la racine
    Declare Property FlatStack(uB as uByte) As Byte                 ' Construction de la Flat List avec retour à la racine(0) ou accès à la flat liste (1)
    Declare Property BCountDown(i As Byte) As Byte                ' CountDown calculation   
    Declare Property ValPrivate(str_Value As String) As Byte
    Declare Property ValPrivate As String
    Declare Property AllOfPrivate As uInteger
    Declare Property TrackCompute As Byte
    Declare Property HashStepTrace As Byte                              ' Required by Sort (for optimization)   
   
    Public:   
    'Special features - Private declared Public   
    Declare Property SetRelation(by as Byte) as Byte
    Declare Property SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr
    Declare Property SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr
    Declare Property Relation As ListNode Ptr   
    Declare Property GiveBranchDown As ListNode Ptr
    Declare Property GiveBranch As ListNode Ptr
    Declare Property GiveFlat As ListNode Ptr
    Declare Property GiveGarbage As ListNode Ptr
    Declare Property GivePanCake As ListContainer Ptr
    Declare Property GiveLastPanCake As ListContainer Ptr
    Declare Property GivePanCakeCount As uInteger
    'Flat control
    Declare Property Tag(str_Tag As String) As Byte                 ' Create a new ListNode with Key=str_Tag OR retrieve position of an existing Tag
    Declare Property Tag As String                                            ' Return current Tag value in a list =Tag(0)
    Declare Property Tag(iTag As Integer) As String                  ' Return current Tag value of the specified entry in array
    Declare Property HasTag(str_Tag As String) As Byte           ' Return 1 if Tag exists
    Declare Property BlindTag(str_Tag As String) As Byte          ' Create a new ListNode with Key=str_Tag at end of the list
    Declare Property RwTag(s_Tag As String) As Byte               ' Rewrite Tag Value of current Node : if current node is Hashed, just rewrite HashTag Value not effective Key value
    Declare Property RwTag1(s_Tag As String) As Byte                ' Rewrite Tag Value(1)
    Declare Property RwTag2(s_Tag As String) As Byte                ' Rewrite Tag Value(2)
    Declare Property RwTag3(s_Tag As String) As Byte                ' Rewrite Tag Value(3)
    Declare Property RwTag4(s_Tag As String) As Byte                ' Rewrite Tag Value(4)
    Declare Property ColTags As Byte                                       ' Renvoie le numéro de la colonne de tag active       
    Declare Property ColTags(i as Byte) As Byte                        ' Définie la colonne de tag active de 0 à MAX_COLS, par défaut 0   
    Declare Property AllOf As uInteger                                       ' Return number of node in  considered Flat List (root or branch), set position to the first node of current branch
    Declare Property Count As uInteger                                     ' Return current node Count of considered Flat List
    Declare Property First As Byte                                              'Set current node to first node considering flat list (root or branch)   
    Declare Property Last As Byte                                              'Set current node to Last node considering flat list (root or branch)       
    Declare Property Val(str_value As String) As Byte                ' Assign a string (+50 len) to the current node that is identified by a Tag
    Declare Property Val As String                                             ' Return current node string datas   
    Declare Property ValTag(str_value As String) As String        ' Considering current Flat list (root or branch as a flat list) return string data identified by Key=str_Tag
    Declare Property fStep As Byte                                            ' FOR EACH - While MyList.fStep : .. : Wend Jump to next node till current flat list end
    Declare Property fStepRev As Byte                                     ' FOR EACH - Idem fStep Jump to previous node till current flat list reach firstnode
    Declare Property bStep As Byte                                           ' FOR NEXT - For i=1 to MyList.AllOf : MyList.bStep : ..... : Next i    -> Jump to next node (NO CHECK)
    Declare Property BlindStep As Byte                                     ' FOR EACH - While MyList.BlindStep : .. : Wend -And- FOR NEXT - For i=1 to MyList.AllOf : MyList.BlindStep : ..... : Next i  Jump to next node  (check)   
    Declare Property BlindStep(i As Integer) As Byte                  ' Jump to +/-n nodes BlindStep(0) equiv Last : goto LastNode  (NO CHECK)
    Declare Property fMove(i As Integer) As Byte                      ' Move a node +/- n positions
    'Sorting
    Declare Property ColSort(i as Byte) As Byte                          'The column number to sort on (0-n) col 0 is indexed. Définie la colonne de tri active de 0 à MAX_COLS, par défaut 0
    Declare Property fSortMethod(bsortM As Byte) As Byte        'FLAT  1=ascending / -1=descending
    Declare Property fSort As Byte                                              'FLAT sort
    Declare Property HashSort(ub as Byte) as Byte                   '0=No sort on mapping, 1=ascending sort on HashTag mapping or on RestoreHash remapping
    Declare Property Sort As Byte
    Declare Property Sort(bSortmt As Byte) As Byte
    'Hash control handling
    Declare Property Root As Byte                                           ' Check/Restore List integrity & set cursor to First node of root flat list - Shall be called before HashStep or After NodeFlat or RestoreHash
    Declare Property FlatStack As Byte                                    ' Flat List Access : use it before RestoreHash
    Declare Property RootNode As Byte                                  ' Set cursor to Root node of root flat list
    Declare Property EndNode As Byte                                   ' Set cursor to the last logical node  ( = While MyList.HashStep : Wend ) which is the last node of the last branch of last root flat node
    Declare Property HashStep As Byte                                   ' FOR EACH - recursive  parse property : syntax : While MyList.HashStep=1 : ... : Wend
    Declare Property HashStepRev As Byte                            ' FOR EACH - idem HashStep
    Declare Property KeyStep As Byte                                      ' FOR EACH - While MyList.KeyStep=1 : ... : Wend idem HashStep but show only Keys tagged by user, not the tree structure
    Declare Property KeyStepRev As Byte                               ' FOR EACH - idem KeyStep
    Declare Property HashTag(str_Tag As String) As Byte       ' Build a hash Key on str_Tag, Return 1 if already exits otherwise return 0   
    Declare Property HashTag As String                                  ' Return Hash key value of current node
    Declare Property HashTagP As String   
    Declare Property HasHashTag(str_Tag As String) As Byte ' Return 1 if str_Tag is a hash key otherwise return 0
    Declare Property HasKey(str_Tag As String) As Byte          ' Idem HasHashTag Return 1 only for values specified with HashTag (not all cascaded index values)
    Declare Property NodeFlat As Byte                                   ' Déréférence une arborescence de clefs (un HashTag), et traite les données en conséquence       
    Declare Property RestoreHash As Byte                             ' Envoi un node de la Flat List en Hash List (réindexation)
    'Hash Control - Object's properties parameters
    Declare Property AutoCursor(i As Byte) As Byte                 'Method for HasTag(string), HasHashTag and HasKey:  0=do nothing current node is unchanged,  1 -DEFAULT- =move current to found on success (HasHashTag), 2=move current to found on success (HasKey), 3=move on partial success
    Declare Property BranchCountDown(i As Byte) As Byte     ' 1/0 Activate(1) or desactivate(0) BranchCountDown, default 0
    Declare Property CopyCatMethod(i As Byte) As Byte          '0 or 1 : CopyCat(1) : tracking is using tracking (no HoldBack/track) OR CopyCat(0) : tracking to source is on BranchCount (no BranchCountDown enabled) but tracking possible inside index !
    Declare Property HashKeyUnique(ub as Byte) As Byte      ' Default=1  HashKeyUnique(0)=>HashTag always create a new key even though a key already exists
    Declare Property HashLen(bHashLen As uByte) As Byte  ' Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' Enregistrement du hashTag parent en premier node caché : optimise l'enregistrement et la récupération de la clef (propriété hashTag) mais ralenti le mapping hashTag("key")
    Declare Property NFmethod(i As Byte) As Byte                  ' Determine le fonctionnement de NodeFlat : NFmethod=-1 node=>GarbageCollector  NFmethod=0 node=>FlatList sauf parents reliquataires NFmethod=1 node=>FlatList même les nodes parents contenant toujours des dépendances
    Declare Property NFrecursive(i As Byte) As Byte               ' NFrecursive=0 Standard / NFrecursive=1 parents nodes auto send to garbage collector till no other child and till they are not keys
    Declare Property PVSmethod(ub As Byte) As Byte            ' Predictive Vectors Static (optimization algo for HashTag) -1=no PVS / disabled (default), 0= PVS on, 1=PVS with priority forced
    Declare Property PVSratio(ub As uByte) As Byte               ' Static coeff for PVS dynamic adjustement
    Declare Property RHmethod(i As Byte) As Byte                 ' Determine le fonctionnement de RestoreHash par rapport aux doublons : RHmethod=-1 : Hashnode->GarbageCollector  / RHmethod=0 : no swap / RHmethod=1 : Hashnode->FlatList
    Declare Property SeekMethod(i as Byte) As Byte              ' Method for Tag(string), HasTag(string), HashTag(string), HasHashTag and HasKey: 1(default)=seek from First to Last | 2: seek from Lastnode to firstNode | 0 :seek from currentnode to last node (Flat multikeys)
    Declare Property SnatchBLmethod(i As Byte) As Byte      ' For SnatchBelow 0=Source ParentNode snatched below target / 1=Source Child Nodes snatched below target (leaving ex-parent node in source list) (for intuitive key pairing between source & target)
    Declare Property TrackMethod(by As Byte) As Byte          ' MyList.TrackMethod(0)=might be faster (Default) / MyList.TrackMethod(1)=slow, might be more secure in specific cases (Pretty useless)
    Declare Property TrackMultiKeys(uB as uByte) As Byte    ' If <>0 multikeys will be automatically tracked (Track & TrackStep) on specified track each HashTag : working with CopyCat and RestoreHash as well
    Declare Property VectorUnlock As Byte                            ' Unlock auto security : Track vector is ONE choice between HoldBack/Track OR CopyCatMethod(1)/Follow - BranchCount vector is ONE choice between CopyCatMethod(0)/Follow OR BranchCountDown(1) OR PVSmethod(1+) - Using CopyCat index let you one choice left between Tracking, CountDown or PSV optimization
    Declare Property VectorClear As Byte                               ' If list structure has been changed (ie snatch, NodeFlat), tracking links or others (count down, PVS, or Follow) might be corrupted : working like CopyCat targeting current node and the whole child tree, clearing corrupted (or so called) links
    'Flow control
    Declare Property BranchCount As uInteger                        'Return Branch Count
    Declare Property Up As Byte                                              'idem UpLevel
    Declare Property Down As Byte                                         'idem Branch but prevent from creating an orphan sublist entry   
    Declare Property HoldBack As Byte                                  ' Works with Track : First Holback is initialiazing tracking, then each HolBack is recording a new tracked node. Track indicates to set cursor to first holbacked node & TrackStep is tracking all holbacked nodes in chronological order
    Declare Property HoldBack(i As Byte) As Byte                  ' Works with Track : indicates the number the track working with
    Declare Property TrackStep As Byte                                ' -SELECTIVE- FOR EACH - While MyList.TrackStep=1 : ... : Wend : selective PARSE only Keys marked for tracking by HoldBack
    Declare Property Track As Byte                                      ' Set track pointer to first tracked node
    Declare Property Track(i As Byte) As Byte                       ' Only one track but several track pointers
    Declare Property TrackSet As Byte                                 ' Create a breaking point in tracking : next List.Track+TrackStep will iterate from next tracked node just following breaking point / does not break track list, just replacing track starting point
    Declare Property TrackSet(i As Byte) As Byte
    Declare Property IsTracked As Byte                                ' When working with several tracks (pointers) it can be usefull to know wether a node has been already tracked or not to control tracking overwrite
    Declare Property TrackClear As Byte
    Declare Property TrackClear(i As Byte) As Byte              ' Indicates to reinitialize Track n°i : next HolBack will initialize a track to current node
    Declare Property Aside As Byte                                      ' Memorise ListNode ptr dans le pointeur n°0
    Declare Property Aside(i As Byte) As Byte                       ' Memorise ListNode ptr dans le pointeur n°i
    Declare Property Recover As Byte                                 ' Repositionne l'élément courant de la liste sur celui mémorisé par Take, si cet élément existe toujours, sinon renvoie False
    Declare Property Recover(i As Byte) As Byte                  ' Repositionne l'élément courant de la liste sur celui mémorisé par Take(i)
    Declare Property Follow(pList As List) As Byte
    'Memory management
    Declare Property FlatCount As uInteger                         ' Return number of values stored in Flat List
    Declare Property GarbageCount As uInteger                 ' Return number of nodes available in garbage collector
    Declare Property ContainerCount As uInteger                ' Return number of nodes container available in hidden garbage collector
    Declare Property NodeCount As uInteger                      ' Return number of nodes including not visible ones
    Declare Property GarbageFlat As Byte                            'Send all Flat List to GarbageCollector
    Declare Property Recycle As uInteger                            'AllFlat+GarbageCollector : détruit une arborescence et envoi tout en GarabgeCollector - do NOT garbage protected flat list
    Declare Property DropAll As uInteger                              'Remove all elements in list, except a 5/6 listnodes subset                         
    Declare Property Destroy As Byte                                   'Manual destructor
    'List Data Links & Exchange   
    Declare Property Snatch(pList As List) As Byte                  'Snatch a whole branch from another List to next node
    Declare Property SnatchBelow(pList As List) As Byte        'Snatch a whole branch from another List Below current node
    Declare Property FlatSnatch(pList As List) As Byte            'Target's Flat list is transfered to current list
    Declare Property GarbageSnatch(pList As List) As Byte    'Target's Garbage Collector is transfered to current list
    Declare Property CopyCat(pList As List) As Byte                'Create an index (linked to source)  from a flat (node per node) or indexed column (if so current node + its whole child tree), element by element (auto support multivalues) can work from loops (filtering)   
    'Debug
  '  Declare Property NextNode As String       
  '  Declare Property PrevNode As String   
End Type

' to do : SmartPatterns (?)  /
' BUGs :
'
' Property List.NextNode As String : Dim str_tmp as string="-" : If pNode->pNext<>0 Then : this.Aside : pNode=pNode->pNext : str_tmp= "next tag=" & pNode->Tag(0) & " & next hashtag=" & this.HashTag : this.Recover : Return str_tmp : End If : End Property
' Property List.PrevNode As String : Dim str_tmp as string="-" : If pNode->pPrev<>0 Then : this.Aside : pNode=pNode->pPrev : str_tmp= " prev tag=" & pNode->Tag(0) & " & prev hashtag=" & this.HashTag  & "  branch=" & Str(pNode->pBranch) : this.Recover : Return str_tmp : End If : End Property

'==========================================================================================CONSTRUCTOR & DESTRUCTOR  :  this.pFirstNode->pBranch->pBranchLastNode=0
Constructor List
    pFlatRoot = _Callocate(Len(ListNode)) : pNode = _Callocate(Len(ListNode)) : this.uNodeCOUNT+=2  ' Moment angulaire(petite masse)
    pPanCakeGarbage=_Callocate(Len(ListContainer)) : pPanCakeGarbage->pNextContainer=pPanCakeGarbage ': pTestContainer=pPanCakeGarbage ' Moment Angulaire(petite masse)
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag(0) = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT
    this.Root : this.AllOf
End Constructor
Destructor List : this.Destroy : End Destructor

'==========================================================================================TYPE LIST PRIVATE PROPERTIES
Property List.AllowCake As ListNode Ptr ' This.Vralloc
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext ' uGarbCt>1 ' If pTemp<>0 Then : If pTemp->pNext=0  Then  : pTemp=pGarbage : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 :  Return pTemp : End If  : End If
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1 : ' And pTemp<>0 ' pTemp->pNext=0 : pTemp->pPrev=0 : pTemp->pBranch=0 :
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ': this.pLastLASTNode=pTemp ' Moment Angulaire(petite masse)         
    End If : Return pTemp
End Property
Property List.AllowPanCake As ListContainer Ptr
    Dim pPanTemp As ListContainer Ptr : dim uB As uByte
    If pPanCakeGarbage->pNextContainer<>pPanCakeGarbage Then
        pPanTemp=pPanCakeGarbage->pNextContainer : pPanTemp->str_item="" : For uB=RUP_COLS+1 To MAX_COLS-1 : pPanTemp->str_tag_C(uB)="" : Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else : pPanTemp=_Callocate(Len(ListContainer)) ': If pTestContainer2=0 Then : pTestContainer2=pPanTemp : End If  ' : pPanTemp->str_item=""  ' Moment Angulaire(petite masse)
    End If : Return pPanTemp
End Property

Property List.AllRecycle As uInteger
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext       
    Dim NbCollected As uInteger=0
    If pGarbage->ListData<>0 Then : pGarbage->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pGarbage->ListData : pGarbage->ListData=0 : uContainerGarbCt+=1 : End If
    If pLocalMove=pLastLASTNode Then : pLastLASTNode=pLastLASTNode->pPrev : End If : this.NodeRecycle : This.RootPrivate
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode= this.pGarbage->pNext : Else : pNode= this.pFirstNode->pNext : End If  : If pNode=0 Then : Return 0 : End If
    If pNode <>0 Then
        Do
            If pNode->Tag(0)<>LIST_RES And pNode->pBranch<>0 Then   
                pNode->pNext->pPrev=pNode->pBranch->pBranchLastNode : pNode->pBranch->pBranchLastNode->pNext=pNode->pNext
                pNode->pNext=pNode->pBranch : pNode->pBranch->pBranch=0 : pNode->pBranch=0 : pNode->BranchCount=0
                pNode->pNext->pPrev=pNode : pNode->pNext->pBranchLastNode=0
            Else
                If this.pNode->pNext<>0 Then
                    pNode->Tag(0) = LIST_DEL : pNode->Tag(1)="" : pNode->BranchCount=0 : NbCollected +=1 ': iLong+=1
                    If pNode->ListData<>0 Then : pNode->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pNode->ListData : pNode->ListData=0 : uContainerGarbCt+=1 : End If                           
                    this.pNode=this.pNode->pNext
                End If               
            End If
        Loop Until pNode->pNext=0
    End If
    If NbCollected>0 Then : This.uGarbCt+=NbCollected : uCount=0 : this.pFirstNode->BranchCount=this.uCount : pLastNode=pNode : If pFirstNode=pFirstFIRSTNode Then : pLastLASTNODE=pNode : End If : End If   
    This.RootPrivate : pGarbage=pLastNode->pPrev :pTemp=pNode : pNode=pGarbage : this.Val(LIST_DEL) : pNode=pTemp
    Return NbCollected
End Property

Property List.Branch As Byte
    Dim pTemp As ListNode Ptr :  Dim pTemp1 As ListNode Ptr   
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp = this.pNode
    If this.pNode->pBranch=0 Then ' this.NewHash(this.pNode)
        pTemp1 = this.pLastNode : this.uCount+=1 : pTemp1->pNext = this.AllowCake 'And eat it
        pTemp1->pNext->pPrev = pTemp1 : pTemp1->pNext->Tag(uTag) = LIST_RES
        pTemp1 = pTemp1->pNext : this.pLastNode = pTemp1 : pNode=pTemp1  ' this.BlindTag(LIST_RES) :
        this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp
        pTemp->pBranch=this.pNode : pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
        this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : this.bSearchRes = 0 : Return 0
    Else 'Branche déjà créée
        this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
        this.pLastNode = this.pNode->pBranch->pBranchLastNode         
        this.pNode = this.pNode->pBranch : this.bSearchRes = 0 : Return 1
    End If   
End Property

Property List.UpLevel As Byte   
    If this.pFirstNode->pPrev = 0 Then : Return 0 : End If
    If this.pFirstNode->pBranch <> 0 Then ' Retour node de départ pour faciliter un parcours éventuel
        this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        this.pFirstNode = this.pFirstNode->pPrev : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode         
        this.bSearchRes = 0 ': this.sSearchTag = ""
        Return 1
    Else : Return 0
    End If               
End Property

Property List.NodeRecycle as Byte
    If pLocalMove<>0 Then 'pLocalMove est un node à suppression décalée       
        pLocalMove->pPrev=this.pFlatRoot : pLocalMove->pNext=this.pFlatRoot->pNext : pLocalMove->BranchCount=0 ' :  pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL :
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pLocalMove->ListData : pLocalMove->ListData=0 : uContainerGarbCt+=1 : End If
        this.pFlatRoot->pNext->pPrev=pLocalMove : this.pFlatRoot->pNext=pLocalMove : this.uGarbCt+=1
        pLocalMove = 0       
    End If
    Return 1
End Property
Property List.NodeRecycle2 as Byte
    If pLocalRoot<>0 Then 'pLocalRoot est un node LIST_RES             
        pLocalRoot->pPrev=this.pFlatRoot : pLocalRoot->pNext=this.pFlatRoot->pNext : pLocalRoot->Tag(0)=LIST_DEL  : pLocalRoot->BranchCount=0
        this.pFlatRoot->pNext->pPrev=pLocalRoot : this.pFlatRoot->pNext=pLocalRoot : This.uGarbCt+=1
        pLocalRoot->pBranch->pBranch=0 : pLocalRoot->pBranch->pBranchLastNode=0 : pLocalRoot->pBranch->BranchCount=0 :
        pLocalRoot->BranchCount=0 : pLocalRoot->pBranch=0 : pLocalRoot = 0
    End If
    Return 1
End Property

Property List.RootPrivate As Byte   
    this.AllOfPrivate : While UpLevel : Wend    ' While this.pFirstNode->pBranch <> 0 : this.UpLevel : Wend   '
    this.pFirstNode = this.pFirstFIRSTNode : this.bSearchRes = 0 : this.sSearchTag = ""
    this.pNode = this.pGarbage
    Return 1
End Property

Property List.FlatStack(uB As Ubyte) As Byte
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    Dim pTemp1 As ListNode Ptr   
    This.RootPrivate
    this.pNode=this.pFlatRoot : this.Branch
    If this.pLastNode=this.pFlatRoot->pBranch Then
        If this.pEndFlat<>0 Then : this.pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=this.pFlatRoot->pBranch : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1         
        End If
    ElseIf this.pLastNode<>this.pEndFlat Then           
        If this.pEndFlat<>0 Then
            this.pEndFlat->pPrev->pNext=this.pEndFlat->pNext : this.pEndFlat->pNext->pPrev=this.pEndFlat->pPrev
            this.pEndFlat->pPrev=this.pLastNode : this.pLastNode->pNext=this.pEndFlat : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If                       
    End If     
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If uB=0 Then : this.UpLevel : End If : this.AllOfPrivate
    Return 1
End Property
Property List.BCountDown(i As Byte) As Byte : Dim pTemp As ListNode Ptr=pFirstNode : While pTemp->pPrev<>0 : If pTemp->pBranch<>0 Then : pTemp->pBranch->BranchCount+=i : End If : pTemp=pTemp->pPrev : Wend : Return 1 : End Property
Property List.ValPrivate(str_value As String) As Byte : If this.pValTmp->ListData=0 Then : this.pValTmp->ListData=this.AllowPanCake : End If : this.pValTmp->ListData->str_item=str_value : Return 1 : End Property
Property List.ValPrivate As String : If this.pValTmp->ListData=0 Then : Return "" : End If : Return this.pValTmp->ListData->str_item : End Property

Property List.AllOfPrivate As uInteger
    this.pNode = this.pFirstNode
    If this.pFirstNode=this.pFirstFIRSTNode Then           
        this.pNode = this.pGarbage
        If pWhyteMove<>0 And pWhyteMove<>pLastNode Then  'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc
            If pWhyteMove->pNext<>0 Then : pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode :  End If     
            pLastNode=pWhyteMove : pLastNode->pNext=pFirstFIRSTNode '0
        End If   
    End If : Return this.Count
End Property

Property List.TrackCompute As Byte
    Dim As ListNode Ptr pTemp1=pNode
    If bAlrdyTracked=1 Then : Return 1 : End If
    While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage
        If pTemp1->pBranch<>0 Then : pTemp1=pTemp1->pBranch->pPrev : Exit While : End If ' This code is naturally using one Swap, Cast and Exit for aesthetic and legitimate reasons, Gosub @ Extends are unfortunately missing.
        pTemp1=pTemp1->pPrev
    Wend
    If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
    pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : bAlrdyTracked=1 : Return 1
End Property

Property List.HashStepTrace As Byte
    While this.pnode->pBranch<>0
        bHStepTrace=-1
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : bHStepTrace=0 : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
         bHStepTrace=1 : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES destination is PRIVATE USE
Property List.SetRelation(by as Byte) as Byte : If by=0 Then : bColBcountLocked=1 : ElseIf by=1 Then : bColTrackLocked=1 : Else : Return 0 : End If : bCopyCatRelation=by : Return 1  : End Property
Property List.SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr : pNode->pBranchLastNode=pRelNode : Return pNode : End Property
Property List.SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr : this.pNode->BranchCount=CuInt(pRelFirstNode) : Return pNode : End Property
Property List.Relation As ListNode Ptr : If this.bCopyCatRelation=1 Then : Return pNode->pBranchLastNode : ElseIf this.bCopyCatRelation=0 Then : Return Cast(ListNode Ptr, pNode->BranchCount) : Else : Return 0 : End If : End Property

Property List.GiveBranchDown As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2   
    If pNode->pBranch=0 Or pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag(0)="" Then : Return 0
    ElseIf pNode->pBranch->Tag(0)<>LIST_RES Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    this.NodeRecycle : this.NodeRecycle2 : this.VectorClear
    pTemp1=pNode->pBranch : pNode->pBranch=0 :
    Return pTemp1
End Property

Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp4
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Then : Return 0 : End If     
    bfStepZero=0 : this.NodeRecycle : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp4=pNode->pPrev : pTemp1=pNode :
    If bBranchCountDown=1 Then : this.BCountDown(-pNode->BranchCount) : End If
    If pTemp1=pLastNode  Then : this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel : this.NodeRecycle2 : bfStepZero=1 :  Return pTemp1
    Else
        pNode->pPrev->pNext=pNode->pNext : pNode->pNext->pPrev=pNode->pPrev : uCount-=1 : pFirstNode->BranchCount-=1       
        If pTemp1=pLastNode And pFirstNode<>pFirstFIRSTNode Then
            this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel :  this.NodeRecycle2 : bfStepZero=1 : Return pTemp1
        End If         
    End If
    If pTemp4<>pFirstNode Then : pNode=pTemp4 : Else : pNode=pFirstNode->pNext : End If
    Return pTemp1
End Property

Property List.GiveFlat As ListNode Ptr   
    Dim As ListNode Ptr pTemp1, pTemp2
    If pFlatRoot->pBranch=0 Then : Return 0 : End If         
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Or pFlatRoot->pBranch->pNext=pFlatRoot->pBranch  Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev : If pTemp2=0 Or pTemp1=pTemp2 Then : Return 0 : End If
    pTemp1->pBranch=pTemp2 : pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=pFlatRoot->pBranch
    pTemp1->BranchCount=pFlatRoot->pBranch->BranchCount : uNodeCOUNT-=pFlatRoot->pBranch->BranchCount 'this.FlatCount :
    this.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If  ' this.FlatStack : uCount=0
    Return pTemp1   
End Property

Property List.GiveGarbage As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2
    If uGarbCt<2 Then : Return 0 : End If : pTemp1=pFlatRoot->pNext : pTemp2=pGarbage->pPrev : If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext=pGarbage : pGarbage->pPrev=pFlatRoot : pTemp1->pBranch=pTemp2 : pTemp1->BranchCount=uGarbCt
    uNodeCOUNT-= uGarbCt : uGarbCt=0
    Return pTemp1
End Property
Property List.GivePanCake As ListContainer Ptr
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2
    If uContainerGarbCt<2 Then : Return 0 : End If : pLastPanCake=0
    pPanTemp1=pPanCakeGarbage->pNextContainer : pPanTemp2=pPanTemp1
    While pPanTemp2->pNextContainer<>pPanCakeGarbage : pPanTemp2=pPanTemp2->pNextContainer : Wend : pPanTemp2->pNextContainer=0 : pLastPanCake=pPanTemp2
    pPanCakeGarbage->pNextContainer=pPanCakeGarbage : uContainerGivenCt=uContainerGarbCt : uContainerGarbCt=0
    Return pPanTemp1
End Property
Property List.GiveLastPanCake As ListContainer Ptr : Return pLastPanCake : End Property
Property List.GivePanCakeCount As uInteger : Return this.uContainerGivenCt : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLAT CONTROL
Property List.Tag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer Ptr
    If this.sSearchTag = str_Tag Then
        If this.bSearchRes=1 Then
            this.pNode = this.pSearchNode : Return 1 'pNode
        Else
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->Tag(uTag) = str_Tag ' pTemp->pNext->ListData = item :
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            this.pNode = pTemp : Return 0
        End If
    Else
        If this.bSeekMethod=1 Then : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then : pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
        Else
            pTemp = this.pNode : If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        End If
        If pTemp->Tag(uTag)<>str_Tag then ' New node
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->ListData = item : pTemp->pNext->Tag(uTag) = str_Tag
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If           
            If pFirstNode=pFirstFIRSTNode And pWhyteMove<>pLastNode Then
                pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode : pLastNode=pWhyteMove : pLastNode->pNext=0
            End If : this.pNode = pTemp : Return 0
        End If   
    End If
    this.pNode = pTemp : Return 1 'pTemp
End Property

Property List.Tag As String
    If uTag<=RUP_COLS Then : Return this.pNode->Tag(uTag)
    ElseIf pNode->ListData=0 Then : Return ""
    Else : Return pNode->ListData->str_tag_C(uTag)
    End If
End Property
Property List.Tag(i As Integer) As String
    If i<=RUP_COLS Then : Return this.pNode->tag(i) : Else : If pNode->ListData<>0 Then : Return pNode->ListData->str_tag_C(i) : Else : Return "" : End If : End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag   
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
    Else
        pTemp = this.pNode : If pTemp=0 Then :  pTemp = this.pFirstNode : End If
        If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag(uTag) = str_Tag Then
        this.pSearchNode=pTemp : this.bSearchRes=1 : If this.bAutoCursor=1 Then : pNode=pTemp : End If : Return 1
    Else : this.bSearchRes = 0 : Return 0 : End If   
End Property

Property List.BlindTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = str_Tag
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte : If uTag<=RUP_COLS Then : this.pNode->tag(this.uTag)=s_Tag : Return 1 : Else : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(uTag)=s_Tag : Return 1 : End If : End Property
Property List.RwTag1(s_Tag As String) As Byte : this.pNode->tag(1)=s_Tag : Return 1 : End Property
Property List.RwTag2(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(2)=s_Tag : Return 1 : End Property
Property List.RwTag3(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(3)=s_Tag : Return 1 : End Property
Property List.RwTag4(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(4)=s_Tag : Return 1 : End Property

Property List.ColTags As Byte : Return(this.uTag) : End Property
Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property

Property List.AllOf As uInteger
    Dim pContextRetour As ListContext
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Return 0 : End If :
    Dim  As ListNode Ptr pTemp, pTemp2 : If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If
    If pFirstNode=pFIRSTFIRSTNode Then : If pLastNode<>pWhyteMove Then : this.Root : End If : End If
    this.NodeRecycle : this.NodeRecycle2
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.AllOfPrivate
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : uCount=pContextRetour.uCount
    pNode=AllowCake : pLocalMove=pNode
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode->pNext=pGarbage->pNext : Else : pNode->pNext=pFirstNode->pNext : End If
    If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    Return this.Count
End Property

Property List.Count As uInteger
    Dim pTemp As ListNode Ptr
    If pWhyteMove=0 And pFirstNode=pFIRSTFIRSTNode Then : pTemp=this.pNode : this.uCount-=2 : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : Return this.uCount
End Property

Property List.First As Byte : If pFirstNode=pFirstFIRSTNode Then : pNode=pGarbage : Else : this.pNode=This.pFirstNode->pNext : End If : Return 1 : End Property
Property List.Last As Byte : this.pNode=This.pLastNode : Return 1 : End Property

Property List.Val(str_value As String) As Byte : this.pValTmp=this.pNode : this.ValPrivate(str_value) : Return 1 : End Property
Property List.Val As String : pValTmp=pNode : Return this.ValPrivate : End Property
Property List.ValTag(str_value As String) As String
    If bSearchRes=1 Then : If str_value=this.Tag(0) Then : pValTmp=pSearchNode : Return this.ValPrivate : End If
    ElseIf this.HasTag(str_value)=1 Then : pValTmp=pSearchNode : Return this.ValPrivate
    End If : Return("")
End Property

Property List.fStep As Byte : If pNode=pLastNode Or bfStepZero=1 Or pNode->pNext=pWhyteMove Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pNext : Return 1 : End If : End Property '
Property List.fStepRev As Byte : If pNode->pPrev=pFirstNode Or pNode->pPrev=pGarbage Or bfStepZero=1 Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pPrev : Return 1 : End If : End Property
Property List.bStep As Byte : this.pNode = this.pNode->pNext : Return 1 : End Property
Property List.BlindStep As Byte : If this.pNode->pNext<>0 Then : this.pNode = this.pNode->pNext : Return 1 : Else   : Return 0 : End If : End Property ' : Print "*Warning : list parse or count down error"
Property List.BlindStep(top As Integer) As Byte
    Dim As Integer i : Dim As Byte istep
    If top>0 Then : istep=1 : For i=1 To top step istep : this.pNode = this.pNode->pNext : Next i : ElseIf top = 0 Then : this.pNode = this.pLastNode : Return 1 : Else : istep=-1 : For i=-1 To top step istep : this.pNode = this.pNode->pPrev : Next i : End If
    Return 1
End Property
Property List.fMove(nbMove As Integer) As Byte
    Dim As ListNode Ptr pFirst, pTemp : Dim i As Integer=0
    If pNode->Tag(0)=LIST_DEL Or pNode->Tag(0)=LIST_RES Or pNode=pWhyteMove Or pNode=pEndFlat  Or pNode=pLocalMove Or pNode=pLocalRoot Then : Return 0 : End If
    If pFirstNode=pFirstFIRSTnode Then : pFirst=pGarbage : Else : pFirst=pFirstNode : End If
    If pNode=pLastNode Then : pLastNode=pNode->pPrev : Else : pNode->pNext->pPrev=pNode->pPrev : End If
    pNode->pPrev->pNext=pNode->pNext : pTemp=pNode
    If nbMove>0 Then : For i=0 To nbMove-1 : If pNode<>pLastNode Then : pTemp=pTemp->pNext : End If : Next i
    Else : For i=nbMove To 0 : If pTemp<>pFirstNode Then : pTemp=pTemp->pPrev : End If : Next i
    End If
    If pTemp<>pLastNode Then : pTemp->pNext->pPrev=pNode : pNode->pNext=pTemp->pNext
    Else : If  pTemp->pNext<>0 Then : pNode->pNext=pTemp->pNext : End If : pLastNode=pNode
    End If
    pTemp->pNext=pNode : pNode->pPrev=pTemp
    Return 1
End Property

Last edited by Lost Zergling on Jun 24, 2019 23:37, edited 1 time in total.
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.992 -

Post by Lost Zergling »

Archive 0.992 Part 2/3

Code: Select all


'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uSortTag=i : Return 1 : End If : End Property
Property List.fSortMethod(bsortM As Byte) As Byte : If bsortM=-1 Then : this.bSortMT=-1 : Else : this.bSortMT=1 : End If : Return 1 : End Property
Property List.fSort As Byte
    Dim As ListNode Ptr pTemp1=pFirstNode, pTemp2, pTemp3, pTemp4 : Dim as byte  by=1
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If
    If this.Count>100 And this.bSortMT=1 Then 'B+Tree Sort - non recursive
        Dim as List L_tmp_Sort : L_tmp_Sort.SetRelation(1) : L_tmp_Sort.HashKeyUnique(1) : L_tmp_Sort.HashSort(1) : L_tmp_Sort.fSortMethod(1) : L_tmp_Sort.HashLen(1) : L_tmp_Sort.GarbageSnatch(this)
        this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        pTemp3=pTemp1 : pNode=pTemp1->pNext : If pNode=pFirstNode Then : pTemp4=pFirstNode->pNext : Else : pTemp4=pNode : End If
        While pNode<>pLastNode and by=1 : L_tmp_Sort.HashTag( this.Tag ) : L_tmp_Sort.SetRelation1(this.pNode) : by=this.fStep : Wend ' L_tmp_Sort.HashTag( this.pNode->Tag(uTag) ) <> L_tmp_Sort.HashTag( this.Tag ) wheras pNode->Tag(uTag) = this.Tag ?
        If pFirstNode<>pFirstFIRSTnode Then : L_tmp_Sort.HashTag( this.Tag ) : L_tmp_Sort.SetRelation1(this.pNode)  : End If
        L_tmp_Sort.Root
        While L_tmp_Sort.KeyStep : If this.Follow(L_tmp_Sort) Then : pTemp3->pNext=this.pNode : pNode->pPrev=pTemp3 : pTemp3=pNode : End If : Wend           
        pFirstNode->pBranchLastNode=pTemp3 : this.pLastNode=pTemp3 : pNode=pTemp4
        If pFirstNode=pFirstFIRSTnode Then : pWhyteMove->pPrev=pLastNode : End If
        L_tmp_Sort.Recycle : this.AllOf : this.GarbageSnatch(L_tmp_Sort)
        L_tmp_Sort.Destroy
        Return 1
    ElseIf this.Count>20 Then 'QuickSort - non recursive  (let's let cache doing job)
        'LoveZerglingsWare : I love Zerglings
    End If
   
    pTemp4=pTemp1: pTemp1=pTemp1->pNext
    If pTemp1=pLastNode Then : Return 1 : End If
    If  this.bSortMT=1 Then       
        While pTemp1->pNext<>pLastNode
            pTemp2=pTemp1->pNext       
            If pTemp2->Tag(uSortTag) < pTemp1->Tag(uSortTag) Then   
                pTemp3=pTemp1
                While pTemp2->Tag(uSortTag) < pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                    pTemp3=pTemp3->pPrev
                Wend
                pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext
                pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
                pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
                pTemp2=pTemp1
            End If
            pTemp1=pTemp2
        Wend
    Else     
        While pTemp1->pNext<>pLastNode
            pTemp2=pTemp1->pNext       
            If pTemp2->Tag(uSortTag) > pTemp1->Tag(uSortTag) Then   
                pTemp3=pTemp1
                While pTemp2->Tag(uSortTag) > pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                    pTemp3=pTemp3->pPrev
                Wend
                pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext
                pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
                pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
                pTemp2=pTemp1
            End If
            pTemp1=pTemp2
        Wend
    End If   
    If pFirstNode<>pFirstFIRSTnode Then
        If pLastNode->Tag(uSortTag) < pTemp1->Tag(uSortTag) And this.bSortMT=1 Then
           pTemp2=pLastNode
           pTemp3=pTemp1
            While pTemp2->Tag(uSortTag) < pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                pTemp3=pTemp3->pPrev
            Wend
            pTemp2->pPrev->pNext=pTemp2->pNext : pTemp2->pNext=0
            pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
            pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
            pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pLastNode
        ElseIf pLastNode->Tag(uSortTag) > pTemp1->Tag(uSortTag) And this.bSortMT<>1 Then
           pTemp2=pLastNode
           pTemp3=pTemp1
            While pTemp2->Tag(uSortTag) > pTemp3->Tag(uSortTag) And pTemp3<>pTemp4
                pTemp3=pTemp3->pPrev
            Wend       
            pTemp2->pPrev->pNext=pTemp2->pNext : pTemp2->pNext=0
            pTemp2->pPrev=pTemp3 : pTemp2->pNext=pTemp3->pNext
            pTemp3->pNext->pPrev=pTemp2 : pTemp3->pNext=pTemp2
            pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pLastNode
        End If
    End If
    Return 1
End Property
Property List.Sort as Byte : this.Sort(this.bSortMT) : Return 1 : End Property
Property List.Sort(bSortMth As Byte) as Byte
    Dim As ListNode Ptr s_pNode=pNode, s_pFirstNode=pFirstNode
    Dim As uInteger s_uCount=uCount
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If     
    this.Root : this.fSort : this.pNode=pGarbage
    While this.HashStepTrace : If bHStepTrace=-1 Then : this.fSort :  pNode=this.pFirstNode->pNext : End If : Wend
    pNode=s_pNode : pFirstNode=s_pFirstNode : pLastNode=pFirstNode->pBranchLastNode : uCount=s_uCount
    Return 1
End Property
Property List.HashSort(ub as Byte) As Byte : If ub=1 And this.bSortMT=-1 Then : this.bSortMT=1 : End If : If ub=0 Or ub=1 Then : bHTmethod=ub : uSortTag=uTag : Return 1 : Else : Return 0 : End If : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - HASH CONTROL
Property List.Root As Byte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext   
    If bTracking=1 Or pFirstNode->Tag(0)<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If :' this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode   
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Beep : Return 0 : End If
    this.RootPrivate : If pLocalMove<>0 Then : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL : End If
    this.NodeRecycle : this.NodeRecycle2 : bSearchRes=0 : pTemp2=0 : this.bHashStepRev=0 : pLatestHTag=0
    'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc qui ne soit jamais 'flaté'
    If this.pWhyteMove<>0 Then
        pWhyteMove->Tag(0)=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag(0)<>LIST_RES Then           
            If pWhyteMove->pPrev<>0 Then : this.pWhyteMove->pPrev->pNext=this.pWhyteMove->pNext : End If
            If pWhyteMove->pNext<>0 Then :this.pWhyteMove->pNext->pPrev=this.pWhyteMove->pPrev : End If         
        End If       
    End If ' If pPanCakeGarbage=0 Then : pPanCakeGarbage=AllowPanCake : pPanCakeGarbage->pNextContainer=pPanCakeGarbage : End If
    If pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : this.Val(LIST_DEL) : pGarbage->pPrev=pFlatRoot
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If : this.pNode = pGarbage
    End If
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    this.FlatStack(0)
    'Corrections  - Patch de compatibilité - : pFlatRoot se balade, il faut le remettre au début -
    If pFlatRoot->pPrev<>0 Then : pFlatRoot->pPrev->pNext=pFlatRoot->pNext : End If : If pFlatRoot->pNext<>0 Then :  pFlatRoot->pNext->pPrev=pFlatRoot->pPrev : End If
    pFlatRoot->pPrev=this.pFirstFIRSTNode : pFlatRoot->pNext=this.pFirstFIRSTNode->pNext : If this.pFirstFIRSTNode->pNext<>0 Then : this.pFirstFIRSTNode->pNext->pPrev=pFlatRoot : End If : this.pFirstFIRSTNode->pNext=pFlatRoot
    'Changement de fonctionnement - Patch de compatibilité - pLastLAST devient dernier node LOGIQUE : on le remet à jour
    If this.pFirstFIRSTNode->pBranchLastNode<>0 Then
        pTemp=this.pFirstFIRSTNode->pBranchLastNode : While pTemp->pBranchLastNode<>0 And pTemp<>pTemp2 : pTemp2=pTemp : pTemp=pTemp->pBranchLastNode : Wend : this.pLastLASTNode=pTemp       
    End If
    'NodeFlat+Restorehash nécessite la présence d'un dernier node fictif
    If this.pLastNode->Tag(0)<>"" Then : If pWhyteMove<>0 Then : this.AllOf  : Else : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : End If
    this.pNode=pGarbage : this.uCount=this.pFirstFIRSTNode->BranchCount : this.pLastLASTNode->pPrev->pNext=this.pLastLASTNode
    If this.pLastLASTNode->pNext->Tag(0)=LIST_RES Then : this.pLastLASTNode->pNext=0 : End If
  ' Option for .Root become compatible with Rev parse with no need to jump to Last node (List.Last)
    this.pNode=AllowCake : pNode->Tag(0)="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL
    If pLastNode=pWhyteMove Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    this.NodeRecycle2 : this.pFirstNode->BranchCount=this.uCount : this.pFirstNode->pBranchLastNode=this.pLastNode
    Return 1   
End Property

Property List.FlatStack As Byte : this.FlatStack(1) : this.AllOf : bSearchRes=0 : Return 1 : End Property
Property List.RootNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pFirstFIRSTNode : Return 1 : End Property
Property List.EndNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pLastLASTNode : Return 1 : End Property

Property List.HashStep As Byte
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If ' If pNode=pWhyteMove Then : Return 0 : Else : Return 1 : End If
    Wend : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

Property List.HashStepRev As Byte
    this.bHashStepRev=1
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode=pLastNode->pPrev : Else : pnode=pLastNode : End If : Return 1
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode Then : this.pnode = this.pnode->pPrev : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    Wend : Return 0
End Property
Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property

Property List.HashTag(str_Tag As String) As Byte   
   Dim As ListNode Ptr pTemp,  pTemp02, pTemp03 , pTemp04
    Dim As uInteger i=0, iLen=Len(str_tag), iLenStrTmp, iLenpNode, iLenCumul, iLenDiff, iLenDelta=0, PvsiStep
    Dim As uByte HadHashTag=1, istep=this.bHashLen, IsLast=0, IsPt2Swp=0, IsPtSwp=0, bSeekMethod_TMP=bSeekMethod, bAutoCursor_TMP=bAutoCursor
    Dim As zString Ptr zp1, zp2, Listptemp2_b, Listptemp_b : Dim As String str_testTMP
    If iLen>MAX_KEYLEN Then : Listptemp2_b=_CAllocate(iLen+1) : Swap Listptemp2,Listptemp2_b : IsPt2Swp=1 : End If
    str_testTMP=str_Tag : If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute : End If

    If pFirstNode<>pFirstFIRSTNode Then 'Déclenchement optimisation // Si pFirstNode=pFirstFIRSTNode il est possible que la liste soit vide ou que le node en cours soit en cours d'envoi au garbage collector
        If pLatestHTag=pNode Then : Str_tmp=sLatestHTag '  Algo optimisation 1 : basé sur la récupération la + rapide possible de la position dans l'arbre // And bPVSmethod=0 //  l'algo d'optimisation le plus simple est souvent le + efficace et reste prioritaire sur PVS
        Else : pNode=pFirstNode->pNext : If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
        End If
        iLenStrTmp=Len(Str_tmp)         
        If iLenStrTmp>MAX_KEYLEN Then : Listptemp_b=_CAllocate(iLenStrTmp+1) : Swap Listptemp,Listptemp_b : IsPtSwp=1 : End If
        If iLen>iLenStrTmp Then : iLenDiff=iLen-iLenStrTmp : End If
       
        *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
        *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=istep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
        If *Listptemp=*Listptemp2  And bPVSmethod<1 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs) // And bPVSmethod=0
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
       '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
            iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
            Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
            iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
            If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode             
           
        ElseIf bPVSmethod>-1 Then ' Algo optimisation 2 : basé sur l'enregistrement à un niveau PvsiStep càd (lngClef/n)+1 de la longueur de la clef, d'un pointeur "prédictif" vers une branche plus basse de l'arbre
            PvsiStep=iLen/PVS_ratio+1
            *Listptemp=Str_tmp : zp1=Listptemp : zp1+=PvsiStep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=PvsiStep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)       
            If  *Listptemp<>*Listptemp2 Then' *Alternative to If Left(Str_tmp,istep)<>Left(str_tag,istep) Then   *Listptemp<>*Listptemp2     
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage
                this.HashTag(*Listptemp2 ) 'youpi
                If pNode->BranchCount<>0 Then : pFirstNode=Cast(ListNode Ptr, pNode->BranchCount) : pLastNode=pFirstNode->pBranchLastNode : End If :  pTemp04=pNode : PVS_Count+=1               
                pNode=pFirstNode->pNext : pNode=pFirstNode->pNext
                If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
                *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            End If
            If *Listptemp=*Listptemp2 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs)
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
                pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
           '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
                iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                    Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                    iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
                Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
                iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
                If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode   
            Else               
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1               
            End If 
           
        Else
            pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
            this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1
        End If
    Else
        pTemp02=pGarbage : bSeekMethod_TMP=1
    End If ' Fin algo optimisation   
   
    iLenCumul=0 : *Listptemp2=str_Tag : zp1=Listptemp2 ' * Alternative to Mid
    For i=1 to Len(str_Tag) step istep
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid :  Str_tmp=Mid(str_Tag,i, istep)
        iLenCumul+=iStep
        If bHTmethod=0 Then
            If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
            Else : pTemp = pTemp02 : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
            End If
        Else
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                While ( pTemp->Tag(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else
                pTemp=pTemp02 : While (pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend               
                If pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
            End If
        End If       
        If pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp  'bHashKeyUnique
        ElseIf pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=0 And iLenCumul<iLen Then : this.pNode = pTemp
        ElseIf bHTmethod=1 And IsLast=0 Then
            pTemp03=AllowCake : this.uCount+=1
            pTemp03->pNext=pTemp : pTemp03->pPrev=pTemp->pPrev : pTemp->pPrev->pNext=pTemp03 : pTemp->pPrev=pTemp03         
            If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pTemp03->Tag(uTag) = Str_tmp : HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03           
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If           
        Else ' If pTemp=pTemp02 Then : this.BlindTag(Str_tmp)                           
            pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode : pTemp03->pNext->Tag(uTag) = Str_tmp
            this.pLastNode = pTemp03->pNext : this.pNode = pTemp03->pNext : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pLastNode->pPrev = pTemp03 : HadHashTag=0 : pFirstNode->BranchCount+=1
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system
        End If
        If iLenCumul<iLen Then  '  If u*istep<iLen Then   ' this.Branch
            pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : pTemp=pNode
            If this.pNode->pBranch=0 Then ' New 'Hash' : this.BlindTag(LIST_RES) :
                pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
                pTemp03->pNext->pPrev = pTemp03 : pTemp03->pNext->Tag(uTag) = LIST_RES
                pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : pNode=pTemp03
                this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp : pTemp->pBranch=this.pNode
                this.uCount=0 :' pTemp->pBranchLastNode=this.pNode     pTemp->BranchCount=0 :
                this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(str_testTMP, iLenCumul+iLenDelta) : End If      '
            Else 'Branche déjà créée
                this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
                this.pLastNode = this.pNode->pBranch->pBranchLastNode : this.pNode = this.pNode->pBranch
            End If
        End If : pTemp02=pFirstNode
    Next i
    this.pLatestHTag=this.pNode : this.sLatestHTag=str_testTMP :
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag(1)="" And bRHByPass=0 Then : this.pNode->Tag(1)=" " : End If
    If pTemp04<>0 Then : pTemp04->BranchCount=CuInt(pFirstNode)  : End If
    If IsPt2Swp=1 Then : Swap Listptemp2,Listptemp2_b : _Deallocate(Listptemp2_b) : End If : If IsPtSwp=1 Then : Swap Listptemp,Listptemp_b : _Deallocate(Listptemp_b) : End If     
  ' If pNode=pFirstNode Then : Print "Error  : pNode=pFirstNode  !! " : beep : sleep : End IF
 '  If this.HashTag<>str_testTMP Then : Print "Erreur sur " & this.HashTag & " <> " & str_testTMP : beep : sleep : End If ' Debug & tests
    Return HadHashTag
End Property

Property List.HashTag As String
    Dim As ListNode Ptr pTemp01= this.pFirstNode, pTemp02=this.pNode
    If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute :  pTemp01 = this.pFirstNode : pTemp02 = this.pNode : End If     
    Str_tmp = this.pnode->Tag(uTag)
    If pTemp01->pPrev<>0  AndAlso pFirstNode->Tag(1)<>"" AndAlso ubKeysRegister=1 Then : KR_Count+=1 : Return pFirstNode->Tag(1) & pTemp02->Tag(0) : End If
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag(0)  + Str_tmp                 
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasHashTag(str_Tag As String) As Byte
    Dim As zString Ptr  zp1, zp2
    Dim pContextRetour As ListContext
    Dim HadHashTag As Byte=0 : Dim IsEtoile As Byte=0 : Dim i as uByte=1 : Dim t as uByte=Len(str_Tag) : Dim istep As uByte=this.bHashLen
   
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode 'this.RootPrivate
    this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode
    zp1=Listptemp+Len(str_Tag)+1 : (*zp1)[0]=0 :
    *Listptemp=str_Tag : zp1=Listptemp' * Alternative to Mid
    Do
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid : Str_tmp=Mid(str_Tag,i, istep)
        If this.HasTag(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            If this.pNode->Tag(1)="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf this.pNode->Tag(1)="!*" Then : HadHashTag=0 : i=t
            ElseIf this.pNode->Tag(1)="!" And i=t Then : HadHashTag=0
            ElseIf i>=t Then : HadHashTag=1
            Else :  HadHashTag=0 : End If   
        ElseIf IsEtoile=0 Then : HadHashTag=0 : i=t
        End If
        If i<t Then
            If this.pNode->pBranch=0 Then
                If bAutoCursor<3 Then : pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount : End If
                Return -1
            Else : this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode : this.pNode = this.pFirstNode
            End If : this.bSearchRes = 0
        End If
        i+=istep
    Loop Until i>t
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag(1)="" Then : HadHashTag=0 : Else : Return 1 : End If
        End If
    End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
   Return HadHashTag
End Property

Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : Else : Return 0 : End If : Else : Return -1 : End If : End Property
Property List.BranchCount As uInteger : If this.pNode->pBranch<>0 Then : Return pNode->BranchCount : Else : Return 0 : End If : End Property ' Return this.pNode->BranchCount

Property List.NodeFlat As Byte 'Réallocation sélective dynamique multimodes rétro-récursive (virtuelle/reelle glissante 0/-n) de la structure de l'index en memoire virtuelle (Reduce) - Compatible HashStep, HashStepRev(?), KeyStep, KeyStepRev(?), fStep, TrackStep
    Dim As ListContext pContext, pContextRetour : Dim  As ListNode Ptr pTemp1, pTemp2, pTemp3, pTemp4, pTemp5, pTemp6, pTemp7 : Dim As uByte IsLastNode=0
    this.NodeRecycle : NodeRecycle2
    'Contrôle multimode en entrée + contrôle du Token de fin de liste + gestion continuité des ptr
    If pNode->Tag(0)=LIST_RES OrElse pNode->Tag(0)=LIST_DEL OrElse pNode=pWhyteMove OrElse pNode=pGarbage Then : Return 0
    ElseIf bTracking=1 Then
        If pFirstNode->pBranch=pFlatRoot Then : Return 0 : End If
        If bTrackingMethod=0 Then : this.TrackCompute : pLastNode->pNext=0 : End If : pTemp6=pNode->pBranchLastNode
    End If : pTemp5=pFirstNode : pTemp2 = this.pNode : If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag(uTag) : End If : pLatestHTag=0
    'Gestion (swapping) des nodes parents                                                   ---------------------------------------------------------------------------
    If this.pNode->pBranch<>0  Then
        'Validation du mouvement mémoire : ' Fonctionnalité Tree List =>FlatList / ByPass Garbage ou 'Déjà swappé 
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag(1)=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag(0)=LIST_DEL Then : Return 0 : End If  ' PATCHED !!
        pTemp1=AllowCake : pTemp4=this.pFlatRoot->pBranch : If this.pNode->pPrev<>0 Then : this.pNode->pPrev->pNext=pTemp1 : End If
        If this.pNode->pNext->pPrev=this.pNode Then this.pNode->pNext->pPrev=pTemp1 : End If       
        pTemp1->pPrev=this.pNode->pPrev : pTemp1->pNext=this.pNode->pNext : pTemp1->pBranch=this.pNode->pBranch
        pTemp1->BranchCount=this.pNode->BranchCount : pTemp1->Tag(0)=this.pNode->Tag(0) : pTemp1->Tag(1)=LIST_DEL
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0 : this.pNode->Tag(0) = Str_tmp
        this.pNode->pPrev=pTemp4 : pTemp4->pNext->pPrev=this.pNode : this.pNode->pNext=pTemp4->pNext : pTemp4->pNext=this.pNode : this.pNode=pTemp1
    Else : this.uCount-=1 : pFirstNode->BranchCount-=1 :  If bBranchCountDown=1 Then : this.BCountDown(-1) : End If
    End If   
    'Gestion (/optimisation) du parsing (rétro-récursivité) ds le HashStep       ---------------------------------------------------------------------------       
    If pNode->pPrev<>pFirstNode Then
        If this.pNode->pNext->Tag(0)=LIST_DEL Then : This.pLastNode=this.pNode->pPrev : This.pFirstNode->pBranchLastNode=this.pNode->pPrev : End If
        If bHashStepRev=1 Then : pContextRetour.pNode=pNode->pNext : Else : pContextRetour.pNode=pNode->pPrev : End If
        pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount   
    Else
        pContext.pNode=This.pNode : pContext.pFirstNode=This.pFirstNode : pContext.pLastNode=This.pLastNode : pContext.uCount=This.uCount       
        If pNode=pLastNode Then : pTemp3=this.pFirstNode->pBranch->pPrev : Else : pTemp3=this.pFirstNode->pBranch : End If
        If pTemp3->Tag(0)=LIST_RES Then
            If pNode=pLastNode Then : this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : End If
            pTemp3=this.pFirstNode->pBranch
        End If
        this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount ' This.UpLevel         
        pContextRetour.pNode = pTemp3 : pContextRetour.pFirstNode = This.pFirstNode : pContextRetour.pLastNode = This.pLastNode : pContextRetour.uCount=This.uCount
        This.pNode=pContext.pNode : This.pFirstNode=pContext.pFirstNode : This.pLastNode=pContext.pLastNode : this.uCount=pContext.uCount                 
    End If
    If this.pNode->pNext=0 And this.pNode->pPrev->Tag(0)=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag(1)="" :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag(0)=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag(1)="" :  pLocalRoot->Tag(0)=LIST_DEL
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
   ' pFirstNode->Tag(1)=""
  ' Swapping / MAJ des pointeurs - depend de IsLastNode                        --------------------------------------------------------------------------     
  ' Envoi d'un ancien node parent déjà swappé vers le garbage collector OU envoi d'un node non parent vers le GarbageCollector (si NFmethod=-1)
    If (pTemp2->Tag(1)=LIST_DEL Or this.bNFmethod=-1) And pTemp2->pBranch=0   Then ' And bNFmethod<>3
        If IsLastNode=0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext : End If
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag(0)=LIST_DEL : pTemp2->Tag(1)="" : uGarbCt+=1 : pTemp2->pBranchLastNode=0
        If pTemp2->ListData<>0 Then : pTemp2->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp2->ListData : pTemp2->ListData=0 : uContainerGarbCt+=1 : End If
        This.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
        If IsLastNode=0 And  bHashStepRev=1 Then : If this.Up=0 Then : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext  : End If : End If
        ElseIf IsLastNode=1 Then       
            this.pNode=pTemp5->pBranch : this.uCount=pTemp5->pPrev->BranchCount : pLastNode=pTemp5->pPrev->pBranchLastNode : this.pFirstNode = pTemp5->pPrev           
            If bTracking=1 Or bPickReduce=1 Then : If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If : '  this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    Else ' Envoi vers la Flat list - Optimisation, à voir                                      --------------------------------------------------------------------------                 
        pFlatRoot->pBranch->BranchCount+=1         
        pNode=pFirstNode->pNext : this.UpLevel
        this.pFirstNode = this.pFirstFIRSTNode : this.pLastNode = this.pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
        this.pNode=this.pFlatRoot : this.Branch ' this.FlatStack
        If pFlatRoot->pBranch->BranchCount=0 Then : pFlatRoot->pBranch->BranchCount=1 : this.uCount=1 :  End If
        pTemp1 = this.pLastNode
        If IsLastNode=0 Then
            If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If
            If pTemp2->pPrev<>0 And pTemp2->Tag(0)<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            pTemp2->pPrev= this.pLastNode : pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->Tag(uTag) = Str_tmp : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            this.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount     
            If bHashStepRev=1 Then : If this.Up=0 Then : this.BlindStep : End If : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If : Return 1 :  End If             
        Else
            pTemp1->pNext=pTemp2  : pTemp2->pNext=0 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2  : pTemp2->Tag(uTag)=Str_tmp : pTemp2->pPrev=pTemp1  '
            this.pNode=pTemp5->pBranch : this.pFirstNode = pTemp5->pPrev : pLastNode=pTemp5->pPrev->pBranchLastNode : this.uCount=pTemp5->pPrev->BranchCount 
            If bTracking=1 Or bPickReduce=1 Then :  If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL  Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If  : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If ' this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL : Return 1 : End If
    Return 1
End Property

Property List.RestoreHash As Byte
    Dim As ListNode Ptr pTemp,  pTmpPrev, pTmpNext, pMove
    Dim str_tmp as string=this.Tag : Dim bTagExists As Byte : Dim uTagTmp As Byte=uTag
    pTemp=this.pnode : str_tmp=this.Tag(uTag) : If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : Return 0 : End If
    'HashTagging
    uTag=0 : bRHByPass=1 : bTagExists=this.HashTag(str_tmp) : bRHByPass=0 :
    'Gestion des modes (RHmethod)
    If bTagExists=1 And pNode->Tag(1)<>""  Then ' tag deja existant et "vraie" clef
        If bRHmethod=-1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
        ElseIf bRHmethod=1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
        Else : If pNode->Tag(1)=LIST_DEL Then : pNode->Tag(1)=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
        End If       
    Else : pTemp->Tag(0)= this.pnode->Tag(uTag) : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext
  '  If bNFmethod<>3 Then : pTemp->pBranch=this.pnode->pBranch : End If
    this.pnode->pPrev->pNext=pTemp
    If this.pnode->pNext<>0 Then : If this.pnode->pNext->pPrev=this.pnode Then : this.pnode->pNext->pPrev=pTemp : End If : End If
    If this.pnode=this.pLastNode Then : this.pLastNode=pTemp : End If : If this.pnode=this.pFirstNode Then : this.pFirstNode=pTemp : End If     
    If this.pnode->pBranch<>0 Then
      '  pFirstNode->Tag(1)=""
      '  pnode->pBranch->Tag(1)=""
        If this.pnode=this.pFirstNode->pBranchLastNode Then : this.pFirstNode->pBranchLastNode=pTemp : End If
        If this.pnode->pBranch->pBranch=this.pnode Then : this.pnode->pBranch->pBranch=pTemp : End If       
        pTemp->pBranch=this.pnode->pBranch : pTemp->pBranchLastNode=this.pnode->pBranchLastNode : pTemp->BranchCount=this.pnode->BranchCount
    End If
    'Reprise ds Flat List
    this.FlatStack(1)
    If bTagExists<>2 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext
    End If
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - PROPERTIES PARAMETERS
Property List.AutoCursor(b As Byte) As Byte : If 0<=b<=3 Then : bAutoCursor=b : Return 1 : End If : Return 0 : End Property
Property List.BranchCountDown(i as Byte) As Byte
    If i<>0 And i<>1 Then : Print "BranchCountDown : invalid parameter" : Return 0 : ElseIf i=0 Or (i=1 And bColBcountLocked=0) Then : bBranchCountDown=i : bColBcountLocked=i : Return 1 : Else : Print "Branch count vector already booked" : Return 0 : End If
End Property
Property List.CopyCatMethod(i As Byte) As Byte : If i=0 Or i=1 Then : bCopyCatMethod=i : Return 1 : Else : Print "CopyCatMethod : invalid parameter" : Return 0 : End If : End Property
Property List.HashKeyUnique(ub as Byte) As Byte : If ub=0 Or ub=1 Then : bHashKeyUnique=ub : Return 1 : Else : Print "HashKeyUnique : invalid parameter" :  Return 0 : End If : End Property
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>0 And bHashLen<255 Then : this.bHashLen = bHashLen : Return 1 : Else : Print "HashLen : invalid parameter" :  Return 0 : End If : End Property
Property List.KeysRegister(ub As uByte) As Byte :  If ub=0 Or ub=1 Then : ubKeysRegister=ub : Return 1 : Else : Print "KeysRegister : invalid parameter" :  Return 0 : End If : End Property
Property List.NFmethod(i As Byte) As Byte : If i=-1 Or i=0 Or i=1 Then : this.bNFmethod=i : Return 1 : Else : Print "NFmethod : invalid parameter" : Return 0 : End If : End Property
Property List.NFrecursive(i As Byte) As Byte : If i=1 Then : this.bPickReduce=1 : Else : this.bPickReduce=0 : End If : Return 1 : End Property
Property List.PVSmethod(ub As Byte) As Byte :
    If ub=-1 Then : bPVSmethod=ub : Return 1
    ElseIf bColBcountLocked=0 and ub<2 Then : bPVSmethod=ub : bColBcountLocked=1 : Return 1
    Else : Print "PVSmethod : Branch count vector already booked or invalid parameter" : Beep : sleep : Return 0 : End If
End Property
Property List.PVSratio(ub As uByte) As Byte : If ub>1 Then : PVS_ratio=ub : Return 1 : Else : Return 0 : End If : End Property
Property List.RHmethod(i As Byte) As Byte : If -2<i<2 Then : this.bRHmethod=i : Return 1 : Else : this.bRHmethod=-1 : Return 0 : End If : End Property
Property List.SeekMethod(i as Byte) As Byte : If i=0 Or i=1 Or i=2 Then : this.bSeekMethod=i : Return 1 : Else : Return 0 : End If : End Property
Property List.SnatchBLmethod(i As Byte) As Byte : If i=0 Or i=1 Then : bSnatchBLMethod=i : Return 1 : Else : Print "SnatchBeMethod : invalid parameter" : Return 0 : End If : End Property
Property List.TrackMethod(by As Byte) As Byte : If by=0 Or by=1 Then : bTrackingMethod=by : Return 1 : Else : Return 0 : End If: End Property
Property List.TrackMultiKeys(uB as uByte) As Byte : If -1<=uB<=MAX_COLS Then : bTrackMultiKeys=uB : Return 1 : End If : Return 0 : End Property
Property List.VectorUnlock As Byte : bColBcountLocked=0 : bColTrackLocked=0 : Return 1 : End Property
Property List.VectorClear As Byte
    Dim As ListNode Ptr Ptemp1=pNode, pTemp2 : Dim As Byte IsUp=0
    pTemp2=pTemp1->pNext
    If pTemp2=0 Or pNode->Tag(0)=LIST_RES  Or pNode->Tag(0)=LIST_DEL Then : Return 0 : End If
    If bColBcountLocked=1 Or bPVSmethod=1 Then : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : Wend
    End If : pNode=pTemp1 : Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLOW CONTROL
Property List.Up As Byte : If pFirstNode=pFirstFIRSTnode Then : Return 0 : Else :  this.UpLevel : Return 1: End If : End Property
Property List.Down As Byte
    If pnode->pBranch=0 Or pNode->Tag(0)=LIST_RES Then  : Return 0 : End If
    If pnode->pBranch->pPrev<>pFirstNode Then : Return 0 :
    Else : pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pNode->pBranch : uCount=pFirstNode->BranchCount : pLastNode=pNode->pBranch->pBranchLastNode : pNode=pNode->pBranch : Return 1
    End If
End Property
Property List.HoldBack As Byte : Return this.HoldBack(0) : End Property
Property List.HoldBack(by As Byte) As Byte   
    If pNode->Tag(0)=LIST_RES Or bColTrackLocked=1 Then : Return 0
    ElseIf TrackTrace(by)<>0 Then : TrackTrace(by)->pBranchLastNode=pNode : TrackTrace(by)=this.pNode : Return 1
    Else : this.TrackSet(by) : pNode->pBranchLastNode=0 : TrackTrace(by)=pNode : Return 1
    End If
End Property
Property List.TrackStep As Byte
    Dim As ListNode Ptr pTemp1 : bAlrdyTracked=0
    If pNode->pBranchLastNode->Tag(0)=LIST_DEL Or bColTrackLocked=1 Then : this.Root : bTracking=0 : Return 0 : End If ' Or pNode->pBranchLastNode->Tag(0)=LIST_RES
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag(0)<>LIST_RES Then           
        pNode=pNode->pBranchLastNode : bTracking=1
        If bTrackingMethod=1 Then : this.TrackCompute ': pLastNode->pNext=0
        End If : Return 1
    End If : this.TrackCompute : bTracking=0 : Return 0
End Property
Property List.Track As Byte : Return this.Track(0) : End Property
Property List.Track(by As Byte) As Byte
    this.Root : If bColTrackLocked=1 Then : Print "Tracking vector already in use (internal) by CopyCat/Follow" & chr(10) & "Use HashStep or other iterator" & chr(10) & "Attempt to use incompatible vectors may lead to crash" : Return 0 : End If : bAlrdyTracked=0
    If pNode->Tag(0)<>LIST_DEL And pNode->Tag(0)<>LIST_RES And pNode<>pLocalMove Then : This.TrackCompute : End If : bTracking=1 : this.Root ': This.TrackMethod(1)
    If this.Tracks(by).pNode=0 Then : this.TrackSet(by)  : Return 0
    Else
        pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : this.NodeRecycle : pNode=AllowCake : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL
        If this.Tracks(by).pNode->Tag(0)=LIST_DEL Then : pNode->pBranchLastNode=this.Tracks(by).pNode->pBranchLastNode
        Else : pNode->pBranchLastNode=this.Tracks(by).pNode
        End If
        pFirstNode=this.Tracks(by).pFirstNode : pLastNode=pFirstNode->pBranchLastNode : bHashLen=this.Tracks(by).bLcHashLen
        pNode->pBranch=0 : pNode->pPrev=0 : pNode->Tag(0)=""
        Return 1
    End If
End Property
Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte
    this.NodeRecycle : If pNode->pBranchLastNode<>0 Then : this.Tracks(by).pNode=pNode->pBranchLastNode  : Else : this.Tracks(by).pNode=pNode : End If
    this.Tracks(by).pFirstNode=pFirstNode : this.Tracks(by).bLcHashLen=bHashLen : TrackTrace(by)=0 : Return 1
End Property
Property List.TrackClear As Byte : Return this.TrackClear(0) : End Property
Property List.TrackClear(by As Byte) As Byte : TrackTrace(by)=0 : Return 1  : End Property
Property List.IsTracked As Byte : Dim i As Byte : If pNode->pBranchLastNode<>0 And pNode->Tag(0)<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS-1 : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : End Property

Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    Lcontext(by).pNode=pNode : Lcontext(by).pFirstNode=pFirstNode : Lcontext(by).pLastNode=pLastNode : Lcontext(by).uCount=this.uCount : Lcontext(by).LcHashTag=pNode->Tag(0) : Lcontext(by).bLcHashLen=this.bHashLen
    Return 1
End Property
Property List.Recover As Byte : Return this.Recover(1) : End Property
Property List.Recover(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pNode=Lcontext(by).pNode : pFirstNode=Lcontext(by).pFirstNode : this.bHashLen=Lcontext(by).bLcHashLen
    pLastNode=pFirstNode->pBranchLastNode : this.uCount= this.pFirstNode->BranchCount : this.bHashLen=Lcontext(by).bLcHashLen
    Return 1
End Property
Property List.Follow(pList As List) As Byte
    Dim As ListNode Ptr pTemp1=pList.Relation : bAlrdyTracked=0
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode : bTracking=1
    If pTemp1<>0 Then : this.pNode=pTemp1 : Else : Return 0 : End If
    this.pLastNode=pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
    Return 1
End Property

'==========================================================================================MEMORY MANAGEMENT
Property List.FlatCount As uInteger : Return this.pFlatRoot->pBranch->BranchCount : End Property
Property List.GarbageCount As uInteger : Return this.uGarbCt : End Property
Property List.ContainerCount As uInteger : Return this.uContainerGarbCt : End Property
Property List.NodeCount As uInteger : Return this.uNodeCOUNT : End Property

Property List.GarbageFlat As Byte
    Dim L_Context As ListContext : Dim As ListNode Ptr pTemp1, pTemp2, pTemp3 : Dim i as Byte
    If pFlatRoot->pBranch=0 Then : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then : pLocalMove=pFlatRoot->pBranch : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : this.NodeRecycle : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev
    If pTemp2=0 Then
        L_Context.pNode=pNode : L_Context.pFirstNode=pFirstNode : L_Context.pLastNode=pLastNode : L_Context.uCount=this.uCount
        this.FlatStack : pTemp2=pEndFlat->pPrev
        pNode=L_Context.pNode : pFirstNode=L_Context.pFirstNode : pLastNode=L_Context.pLastNode : this.uCount=L_Context.uCount
    End If :  If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext
    pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot
    Do
        pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If
        pNode=pTemp3
        pTemp1=pTemp1->pNext
    Loop Until pTemp1=pTemp2
    pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ': pTemp1->ListData.sData=""
    pTemp3=pNode : pNode=pTemp1 : this.Val("") : pNode=pTemp3
    uGarbCt+=pFlatRoot->pBranch->BranchCount
    pFlatRoot->pBranch->pNext=pFlatRoot->pBranchLastNode : pFlatRoot->pBranchLastNode->pPrev=pFlatRoot->pBranch : pFlatRoot->pBranch->BranchCount=0
    If pFirstNode=pFlatRoot->pBranch Then : uCount=0 : this.RootPrivate : End If
    Return 1
End Property

Property List.Recycle As uInteger : this.Up : this.Root : this.AllOf : Return this.AllRecycle : End Property  '

Property List.DropAll As uInteger  'pRoot principal + pFlatRoot + pFlatRoot->pBranch + pGarbage + pLastLAST/pWhyte = 5 nodes déalloues ds destructor     
    If this.IsDestroyed=1 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
    this.Root : this.GarbageFlat :  this.AllOf : this.AllRecycle : this.NodeRecycle : this.NodeRecycle2
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext  : Dim iLong As uInteger=0     
    While pTemp<>pGarbage And pTemp<>0 And pTemp<>pFlatRoot
        If pFlatRoot->pNext->ListData<>0 Then : _Deallocate(pFlatRoot->pNext->ListData) : End If
        _Deallocate(AllowCake) : pTemp=pFlatRoot->pNext : this.uNodeCOUNT-=1 : iLong+=1
    Wend
    Dim pPanTemp As ListContainer Ptr =pPanCakeGarbage->pNextContainer : Dim SeekMt As Byte=this.bSeekMethod
    While pPanTemp<>pPanCakeGarbage : _Deallocate(AllowPanCake) : pPanTemp=pPanCakeGarbage->pNextContainer : Wend  ' pPanCakeGarbage->pNextContainer=pPanCakeGarbage       
    this.bSeekMethod=SeekMt : uCount=0 : this.pFirstNode->BranchCount=0   
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then :  _Deallocate(pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1 : iLong+=1 : End If
    this.AllOfPrivate
    Return iLong   
End Property

Property List.Destroy As Byte
    If bPVSmethod<>-1 Then : Print "PVS_Count=" & PVS_Count  : End If '& " (the bigger, the most the optimization algo was used)" : End If
    If ubKeysRegister=1 Then : Print "KR_Count=" & KR_Count  : End If
    If this.IsDestroyed=1 Then : Return 0 : End If
    this.Root : this.DropAll : IsDestroyed=1
    If pPanCakeGarbage<>0 Then _Deallocate(pPanCakeGarbage) : pPanCakeGarbage=0 : End If  :
    If this.pFlatRoot<>0 Then
        If this.pFlatRoot->ListData<>0 Then : _Deallocate this.pFlatRoot->ListData : this.pFlatRoot->ListData=0 : End If
        If this.pFlatRoot->pBranch<>0 Then
            If this.pFlatRoot->pBranch->pNext<>0 And pFlatRoot->pBranch->pNext<>pEndFlat Then               
                _Deallocate(this.pFlatRoot->pBranch->pNext) : pFlatRoot->pBranch->pNext=0 :  this.uNodeCOUNT-=1
            End If
            _Deallocate(this.pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1
        End If
        _Deallocate(this.pFlatRoot) : pFlatRoot=0 : this.uNodeCOUNT-=1
    End If
    If this.pEndFlat->ListData<>0 Then : _Deallocate this.pEndFlat->ListData : this.pEndFlat->ListData=0 : End If
    If this.pLastLASTNode->ListData<>0 Then : _Deallocate this.pLastLASTNode->ListData : this.pLastLASTNode->ListData=0 : End If
    If this.pGarbage->ListData<>0 Then : _Deallocate this.pGarbage->ListData : this.pGarbage->ListData=0 : End If
    If this.pWhyteMove->ListData<>0 Then : _Deallocate this.pWhyteMove->ListData : this.pWhyteMove->ListData=0 : End If
    If this.pFirstFIRSTNode->ListData<>0 Then : _Deallocate this.pFirstFIRSTNode->ListData : this.pFirstFIRSTNode->ListData=0 : End If
    If this.pNode->ListData<>0 Then : _Deallocate this.pNode->ListData : this.pNode->ListData=0 : End If
    If this.pEndFlat<>0 Then : _Deallocate(this.pEndFlat) : pEndFlat=0 : This.uNodeCOUNT-=1 : End If   
    If this.pLastLASTNode<>0 And pLastLASTNode<>pWhyteMove And pLastLASTNode<>pFirstFIRSTNode Then : _Deallocate(this.pLastLASTNode) : pLastLASTNode=0 : this.uNodeCOUNT-=1 : End If
    If this.pGarbage<>0 And pGarbage<>pNode Then : _Deallocate(this.pGarbage) : pGarbage=0 : This.uNodeCOUNT-=1 : End If
    If this.pWhyteMove<>0 Then : _Deallocate(this.pWhyteMove) : pWhyteMove=0 : This.uNodeCOUNT-=1 : End If
    If this.pFirstFIRSTNode<>0 Then : _Deallocate(this.pFirstFIRSTNode) : pFirstFIRSTNode=0 :  this.uNodeCOUNT-=1 : End If
    If this.pNode<>0 Then : _Deallocate(this.pNode) : pNode=0 : this.uNodeCOUNT-=1 : End If
    If Listptemp<>0 Then : _Deallocate(Listptemp) : Listptemp=0 : End If : If Listptemp2<>0 Then : _Deallocate(Listptemp2) : Listptemp2=0 : End If : If zp3<>0 Then :  _Deallocate(zp3) : zp3=0 : End If
   ' If this.uNodeCount>2 Then : Print "Erreur a reporter : " & Str(this.uNodeCount-2) & " non dealloues !" : sleep : End If   '_Deallocate( New(@this) List )   
    Return 0
End Property


Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.992 -

Post by Lost Zergling »

Archive 0.992 Part 3/3

Code: Select all


'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
  Dim As ListNode Ptr pTemp1, pTemp2
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode=pLocalMove Or pNode=pLocalRoot Or pNode=pEndFlat Then : Return 0 : End If
    this.NodeRecycle : this.NodeRecycle2
    If bSnatchBLMethod=0 Then       
        If pNode->pBranch=0 Then
            this.Branch : this.BlindTag("") : pTemp1=pNode : pLocalMove=pNode : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL
            If this.Snatch(pList) <> 1 Then : this.NodeRecycle : pLocalMove=pFirstNode : pFirstNode->pBranch->pBranch=0 : pFirstNode->pBranch=0 :  pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : this.NodeRecycle : Return 0
            Else : pTemp1->pPrev->pNext=pTemp1->pNext : pTemp1->pNext->pPrev=pTemp1->pPrev                 
            End If : this.uCount-=1 : pFirstNode->BranchCount-=1 : this.NodeRecycle
        Else : this.Branch : pNode=pFirstNode->pNext : If this.Snatch(pList) <> 1 Then : Return 0 : End If
        End If
 '       pTemp1=pFirstNode ' MAJ des pointeur pFirstNode->pPrev
 '       While pTemp1->pNext<>0 And pTemp1<>pFirstNode->pBranchLastNode : pTemp1=pTemp1->pNext : If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode : End If : Wend 
    Else       
        If pNode->pBranch=0 Then
            pTemp2=pList.GiveBranchDown : If pTemp2=0 Then : Return 0 : End If
            pTemp2->pBranch=pNode : pTemp2->pPrev=pFirstNode
            pNode->pBranch=pTemp2
            pLastNode=pTemp2->pBranchLastNode : pFirstNode=pTemp2 : pNode=pFirstNode->pNext : Return 1
        Else
            pTemp2=pList.GiveBranchDown : If pTemp2=0 Then : Return 0 : End If
            this.Branch :
            pTemp2->pPrev=pFirstNode->pPrev : pTemp2->pBranch=pFirstNode->pBranch : pTemp2->pBranch->pBranch=pTemp2
            pFirstNode->pNext->pPrev=pTemp2->pBranchLastNode : pTemp2->pBranchLastNode->pNext=pFirstNode->pNext
            pTemp2->pBranchLastNode=pFirstNode->pBranchLastNode
            pTemp1=pFirstNode ' MAJ des pointeur pFirstNode->pPrev
            While pTemp1->pNext<>0 And pTemp1<>pFirstNode->pBranchLastNode : pTemp1=pTemp1->pNext : If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pTemp2 : End If : Wend         
            pLocalMove=pFirstNode : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : pFirstNode=pTemp2
        End If
    End If
    this.UpLevel : Return 1
End Property

Property List.Snatch(pList As List) As Byte
    Dim As ListNode Ptr pTemp1, pTemp2
    this.NodeRecycle : this.NodeRecycle2
    If pNode->Tag(0)=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If
    ElseIf pNode->Tag(0)=LIST_RES Then : pNode=pNode->pNext : Return 0 : End If
   ' If pNode=pWhyteMove Then : Return 0 : End If
    pTemp1=pList.GiveBranch : If pTemp1=0 Then : Return 0 : End If
   ' If pFirstNode=pFirstFIRSTNode Then : pTemp2= : End If
    If bBranchCountDown=1 Then : this.BCountDown(pTemp1->BranchCount) : End If : uCount+=1 : pFirstNode->BranchCount+=1
    If pNode<>pLastNode Then : pNode->pNext->pPrev=pTemp1 : Else : pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pTemp1 : End If
    If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode  : End If
    pTemp1->pNext=pNode->pNext : pNode->pNext=pTemp1 : pTemp1->pPrev=pNode
    If pNode->pBranch<>0 Then : pNode->pBranch->pBranch=pNode : End If
    pList.AllOfPrivate : pNode=pTemp1 : this.VectorClear : Return 1
End Property

Property List.FlatSnatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : Dim pTemp2 As ListNode Ptr   
    pTemp1=pList.GiveFlat : If pTemp1=0 Then : Return 0 : End If
    pFlatRoot->pBranch->BranchCount+=pTemp1->BranchCount : uNodeCOUNT+=pTemp1->BranchCount : pTemp1->BranchCount=0
    pTemp2=pTemp1->pBranch : pTemp1->pBranch=0 : pFlatRoot->pBranch->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pBranch->pNext
    pFlatRoot->pBranch->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot->pBranch : Return 1
End Property

Property List.GarbageSnatch(pList As List) As Byte
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2 : Dim As ListNode Ptr pTemp1, pTemp2
    pTemp1=pList.GiveGarbage : If pTemp1=0 Then : Return 0 : End If : uNodeCOUNT+=pTemp1->BranchCount : uGarbCt+=pTemp1->BranchCount
    pTemp2=pTemp1->pBranch : pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext : pTemp1->pBranch=0 : pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot   
    pPanTemp1=pPanCakeGarbage->pNextContainer
    pPanTemp2=pList.GivePanCake : If pPanTemp2=0 Then : Return 0 : End If :  pPanCakeGarbage->pNextContainer=pPanTemp2
    pPanTemp2=pList.GiveLastPanCake : uContainerGarbCt+=pList.GivePanCakeCount : pPanTemp2->pNextContainer=pPanTemp1 : Return 1
End Property

Property List.CopyCat(pList As List) As Byte
    Dim As ListNode Ptr pTmp1, pTmp2=pNode : Dim as byte by=1 : this.NodeRecycle
    pTmp1=pNode->pNext : pList.HashKeyUnique(0) : pList.HashSort(1) : pList.fSortMethod(1)
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pList.SetRelation(bCopyCatMethod)
    If this.uTag=0 Then
        If this.bCopyCatMethod=1 Then : While pNode<>pTmp1 and by=1 : pList.HashTag(this.HashTag) : pList.RwTag1(this.Tag(1)) : pList.SetRelation1(this.pNode) : by=this.HashStep : Wend
        Else : pList.BranchCountDown(0) : While pNode<>pTmp1 and by=1 : pList.HashTag(this.HashTag) : pList.RwTag1(this.Tag(1)) : pList.SetRelation2(this.pNode) : by=this.HashStep : Wend   
        End If
    Else
        If this.bCopyCatMethod=1 Then : While pNode<>pTmp1 and by=1 : pList.HashTag(this.Tag(uTag)) : pList.SetRelation1(this.pNode) : by=this.HashStep : Wend
        Else : pList.BranchCountDown(0) : While pNode<>pTmp1 and by=1 : pList.HashTag(this.Tag(uTag)) : pList.SetRelation2(this.pNode) : by=this.HashStep : Wend
        End If
    End If
    pNode=pTmp2 : pList.HashKeyUnique(1) : Return 1
End Property



Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.993 -

Post by Lost Zergling »

Archive Beta 0.993 Part 1

Code: Select all

' NOTICE : Thank you to remove first single quote on the line below once you accepted the licence.
' /'   In case redistribution of SOURCES you may ensure to reactivate the acceptance of the license. This notice may be anywhere in source code till licensed user is aware it exists.
CONST PRODUCT_LIC =_
"_______________________________________________________________________________" & chr(10) &_
"  LZListsEngine/ListsVM by Etienne Carfagnini - contact:etienne.carfa@gmail.com" & chr(10) &_
"  Bd Henri Barbusse 92700 Colombes France 01 46 49 99 02" & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  This Freeware/Openware licence specify the rights to use the software" & chr(10) &_
"* Distribution of derivating software : " & chr(10) & "  The information access to the original software must be guaranteed to" & chr(10) & "  developers and users (https://freebasic.net/forum/ or alternative mentionned)" & chr(10) &_
"* Right to use the software and its derivating : 2 options : " & chr(10) & " >OPTION 1 (Openware) :"  & chr(10) & "  The software is free for any use (under FreeBasic)." & chr(10) &_
"  'LZLE Openware licence' is mentionned in licence contributors." & chr(10) &_
"  The software must be compiled using any official GPL FreeBasic Compiler." & chr(10) & "  https://freebasic.net/forum/viewforum.php?f=1 Or" & chr(10) & "  http://users.freebasic-portal.de/stw/builds/)" & chr(10) &_
" >OPTION 2 (Freeware) (any language) :"  & chr(10) & "  The software is free for any use except the following limitation as to its"  & chr(10) & "  fields of application : not for use on virtual machine or on virtual server." & chr(10) &_
"  'LZLE Freeware licence' is mentionned in licence contributors." & chr(10) &_
"* Apart from the restrictions of use (options 1 and 2) which are not compatible"  & chr(10) & "  with the rights of uses specified in clause 5.1, the legal clauses whenever"  & chr(10) &_
"  compatible will be those specified by the CeCILL-C license"  & chr(10) & "  ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )" & chr(10) &_
"  Disclaimer :"  & chr(10) & "  This licence refers to CeCILL-C but is NOT a CeCILL-C because the right to"  & chr(10) & "  use the software with no restriction is limited to the FreeBasic ecosystem." & chr(10) &_
"  This because it aims to be an extension of the language instructions set."  & chr(10) &_
"  LZLE (instruction set architecture,coding style) is dedicated to FreeBasic."  & chr(10) &_
"  This notice constitutes a whole that must be present in the source code." & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  Cette licence Freeware/Openware precise les droits a utiliser le logiciel" & chr(10) &_
"* Distribution de logiciels derives :" & chr(10) & "  L'acces informatif au logiciel original doit etre garanti aux" & chr(10) & "  developpeurs et aux utilisateurs (https://freebasic.net/forum/ ou autre)." & chr(10) &_
"* Droit d'utiliser le logiciel et ses derives : 2 options : " & chr(10) & " >OPTION 1 (Libre) :"  & chr(10) & "  Le logiciel est gratuit pour toute utilisation (sous FreeBasic)." & chr(10) &_
"  'LZLE licence Openware' est mentionne dans les contributions." & chr(10) &_
"  Le logiciel doit etre compile en utilisant n'importe quel compilateur GPL" & chr(10) & "  FreeBasic 'officiel' " & chr(10) & "  https://freebasic.net/forum/viewforum.php?f=1 ou bien" & chr(10) & "  http://users.freebasic-portal.de/stw/builds/" & chr(10) &_
" >OPTION 2 (Gratuiciel) (tout langage):"  & chr(10) & "  Le logiciel est gratuit pour tout usage sauf la limitation suivante quant a"  & chr(10) & "  son champs d'application : pas d'utilisation sur machine ou serveur virtuel." & chr(10) &_
"  'LZLE licence Freeware' est mentionne dans les contributions." & chr(10) &_
"* En dehors des restrictions d'utilisation (options 1 et 2) lesquelles ne sont "  & chr(10) & "  pas compatibles avec les droits d'utilisation prevus a la clause 5.1, les"  & chr(10) &_
"  clauses applicables seront celles compatibles specifiees par la licence"  & chr(10) & "  CeCILL-C ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-fr.txt )" & chr(10) &_
"  Avertissement :"  & chr(10) & "  Cette licence fait reference a la licence CeCILL-C mais n'en est PAS une car"  & chr(10) & "  le droit a utiliser librement le logiciel est limite a l'ecosysteme FreeBasic" & chr(10) &_
"  Ce moteur de liste a jeu d'instructions est dedie au langage FreeBasic" & chr(10) &_
"  Cette notice constitue un tout lequel doit etre present dans le code source." & chr(10) &_
"_______________________________________________________________________________"
Dim k As String
Print PRODUCT_LIC : Print
Print "Please press 'Y' (Yes) to accept the licence or Esc to abort"
Print "Merci d'appuyer sur 'O' (Oui) pour accepter la licence ou echap pour annuler"
Do : k = Inkey : Select Case k : Case "Y" : Exit Do : Case "y" : Exit Do : Case "O" : Exit Do : Case "o" : Exit Do : Case Chr(27) : System : End Select : Loop
Print "Removing first single quote on line 2 in source code will activate the licence" : Print "Retirer la premiere simple quote en ligne 2 du code source activera la licence" : Print "Thank you for chosing this software - Merci d'avoir choisi ce logiciel" : Print
'/ ' END NOTICE

Dim Shared As uInteger AllocateDeallocateCounter=0
Function _Callocate(Byval n As Integer) As Any Ptr : AllocateDeallocateCounter += 1 : Return Callocate(n) : End Function
Sub _Deallocate(Byval p As Any Ptr) : AllocateDeallocateCounter -= 1 : Deallocate(p) : End Sub

CONST MAX_KEYLEN=50
CONST RUP_COLS=4 : CONST MAX_COLS=7 : CONST MAX_TRACKS=20 ' RUP_COLS = ListNode ArraySize / MAX_COLS = Extended range ListNode ArraySize / MAX_TRACKS = all tracks are on a same single track beware not to overwrite elements otherwise overwritten track will be rerouted
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4)

Type ListContainer 'Data Segment Level
    Dim str_tag_C(RUP_COLS+1 to MAX_COLS-1) As String
    Dim str_item as String : Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag(0 to RUP_COLS) As String : Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode : Dim BranchCount As uInteger=0
End Type
Type ListContext ' Branch context Level   
    Dim  As ListNode Ptr pNode, pFirstNode, pLastNode : Dim As String LcHashTag : Dim  As uInteger  uCount : Dim As uByte bLcHashLen
End Type

Type List
    Declare Constructor() : Declare Destructor()   
   
    Private:
    Dim As zString Ptr Listptemp=_Callocate(MAX_KEYLEN), Listptemp2=_Callocate(MAX_KEYLEN), zp3=_Callocate(1)
    Dim  As ListContext Lcontext(0 to MAX_COLS-1), Tracks(0 to MAX_COLS-1)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt, PVS_Count=0, KR_Count=0, uSortThreshold=300 ', iLenDelta  ', iLenStrTmp, iLenpNode, iLenCumul, iLenDiff
    Dim As Byte uTag=0, bSearchRes=0, bRHByPass=0, bHashStepRev=0, bfStepZero=0, bTrackingMethod=0, bTracking=0, bHTMethod=1, bHashKeyUnique=1, uSortTag=0,_
                        bSortMT=1, bNFmethod=1, bRHmethod=-1, bAutoCursor=1, bSeekMethod=2, bBranchCountDown=0, bPickReduce=0, bCopyCatMethod=0, bCopyCatRelation=0,_
                        bColBcountLocked=0, bColTrackLocked=0, bAlrdyTracked=0, bSnatchBLMethod=0, bHStepTrace=0, bTrackMultiKeys=1, bPVSmethod=-1, bnStepByPass=0
                       
    Dim As uByte bHashLen=1, IsDestroyed=0, PVS_ratio=3, ubKeysRegister=0, uB_CurLevel=1, uB_Level=1, uB_KeyStepCumul=1, uB_MaxLevel=1, uB_BottomLevel=255, uB_BottomByPass=0, nbloops=0
    Dim As String  sSearchTag, sLatestHTag, Str_tmp, str_arbo , Str_tmp2, str_testTMP
    Declare Property AllowCake() As ListNode Ptr                      ' Cooking here
    Declare Property AllowPanCake() As ListContainer Ptr          ' No comment
    Declare Property AllRecycle() As uInteger   
    Declare Property Branch() As Byte                                        ' Descend dans la liste enfants, creation de nouvelles entrées
    Declare Property UpLevel() As Byte                                      ' Revient à la liste parente   
    Declare Property NodeRecycle() as Byte                              ' Supression en décalé (NodeFlat)
    Declare Property NodeRecycle2() as Byte                            ' Supression en décalé (RestoreHash)
    Declare Property RootPrivate As Byte                                   ' Accès direct rapide à la racine
    Declare Property FlatStack(uB as uByte) As Byte                 ' Construction de la Flat List avec retour à la racine(0) ou accès à la flat liste (1)
    Declare Property BCountDown(i As Byte) As Byte                ' CountDown calculation   
    Declare Property ValPrivate(str_Value As String) As Byte
    Declare Property ValPrivate As String
    Declare Property AllOfPrivate As uInteger
    Declare Property TrackCompute As Byte
    Declare Property HashStepTrace As Byte                              ' Required by Sort (for optimization)   
   
    Public:   
    'Special features - Private declared Public   
    Declare Property SetRelation(by as Byte) as Byte
    Declare Property SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr
    Declare Property SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr
    Declare Property Relation As ListNode Ptr   
    Declare Property GiveBranchDown As ListNode Ptr
    Declare Property GiveBranch As ListNode Ptr
    Declare Property GiveFlat As ListNode Ptr
    Declare Property GiveGarbage As ListNode Ptr
    Declare Property GivePanCake As ListContainer Ptr
    Declare Property GiveLastPanCake As ListContainer Ptr
    Declare Property GivePanCakeCount As uInteger
    'Flat control
    Declare Property Tag(str_Tag As String) As Byte                 ' Create a new ListNode with Key=str_Tag OR retrieve position of an existing Tag
    Declare Property Tag As String                                            ' Return current Tag value in a list =Tag(0)
    Declare Property Tag(iTag As Integer) As String                  ' Return current Tag value of the specified entry in array
    Declare Property HasTag(str_Tag As String) As Byte           ' Return 1 if Tag exists
    Declare Property BlindTag(str_Tag As String) As Byte          ' Create a new ListNode with Key=str_Tag at end of the list
    Declare Property RwTag(s_Tag As String) As Byte               ' Rewrite Tag Value of current Node : if current node is Hashed, just rewrite HashTag Value not effective Key value
    Declare Property RwTag1(s_Tag As String) As Byte                ' Rewrite Tag Value(1)
    Declare Property RwTag2(s_Tag As String) As Byte                ' Rewrite Tag Value(2)
    Declare Property RwTag3(s_Tag As String) As Byte                ' Rewrite Tag Value(3)
    Declare Property RwTag4(s_Tag As String) As Byte                ' Rewrite Tag Value(4)
    Declare Property ColTags As Byte                                       ' Renvoie le numéro de la colonne de tag active       
    Declare Property ColTags(i as Byte) As Byte                        ' Définie la colonne de tag active de 0 à MAX_COLS, par défaut 0   
    Declare Property AllOf As uInteger                                       ' Return number of node in  considered Flat List (root or branch), set position to the first node of current branch
    Declare Property Count As uInteger                                     ' Return current node Count of considered Flat List
    Declare Property First As Byte                                              'Set current node to first node considering flat list (root or branch)   
    Declare Property Last As Byte                                              'Set current node to Last node considering flat list (root or branch)       
    Declare Property Val(str_value As String) As Byte                ' Assign a string (+50 len) to the current node that is identified by a Tag
    Declare Property Val As String                                             ' Return current node string datas   
    Declare Property ValTag(str_value As String) As String        ' Considering current Flat list (root or branch as a flat list) return string data identified by Key=str_Tag
    Declare Property fStep As Byte                                            ' FOR EACH - While MyList.fStep : .. : Wend Jump to next node till current flat list end
    Declare Property fStepRev As Byte                                     ' FOR EACH - Idem fStep Jump to previous node till current flat list reach firstnode
    Declare Property bStep As Byte                                           ' FOR NEXT - For i=1 to MyList.AllOf : MyList.bStep : ..... : Next i    -> Jump to next node (NO CHECK)
    Declare Property BlindStep As Byte                                     ' FOR EACH - While MyList.BlindStep : .. : Wend -And- FOR NEXT - For i=1 to MyList.AllOf : MyList.BlindStep : ..... : Next i  Jump to next node  (check)   
    Declare Property BlindStep(i As Integer) As Byte                  ' Jump to +/-n nodes BlindStep(0) equiv Last : goto LastNode  (NO CHECK)
    Declare Property fMove(i As Integer) As Byte                      ' Move a node +/- n positions
    'Sorting
    Declare Property ColSort(i as Byte) As Byte                          'The column number to sort on (0-n) col 0 is indexed. Définie la colonne de tri active de 0 à MAX_COLS, par défaut 0
    Declare Property fSortMethod(bsortM As Byte) As Byte        'FLAT  1=ascending / -1=descending
    Declare Property BTreeSortTH(uSortT As uInteger) As Byte
    Declare Property fSort As Byte                                              'FLAT sort
    Declare Property HashSort(ub as Byte) as Byte                   '0=No sort on mapping, 1=ascending sort on HashTag mapping or on RestoreHash remapping
    Declare Property Sort As Byte
    Declare Property Sort(bSortmt As Byte) As Byte
    'Hash control handling
    Declare Property Root As Byte                                           ' Check/Restore List integrity & set cursor to First node of root flat list - Shall be called before HashStep or After NodeFlat or RestoreHash
    Declare Property FlatStack As Byte                                    ' Flat List Access : use it before RestoreHash
    Declare Property RootNode As Byte                                  ' Set cursor to Root node of root flat list
    Declare Property EndNode As Byte                                   ' Set cursor to the last logical node  ( = While MyList.HashStep : Wend ) which is the last node of the last branch of last root flat node
    Declare Property HashStep As Byte                                   ' FOR EACH - recursive  parse property : syntax : While MyList.HashStep=1 : ... : Wend
    Declare Property HashStepRev As Byte                            ' FOR EACH - idem HashStep
    Declare Property KeyStep As Byte                                      ' FOR EACH - While MyList.KeyStep=1 : ... : Wend idem HashStep but show only Keys tagged by user, not the tree structure
    Declare Property KeyStepRev As Byte                               ' FOR EACH - idem KeyStep
    Declare Property nCurLevel(t as uByte) As Byte
    Declare Property nHashStep(t as uByte) As Byte
    Declare Property nKeyStep(t as uByte) As Byte
    Declare Property nHashStepRev(t as uByte) As Byte
    Declare Property nKeyStepRev(t as uByte) As Byte
    Declare Property nKeyStepRev as Byte
    Declare Property nKeyStep As Byte
    Declare Property HashTag(str_Tag As String) As Byte       ' Build a hash Key on str_Tag, Return 1 if already exits otherwise return 0   
    Declare Property HashTag As String                                  ' Return Hash key value of current node 
    Declare Property HasHashTag(str_Tag As String) As Byte ' Return 1 if str_Tag is a hash key otherwise return 0
    Declare Property HasKey(str_Tag As String) As Byte          ' Idem HasHashTag Return 1 only for values specified with HashTag (not all cascaded index values)
    Declare Property NodeFlat As Byte                                   ' Déréférence une arborescence de clefs (un HashTag), et traite les données en conséquence       
    Declare Property RestoreHash As Byte                             ' Envoi un node de la Flat List en Hash List (réindexation)
    'Hash Control - Object's properties parameters
    Declare Property AutoCursor(i As Byte) As Byte                 'Method for HasTag(string), HasHashTag and HasKey:  0=do nothing current node is unchanged,  1 -DEFAULT- =move current to found on success (HasHashTag), 2=move current to found on success (HasKey), 3=move on partial success
    Declare Property BranchCountDown(i As Byte) As Byte     ' 1/0 Activate(1) or desactivate(0) BranchCountDown, default 0
    Declare Property CopyCatMethod(i As Byte) As Byte          '0 or 1 : CopyCat(1) : tracking is using tracking (no HoldBack/track) OR CopyCat(0) : tracking to source is on BranchCount (no BranchCountDown enabled) but tracking possible inside index !
    Declare Property HashKeyUnique(ub as Byte) As Byte      ' Default=1  HashKeyUnique(0)=>HashTag always create a new key even though a key already exists
    Declare Property HashLen(bHashLen As uByte) As Byte  ' Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' Enregistrement du hashTag parent en premier node caché : optimise l'enregistrement et la récupération de la clef (propriété hashTag) mais ralenti le mapping hashTag("key")
    Declare Property NFmethod(i As Byte) As Byte                  ' Determine le fonctionnement de NodeFlat : NFmethod=-1 node=>GarbageCollector  NFmethod=0 node=>FlatList sauf parents reliquataires NFmethod=1 node=>FlatList même les nodes parents contenant toujours des dépendances
    Declare Property NFrecursive(i As Byte) As Byte               ' NFrecursive=0 Standard / NFrecursive=1 parents nodes auto send to garbage collector till no other child and till they are not keys
    Declare Property PVSmethod(ub As Byte) As Byte            ' Predictive Vectors Static (optimization algo for HashTag) -1=no PVS / disabled (default), 0= PVS on, 1=PVS with priority forced
    Declare Property PVSratio(ub As uByte) As Byte               ' Static coeff for PVS dynamic adjustement
    Declare Property RHmethod(i As Byte) As Byte                 ' Determine le fonctionnement de RestoreHash par rapport aux doublons : RHmethod=-1 : Hashnode->GarbageCollector  / RHmethod=0 : no swap / RHmethod=1 : Hashnode->FlatList
    Declare Property SeekMethod(i as Byte) As Byte              ' Method for Tag(string), HasTag(string), HashTag(string), HasHashTag and HasKey: 1(default)=seek from First to Last | 2: seek from Lastnode to firstNode | 0 :seek from currentnode to last node (Flat multikeys)
    Declare Property SnatchBLmethod(i As Byte) As Byte      ' For SnatchBelow 0=Source ParentNode snatched below target / 1=Source Child Nodes snatched below target (leaving ex-parent node in source list) (for intuitive key pairing between source & target)
    Declare Property TrackMethod(by As Byte) As Byte          ' MyList.TrackMethod(0)=might be faster (Default) / MyList.TrackMethod(1)=slow, might be more secure in specific cases (Pretty useless)
    Declare Property TrackMultiKeys(uB as uByte) As Byte    ' If <>0 multikeys will be automatically tracked (Track & TrackStep) on specified track each HashTag : working with CopyCat and RestoreHash as well
    Declare Property VectorUnlock As Byte                            ' Unlock auto security : Track vector is ONE choice between HoldBack/Track OR CopyCatMethod(1)/Follow - BranchCount vector is ONE choice between CopyCatMethod(0)/Follow OR BranchCountDown(1) OR PVSmethod(1+) - Using CopyCat index let you one choice left between Tracking, CountDown or PSV optimization
    Declare Property VectorClear As Byte                               ' If list structure has been changed (ie snatch, NodeFlat), tracking links or others (count down, PVS, or Follow) might be corrupted : working like CopyCat targeting current node and the whole child tree, clearing corrupted (or so called) links
    'Flow control
    Declare Property BranchCount As uInteger                        'Return Branch Count
    Declare Property Up As Byte                                              'idem UpLevel
    Declare Property Down As Byte                                         'idem Branch but prevent from creating an orphan sublist entry   
    Declare Property HoldBack As Byte                                  ' Works with Track : First Holback is initialiazing tracking, then each HolBack is recording a new tracked node. Track indicates to set cursor to first holbacked node & TrackStep is tracking all holbacked nodes in chronological order
    Declare Property HoldBack(i As Byte) As Byte                  ' Works with Track : indicates the number the track working with
    Declare Property TrackStep As Byte                                ' -SELECTIVE- FOR EACH - While MyList.TrackStep=1 : ... : Wend : selective PARSE only Keys marked for tracking by HoldBack
    Declare Property Track As Byte                                      ' Set track pointer to first tracked node
    Declare Property Track(i As Byte) As Byte                       ' Only one track but several track pointers
    Declare Property TrackSet As Byte                                 ' Create a breaking point in tracking : next List.Track+TrackStep will iterate from next tracked node just following breaking point / does not break track list, just replacing track starting point
    Declare Property TrackSet(i As Byte) As Byte
    Declare Property IsTracked As Byte                                ' When working with several tracks (pointers) it can be usefull to know wether a node has been already tracked or not to control tracking overwrite
    Declare Property TrackClear As Byte
    Declare Property TrackClear(i As Byte) As Byte              ' Indicates to reinitialize Track n°i : next HolBack will initialize a track to current node
    Declare Property Aside As Byte                                      ' Memorise ListNode ptr dans le pointeur n°0
    Declare Property Aside(i As Byte) As Byte                       ' Memorise ListNode ptr dans le pointeur n°i
    Declare Property Recover As Byte                                 ' Repositionne l'élément courant de la liste sur celui mémorisé par Take, si cet élément existe toujours, sinon renvoie False
    Declare Property Recover(i As Byte) As Byte                  ' Repositionne l'élément courant de la liste sur celui mémorisé par Take(i)
    Declare Property Follow(pList As List) As Byte
    'Memory management
    Declare Property FlatCount As uInteger                         ' Return number of values stored in Flat List
    Declare Property GarbageCount As uInteger                 ' Return number of nodes available in garbage collector
    Declare Property ContainerCount As uInteger                ' Return number of nodes container available in hidden garbage collector
    Declare Property NodeCount As uInteger                      ' Return number of nodes including not visible ones
    Declare Property GarbageFlat As Byte                            'Send all Flat List to GarbageCollector
    Declare Property Recycle As uInteger                            'AllFlat+GarbageCollector : détruit une arborescence et envoi tout en GarabgeCollector - do NOT garbage protected flat list
    Declare Property DropAll As uInteger                              'Remove all elements in list, except a 5/6 listnodes subset                         
    Declare Property Destroy As Byte                                   'Manual destructor
    'List Data Links & Exchange   
    Declare Property Snatch(pList As List) As Byte                  'Snatch a whole branch from another List to next node
    Declare Property SnatchBelow(pList As List) As Byte        'Snatch a whole branch from another List Below current node
    Declare Property FlatSnatch(pList As List) As Byte            'Target's Flat list is transfered to current list
    Declare Property GarbageSnatch(pList As List) As Byte    'Target's Garbage Collector is transfered to current list
    Declare Property CopyCat(pList As List) As Byte                'Create an index (linked to source)  from a flat (node per node) or indexed column (if so current node + its whole child tree), element by element (auto support multivalues) can work from loops (filtering)   
    'Debug
  '  Declare Property NextNode As String       
  '  Declare Property PrevNode As String   
End Type
'Shared
Dim Shared gCollector As List
' to do : Code Review+doc /
' BUGs :
'
' Property List.NextNode As String : Dim str_tmp as string="-" : If pNode->pNext<>0 Then : this.Aside : pNode=pNode->pNext : str_tmp= "next tag=" & pNode->Tag(0) & " & next hashtag=" & this.HashTag : this.Recover : Return str_tmp : End If : End Property
' Property List.PrevNode As String : Dim str_tmp as string="-" : If pNode->pPrev<>0 Then : this.Aside : pNode=pNode->pPrev : str_tmp= " prev tag=" & pNode->Tag(0) & " & prev hashtag=" & this.HashTag  & "  branch=" & Str(pNode->pBranch) : this.Recover : Return str_tmp : End If : End Property

'==========================================================================================CONSTRUCTOR & DESTRUCTOR  :  this.pFirstNode->pBranch->pBranchLastNode=0
Constructor List
    pFlatRoot = _Callocate(Len(ListNode)) : pNode = _Callocate(Len(ListNode)) : this.uNodeCOUNT+=2  ' Moment angulaire(petite masse)
    pPanCakeGarbage=_Callocate(Len(ListContainer)) : pPanCakeGarbage->pNextContainer=pPanCakeGarbage ': pTestContainer=pPanCakeGarbage ' Moment Angulaire(petite masse)
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag(0) = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT
    this.Root : this.AllOf
End Constructor
Destructor List : this.Destroy : End Destructor

'==========================================================================================TYPE LIST PRIVATE PROPERTIES
Property List.AllowCake As ListNode Ptr ' This.Vralloc
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext ' uGarbCt>1 ' If pTemp<>0 Then : If pTemp->pNext=0  Then  : pTemp=pGarbage : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 :  Return pTemp : End If  : End If
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1 : ' And pTemp<>0 ' pTemp->pNext=0 : pTemp->pPrev=0 : pTemp->pBranch=0 :
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ': this.pLastLASTNode=pTemp ' Moment Angulaire(petite masse)         
    End If : Return pTemp
End Property
Property List.AllowPanCake As ListContainer Ptr
    Dim pPanTemp As ListContainer Ptr : dim uB As uByte
    If pPanCakeGarbage->pNextContainer<>pPanCakeGarbage Then
        pPanTemp=pPanCakeGarbage->pNextContainer : pPanTemp->str_item="" : For uB=RUP_COLS+1 To MAX_COLS-1 : pPanTemp->str_tag_C(uB)="" : Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else : pPanTemp=_Callocate(Len(ListContainer)) ': If pTestContainer2=0 Then : pTestContainer2=pPanTemp : End If  ' : pPanTemp->str_item=""  ' Moment Angulaire(petite masse)
    End If : Return pPanTemp
End Property

Property List.AllRecycle As uInteger
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext       
    Dim NbCollected As uInteger=0
    If this.pNode->pNext=0 Or this.pGarbage->pNext=0 Then : Return 0 : End If
    If pGarbage->ListData<>0 Then : pGarbage->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pGarbage->ListData : pGarbage->ListData=0 : uContainerGarbCt+=1 : End If
    If pLocalMove=pLastLASTNode Then : pLastLASTNode=pLastLASTNode->pPrev : End If : this.NodeRecycle : This.RootPrivate
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode= this.pGarbage->pNext : Else : pNode= this.pFirstNode->pNext : End If  : If pNode=0 Then : Return 0 : End If
    If pNode <>0 Then
        Do
            If pNode->Tag(0)<>LIST_RES And pNode->pBranch<>0 Then   
                pNode->pNext->pPrev=pNode->pBranch->pBranchLastNode : pNode->pBranch->pBranchLastNode->pNext=pNode->pNext
                pNode->pNext=pNode->pBranch : pNode->pBranch->pBranch=0 : pNode->pBranch=0 : pNode->BranchCount=0
                pNode->pNext->pPrev=pNode : pNode->pNext->pBranchLastNode=0 ':  pNode->pBranchLastNode=0
            Else
                If this.pNode->pNext<>0 Then
                    pNode->Tag(0) = LIST_DEL : pNode->Tag(1)="" : pNode->BranchCount=0 : NbCollected +=1 ':  pNode->pBranchLastNode=0 ': iLong+=1
                    If pNode->ListData<>0 Then : pNode->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pNode->ListData : pNode->ListData=0 : uContainerGarbCt+=1 : End If                           
                    this.pNode=this.pNode->pNext
                End If               
            End If
        Loop Until pNode->pNext=0
    End If
    If NbCollected>0 Then : This.uGarbCt+=NbCollected : uCount=0 : this.pFirstNode->BranchCount=this.uCount : pLastNode=pNode : If pFirstNode=pFirstFIRSTNode Then : pLastLASTNODE=pNode : End If : End If   
    This.RootPrivate : pGarbage=pLastNode->pPrev :pTemp=pNode : pNode=pGarbage : this.Val(LIST_DEL) : pNode=pTemp
    Return NbCollected
End Property

Property List.Branch As Byte
    Dim pTemp As ListNode Ptr :  Dim pTemp1 As ListNode Ptr   
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp = this.pNode
    If this.pNode->pBranch=0 Then ' this.NewHash(this.pNode)
        pTemp1 = this.pLastNode : this.uCount+=1 : pTemp1->pNext = this.AllowCake 'And eat it
        pTemp1->pNext->pPrev = pTemp1 : pTemp1->pNext->Tag(uTag) = LIST_RES
        pTemp1 = pTemp1->pNext : this.pLastNode = pTemp1 : pNode=pTemp1  ' this.BlindTag(LIST_RES) :
        this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp
        pTemp->pBranch=this.pNode : pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
        this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : this.bSearchRes = 0 : Return 0
    Else 'Branche déjà créée
        this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
        this.pLastNode = this.pNode->pBranch->pBranchLastNode         
        this.pNode = this.pNode->pBranch : this.bSearchRes = 0 : Return 1
    End If   
End Property

Property List.UpLevel As Byte   
    If this.pFirstNode->pPrev = 0 Then : Return 0 : End If
    If this.pFirstNode->pBranch <> 0 Then ' Retour node de départ pour faciliter un parcours éventuel
        this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        this.pFirstNode = this.pFirstNode->pPrev : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode         
        this.bSearchRes = 0 ': this.sSearchTag = ""
        Return 1
    Else : Return 0
    End If               
End Property

Property List.NodeRecycle as Byte
    If pLocalMove<>0 Then 'pLocalMove est un node à suppression décalée       
        pLocalMove->pPrev=this.pFlatRoot : pLocalMove->pNext=this.pFlatRoot->pNext : pLocalMove->BranchCount=0 ' :  pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL :
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pLocalMove->ListData : pLocalMove->ListData=0 : uContainerGarbCt+=1 : End If
        this.pFlatRoot->pNext->pPrev=pLocalMove : this.pFlatRoot->pNext=pLocalMove : this.uGarbCt+=1
        pLocalMove = 0       
    End If
    Return 1
End Property
Property List.NodeRecycle2 as Byte
    If pLocalRoot<>0 Then 'pLocalRoot est un node LIST_RES             
        pLocalRoot->pPrev=this.pFlatRoot : pLocalRoot->pNext=this.pFlatRoot->pNext : pLocalRoot->Tag(0)=LIST_DEL  : pLocalRoot->BranchCount=0
        this.pFlatRoot->pNext->pPrev=pLocalRoot : this.pFlatRoot->pNext=pLocalRoot : This.uGarbCt+=1
        pLocalRoot->pBranch->pBranch=0 : pLocalRoot->pBranch->pBranchLastNode=0 : pLocalRoot->pBranch->BranchCount=0 :
        pLocalRoot->BranchCount=0 : pLocalRoot->pBranch=0 : pLocalRoot = 0
    End If
    Return 1
End Property

Property List.RootPrivate As Byte   
    this.AllOfPrivate : While UpLevel : Wend    ' While this.pFirstNode->pBranch <> 0 : this.UpLevel : Wend   '
    this.pFirstNode = this.pFirstFIRSTNode : this.bSearchRes = 0 : this.sSearchTag = ""
    this.pNode = this.pGarbage   
    Return 1
End Property

Property List.FlatStack(uB As Ubyte) As Byte
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    Dim pTemp1 As ListNode Ptr   
    This.RootPrivate
    this.pNode=this.pFlatRoot : this.Branch
    If this.pLastNode=this.pFlatRoot->pBranch Then
        If this.pEndFlat<>0 Then : this.pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=this.pFlatRoot->pBranch : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1         
        End If
    ElseIf this.pLastNode<>this.pEndFlat Then           
        If this.pEndFlat<>0 Then
            this.pEndFlat->pPrev->pNext=this.pEndFlat->pNext : this.pEndFlat->pNext->pPrev=this.pEndFlat->pPrev
            this.pEndFlat->pPrev=this.pLastNode : this.pLastNode->pNext=this.pEndFlat : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If                       
    End If     
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If uB=0 Then : this.UpLevel : End If : this.AllOfPrivate
    Return 1
End Property
Property List.BCountDown(i As Byte) As Byte : Dim pTemp As ListNode Ptr=pFirstNode : While pTemp->pPrev<>0 : If pTemp->pBranch<>0 Then : pTemp->pBranch->BranchCount+=i : End If : pTemp=pTemp->pPrev : Wend : Return 1 : End Property
Property List.ValPrivate(str_value As String) As Byte : If this.pValTmp->ListData=0 Then : this.pValTmp->ListData=this.AllowPanCake : End If : this.pValTmp->ListData->str_item=str_value : Return 1 : End Property
Property List.ValPrivate As String : If this.pValTmp->ListData=0 Then : Return "" : End If : Return this.pValTmp->ListData->str_item : End Property

Property List.AllOfPrivate As uInteger
    this.pNode = this.pFirstNode
    If this.pFirstNode=this.pFirstFIRSTNode Then           
        this.pNode = this.pGarbage
        If pWhyteMove<>0 And pWhyteMove<>pLastNode Then  'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc
            If pWhyteMove->pNext<>0 Then : pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode :  End If     
            pLastNode=pWhyteMove : pLastNode->pNext=pFirstFIRSTNode '0
        End If   
    End If : Return this.Count
End Property

Property List.TrackCompute As Byte
    Dim As ListNode Ptr pTemp1=pNode
    If bAlrdyTracked=1 Then : Return 1 : End If
    While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage
        If pTemp1->pBranch<>0 Then : pTemp1=pTemp1->pBranch->pPrev : Exit While : End If ' This code is naturally using one Swap, Cast and Exit for aesthetic and legitimate reasons, Gosub @ Extends are unfortunately missing.
        pTemp1=pTemp1->pPrev
    Wend
    If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
    pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : bAlrdyTracked=1 : Return 1
End Property

Property List.HashStepTrace As Byte
    While this.pnode->pBranch<>0
        bHStepTrace=-1
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : bHStepTrace=0 : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
         bHStepTrace=1 : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES destination is PRIVATE USE
Property List.SetRelation(by as Byte) as Byte : If by=0 Then : bColBcountLocked=1 : ElseIf by=1 Then : bColTrackLocked=1 : Else : Return 0 : End If : bCopyCatRelation=by : Return 1  : End Property
Property List.SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr : pNode->pBranchLastNode=pRelNode : Return pNode : End Property
Property List.SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr : this.pNode->BranchCount=CuInt(pRelFirstNode) : Return pNode : End Property
Property List.Relation As ListNode Ptr : If this.bCopyCatRelation=1 Then : Return pNode->pBranchLastNode : ElseIf this.bCopyCatRelation=0 Then : Return Cast(ListNode Ptr, pNode->BranchCount) : Else : Return 0 : End If : End Property

Property List.GiveBranchDown As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2   
    If pNode->pBranch=0 Or pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag(0)="" Then : Return 0
    ElseIf pNode->pBranch->Tag(0)<>LIST_RES Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    this.NodeRecycle : this.NodeRecycle2 : this.VectorClear
    pTemp1=pNode->pBranch : pNode->pBranch=0 :
    Return pTemp1
End Property

Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp4
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Then : Return 0 : End If     
    bfStepZero=0 : this.NodeRecycle : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp4=pNode->pPrev : pTemp1=pNode :
    If bBranchCountDown=1 Then : this.BCountDown(-pNode->BranchCount) : End If
    If pTemp1=pLastNode  Then : this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel : this.NodeRecycle2 : bfStepZero=1 :  Return pTemp1
    Else
        pNode->pPrev->pNext=pNode->pNext : pNode->pNext->pPrev=pNode->pPrev : uCount-=1 : pFirstNode->BranchCount-=1       
        If pTemp1=pLastNode And pFirstNode<>pFirstFIRSTNode Then
            this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel :  this.NodeRecycle2 : bfStepZero=1 : Return pTemp1
        End If         
    End If
    If pTemp4<>pFirstNode Then : pNode=pTemp4 : Else : pNode=pFirstNode->pNext : End If
    Return pTemp1
End Property

Property List.GiveFlat As ListNode Ptr   
    Dim As ListNode Ptr pTemp1, pTemp2
    If pFlatRoot->pBranch=0 Then : Return 0 : End If         
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Or pFlatRoot->pBranch->pNext=pFlatRoot->pBranch  Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev : If pTemp2=0 Or pTemp1=pTemp2 Then : Return 0 : End If
    pTemp1->pBranch=pTemp2 : pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=pFlatRoot->pBranch
    pTemp1->BranchCount=pFlatRoot->pBranch->BranchCount : uNodeCOUNT-=pFlatRoot->pBranch->BranchCount 'this.FlatCount :
    this.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If  ' this.FlatStack : uCount=0
    Return pTemp1   
End Property

Property List.GiveGarbage As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2
    If uGarbCt<2 Then : Return 0 : End If : pTemp1=pFlatRoot->pNext : pTemp2=pGarbage->pPrev : If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext=pGarbage : pGarbage->pPrev=pFlatRoot : pTemp1->pBranch=pTemp2 : pTemp1->BranchCount=uGarbCt
    uNodeCOUNT-= uGarbCt : uGarbCt=0
    Return pTemp1
End Property
Property List.GivePanCake As ListContainer Ptr
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2
    If uContainerGarbCt<2 Then : Return 0 : End If : pLastPanCake=0
    pPanTemp1=pPanCakeGarbage->pNextContainer : pPanTemp2=pPanTemp1
    While pPanTemp2->pNextContainer<>pPanCakeGarbage : pPanTemp2=pPanTemp2->pNextContainer : Wend : pPanTemp2->pNextContainer=0 : pLastPanCake=pPanTemp2
    pPanCakeGarbage->pNextContainer=pPanCakeGarbage : uContainerGivenCt=uContainerGarbCt : uContainerGarbCt=0
    Return pPanTemp1
End Property
Property List.GiveLastPanCake As ListContainer Ptr : Return pLastPanCake : End Property
Property List.GivePanCakeCount As uInteger : Return this.uContainerGivenCt : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLAT CONTROL
Property List.Tag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer Ptr
    If this.sSearchTag = str_Tag Then
        If this.bSearchRes=1 Then
            this.pNode = this.pSearchNode : Return 1 'pNode
        Else
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->Tag(uTag) = str_Tag ' pTemp->pNext->ListData = item :
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            this.pNode = pTemp : Return 0
        End If
    Else
        If this.bSeekMethod=1 Then : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then : pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
        Else
            pTemp = this.pNode : If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        End If
        If pTemp->Tag(uTag)<>str_Tag then ' New node
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->ListData = item : pTemp->pNext->Tag(uTag) = str_Tag
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If           
            If pFirstNode=pFirstFIRSTNode And pWhyteMove<>pLastNode Then
                pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode : pLastNode=pWhyteMove : pLastNode->pNext=0
            End If : this.pNode = pTemp : Return 0
        End If   
    End If
    this.pNode = pTemp : Return 1 'pTemp
End Property

Property List.Tag As String
 '  Return this.pNode->Tag(uTag)
    If uTag<=RUP_COLS Then : Return this.pNode->Tag(uTag)
    ElseIf pNode->ListData=0 Then : Return ""
    Else : Return pNode->ListData->str_tag_C(uTag)
    End If
End Property
Property List.Tag(i As Integer) As String
    If i<=RUP_COLS Then : Return this.pNode->tag(i) : Else : If pNode->ListData<>0 Then : Return pNode->ListData->str_tag_C(i) : Else : Return "" : End If : End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag   
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
    Else
        pTemp = this.pNode : If pTemp=0 Then :  pTemp = this.pFirstNode : End If
        If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag(uTag) = str_Tag Then
        this.pSearchNode=pTemp : this.bSearchRes=1 : If this.bAutoCursor=1 Then : pNode=pTemp : End If : Return 1
    Else : this.bSearchRes = 0 : Return 0 : End If   
End Property

Property List.BlindTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = str_Tag
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte : If uTag<=RUP_COLS Then : this.pNode->tag(this.uTag)=s_Tag : Return 1 : Else : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(uTag)=s_Tag : Return 1 : End If : End Property
Property List.RwTag1(s_Tag As String) As Byte : this.pNode->tag(1)=s_Tag : Return 1 : End Property
Property List.RwTag2(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(2)=s_Tag : Return 1 : End Property
Property List.RwTag3(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(3)=s_Tag : Return 1 : End Property
Property List.RwTag4(s_Tag As String) As Byte : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(4)=s_Tag : Return 1 : End Property

Property List.ColTags As Byte : Return(this.uTag) : End Property
Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property

Property List.AllOf As uInteger
    Dim pContextRetour As ListContext
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Return 0 : End If :
    Dim  As ListNode Ptr pTemp, pTemp2 : If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If
    If pFirstNode=pFIRSTFIRSTNode Then : If pLastNode<>pWhyteMove Then : this.Root : End If : End If
    this.NodeRecycle : this.NodeRecycle2
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.AllOfPrivate
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : uCount=pContextRetour.uCount
    pNode=AllowCake : pLocalMove=pNode
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode->pNext=pGarbage->pNext : Else : pNode->pNext=pFirstNode->pNext : End If
    If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    Return this.Count
End Property

Property List.Count As uInteger
    Dim pTemp As ListNode Ptr
    If pWhyteMove=0 And pFirstNode=pFIRSTFIRSTNode Then : pTemp=this.pNode : this.uCount-=2 : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : Return this.uCount
End Property

Property List.First As Byte : If pFirstNode=pFirstFIRSTNode Then : pNode=pGarbage : Else : this.pNode=This.pFirstNode->pNext : End If : Return 1 : End Property
Property List.Last As Byte : this.pNode=This.pLastNode : Return 1 : End Property

Property List.Val(str_value As String) As Byte : this.pValTmp=this.pNode : this.ValPrivate(str_value) : Return 1 : End Property
Property List.Val As String : pValTmp=pNode : Return this.ValPrivate : End Property
Property List.ValTag(str_value As String) As String
    If bSearchRes=1 Then : If str_value=this.Tag(0) Then : pValTmp=pSearchNode : Return this.ValPrivate : End If
    ElseIf this.HasTag(str_value)=1 Then : pValTmp=pSearchNode : Return this.ValPrivate
    End If : Return("")
End Property

Property List.fStep As Byte : If pNode=pLastNode Or bfStepZero=1 Or pNode->pNext=pWhyteMove Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pNext : Return 1 : End If : End Property '
Property List.fStepRev As Byte : If pNode->pPrev=pFirstNode Or pNode->pPrev=pGarbage Or bfStepZero=1 Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pPrev : Return 1 : End If : End Property
Property List.bStep As Byte : this.pNode = this.pNode->pNext : Return 1 : End Property
Property List.BlindStep As Byte : If this.pNode->pNext<>0 Then : this.pNode = this.pNode->pNext : Return 1 : Else   : Return 0 : End If : End Property ' : Print "*Warning : list parse or count down error"
Property List.BlindStep(top As Integer) As Byte
    Dim As Integer i : Dim As Byte istep
    If top>0 Then : istep=1 : For i=1 To top step istep : this.pNode = this.pNode->pNext : Next i : ElseIf top = 0 Then : this.pNode = this.pLastNode : Return 1 : Else : istep=-1 : For i=-1 To top step istep : this.pNode = this.pNode->pPrev : Next i : End If
    Return 1
End Property
Property List.fMove(nbMove As Integer) As Byte
    Dim As ListNode Ptr pFirst, pTemp : Dim i As Integer=0
    If pNode->Tag(0)=LIST_DEL Or pNode->Tag(0)=LIST_RES Or pNode=pWhyteMove Or pNode=pEndFlat  Or pNode=pLocalMove Or pNode=pLocalRoot Then : Return 0 : End If
    If pFirstNode=pFirstFIRSTnode Then : pFirst=pGarbage : Else : pFirst=pFirstNode : End If
    If pNode=pLastNode Then : pLastNode=pNode->pPrev : Else : pNode->pNext->pPrev=pNode->pPrev : End If
    pNode->pPrev->pNext=pNode->pNext : pTemp=pNode
    If nbMove>0 Then : For i=0 To nbMove-1 : If pNode<>pLastNode Then : pTemp=pTemp->pNext : End If : Next i
    Else : For i=nbMove To 0 : If pTemp<>pFirstNode Then : pTemp=pTemp->pPrev : End If : Next i
    End If
    If pTemp<>pLastNode Then : pTemp->pNext->pPrev=pNode : pNode->pNext=pTemp->pNext
    Else : If  pTemp->pNext<>0 Then : pNode->pNext=pTemp->pNext : End If : pLastNode=pNode
    End If
    pTemp->pNext=pNode : pNode->pPrev=pTemp
    Return 1
End Property

Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.993 -

Post by Lost Zergling »

Archive Beta 0.993 Part 2

Code: Select all


'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uSortTag=i : Return 1 : End If : End Property
Property List.fSortMethod(bsortM As Byte) As Byte : If bsortM=-1 Then : this.bSortMT=-1 : Else : this.bSortMT=1 : End If : Return 1 : End Property
Property List.BTreeSortTH(uSortT As uInteger) As Byte : If uSortT>10 Then : uSortThreshold=uSortT : End If : Return 1 : End Property
Property List.fSort As Byte
    Dim As ListNode Ptr pTemp1=pFirstNode, pTemp2, pTemp3, pTemp4, pTemp5=pLastNode->pNext : Dim as byte  by=1
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If   
    'Trie+Insert Sort - non recursive   
    gCollector.SetRelation(1) : gCollector.HashKeyUnique(1) : gCollector.HashSort(1) : gCollector.fSortMethod(1) : gCollector.HashLen(1) : gCollector.GarbageSnatch(this)
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp3=pTemp1 : pNode=pTemp1->pNext : If pNode=pFirstNode Then : pTemp4=pFirstNode->pNext : Else : pTemp4=pNode : End If
    While pNode<>pLastNode and by=1 : gCollector.HashTag( this.Tag) : gCollector.SetRelation1(this.pNode) : by=this.fStep : Wend ' gCollector.HashTag( this.pNode->Tag(uTag) ) <> gCollector.HashTag( this.Tag ) wheras pNode->Tag(uTag) = this.Tag ?
    If pFirstNode<>pFirstFIRSTnode Then : gCollector.HashTag( this.Tag ) : gCollector.SetRelation1(this.pNode)  : End If
    gCollector.Root
    If this.bSortMT=1 Then : While gCollector.KeyStep : If this.Follow(gCollector) Then : pTemp3->pNext=this.pNode : pNode->pPrev=pTemp3 : pTemp3=pNode : End If : Wend         
    Else : While gCollector.KeyStepRev : If this.Follow(gCollector) Then : pTemp3->pNext=this.pNode : pNode->pPrev=pTemp3 : pTemp3=pNode : End If : Wend
    End If
    pFirstNode->pBranchLastNode=pTemp3 : this.pLastNode=pTemp3 : pNode=pTemp4
    If pFirstNode=pFirstFIRSTnode Then : pWhyteMove->pPrev=pLastNode : End If
    gCollector.Recycle : this.AllOf : this.GarbageSnatch(gCollector)
    Return 1
End Property

Property List.Sort as Byte : this.Sort(this.bSortMT) : Return 1 : End Property
Property List.Sort(bSortMth As Byte) as Byte
    Dim As ListNode Ptr s_pNode=pNode, s_pFirstNode=pFirstNode
    Dim As uInteger s_uCount=uCount
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If   
    this.Root : this.fSort : this.pNode=pGarbage
    While this.HashStepTrace : If bHStepTrace=-1 Then : this.fSort : pNode=this.pFirstNode->pNext : End If : Wend
    pNode=s_pNode : pFirstNode=s_pFirstNode : pLastNode=pFirstNode->pBranchLastNode : uCount=s_uCount
    Return 1
End Property
Property List.HashSort(ub as Byte) As Byte : If ub=1 And this.bSortMT=-1 Then : this.bSortMT=1 : End If : If ub=0 Or ub=1 Then : bHTmethod=ub : uSortTag=uTag : Return 1 : Else : Return 0 : End If : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - HASH CONTROL
Property List.Root As Byte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext   
    If bTracking=1 Or pFirstNode->Tag(0)<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If :' this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode   
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Beep : Return 0 : End If
    this.RootPrivate : If pLocalMove<>0 Then : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL : End If
    this.NodeRecycle : this.NodeRecycle2 : bSearchRes=0 : pTemp2=0 : this.bHashStepRev=0 : pLatestHTag=0   
    'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc qui ne soit jamais 'flaté'
    If this.pWhyteMove<>0 Then
        pWhyteMove->Tag(0)=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag(0)<>LIST_RES Then           
            If pWhyteMove->pPrev<>0 Then : this.pWhyteMove->pPrev->pNext=this.pWhyteMove->pNext : End If
            If pWhyteMove->pNext<>0 Then :this.pWhyteMove->pNext->pPrev=this.pWhyteMove->pPrev : End If         
        End If       
    End If ' If pPanCakeGarbage=0 Then : pPanCakeGarbage=AllowPanCake : pPanCakeGarbage->pNextContainer=pPanCakeGarbage : End If
    If pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : this.Val(LIST_DEL) : pGarbage->pPrev=pFlatRoot
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If : this.pNode = pGarbage
    End If
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    this.FlatStack(0)
    'Corrections  - Patch de compatibilité - : pFlatRoot se balade, il faut le remettre au début -
    If pFlatRoot->pPrev<>0 Then : pFlatRoot->pPrev->pNext=pFlatRoot->pNext : End If : If pFlatRoot->pNext<>0 Then :  pFlatRoot->pNext->pPrev=pFlatRoot->pPrev : End If
    pFlatRoot->pPrev=this.pFirstFIRSTNode : pFlatRoot->pNext=this.pFirstFIRSTNode->pNext : If this.pFirstFIRSTNode->pNext<>0 Then : this.pFirstFIRSTNode->pNext->pPrev=pFlatRoot : End If : this.pFirstFIRSTNode->pNext=pFlatRoot
    'Changement de fonctionnement - Patch de compatibilité - pLastLAST devient dernier node LOGIQUE : on le remet à jour
    If this.pFirstFIRSTNode->pBranchLastNode<>0 Then
        pTemp=this.pFirstFIRSTNode->pBranchLastNode : While pTemp->pBranchLastNode<>0 And pTemp<>pTemp2 : pTemp2=pTemp : pTemp=pTemp->pBranchLastNode : Wend : this.pLastLASTNode=pTemp       
    End If
    'NodeFlat+Restorehash nécessite la présence d'un dernier node fictif
    If this.pLastNode->Tag(0)<>"" Then : If pWhyteMove<>0 Then : this.AllOf  : Else : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : End If
    this.pNode=pGarbage : this.uCount=this.pFirstFIRSTNode->BranchCount : this.pLastLASTNode->pPrev->pNext=this.pLastLASTNode
    If this.pLastLASTNode->pNext->Tag(0)=LIST_RES Then : this.pLastLASTNode->pNext=0 : End If
  ' Option for .Root become compatible with Rev parse with no need to jump to Last node (List.Last)
    this.pNode=AllowCake : pNode->Tag(0)="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL
    If pLastNode=pWhyteMove Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    this.NodeRecycle2 : this.pFirstNode->BranchCount=this.uCount : this.pFirstNode->pBranchLastNode=this.pLastNode
    uB_CurLevel=1 : uB_Level=1 : If bnStepByPass=0 Then :  uB_BottomLevel=255 : uB_MaxLevel=1 : uB_KeyStepCumul=1 : End If
    Return 1
End Property

Property List.FlatStack As Byte : this.FlatStack(1) : this.AllOf : bSearchRes=0 : Return 1 : End Property
Property List.RootNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pFirstFIRSTNode : Return 1 : End Property
Property List.EndNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pLastLASTNode : Return 1 : End Property

Property List.HashStep As Byte
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If ' If pNode=pWhyteMove Then : Return 0 : Else : Return 1 : End If
    Wend : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

Property List.HashStepRev As Byte
    this.bHashStepRev=1
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode=pLastNode->pPrev : Else : pnode=pLastNode : End If : Return 1
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode Then : this.pnode = this.pnode->pPrev : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    Wend : Return 0
End Property

Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property

'Numeric parse optimization
Property List.nCurLevel(uB_len as uByte) As Byte : If uB_len=uB_CurLevel Then : Return 1 : Else : Return 0 : End If : End Property

'Numeric sorted parse
Property List.nHashStep(uB_len as uByte) As Byte   
    While this.pnode->pBranch<>0 And uB_CurLevel<=uB_len
        uB_CurLevel +=1 : If uB_CurLevel>uB_MaxLevel Then : uB_MaxLevel=uB_CurLevel : End If
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend :     
    If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If   
    While pFirstNode->pBranch<>0
        uB_CurLevel -=1
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : uB_Level+=1 : Return 0 : Else : Return 1 : End If : End If
    Wend :
    this.RootPrivate : Return 0
End Property
Property List.nKeyStep(uB_len as uByte) As Byte : While this.nHashStep(uB_len)=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : Return 0 : End Property
Property List.nKeyStep as Byte
    While uB_KeyStepCumul<=uB_MaxLevel
        While this.nKeyStep(uB_Level) : If this.nCurLevel(uB_Level)=1 Then : Return 1 : End If : Wend
        bnStepByPass=1 : this.Root : bnStepByPass=0 : uB_Level+=uB_KeyStepCumul : uB_KeyStepCumul+=1
    Wend : uB_CurLevel=1 : uB_Level=1 : uB_MaxLevel=1 : uB_KeyStepCumul=1 : Return 0
End Property

'Numeric sorted Reverse parse
Property List.nHashStepRev(uB_len as uByte) As Byte   
    this.bHashStepRev=1
    While this.pnode->pBranch<>0 And uB_CurLevel<=uB_len
        uB_CurLevel +=1 : If uB_CurLevel>uB_MaxLevel Then : uB_MaxLevel=uB_CurLevel : uB_BottomLevel = uB_MaxLevel+1 : End If
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode=pLastNode->pPrev : Else : pnode=pLastNode : End If : Return 1
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    While pFirstNode->pBranch<>0
        uB_CurLevel -=1
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If
    Wend : Return 0
End Property
Property List.nKeyStepRev(uB_len as uByte) As Byte : While this.nHashStepRev(uB_len)=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : Return 0 : End Property
Property List.nKeyStepRev as Byte
   Dim t as Integer
   For t=uB_BottomLevel to 1 Step-1
        While this.nKeyStepRev(uB_BottomLevel) : If this.nCurLevel(uB_BottomLevel)=1 Then : Return 1 : End If : Wend : bnStepByPass=1 : this.Root : bnStepByPass=0 : uB_BottomLevel-=uB_KeyStepCumul
    Next t : uB_CurLevel=1 : uB_BottomLevel=255 : uB_KeyStepCumul=1 : Return 0
End Property

Property List.HashTag(str_Tag As String) As Byte
   Dim As ListNode Ptr pTemp,  pTemp02, pTemp03 , pTemp04
    Dim As uInteger i=0, iLen=Len(str_tag), iLenStrTmp, iLenpNode, iLenCumul, iLenDiff, iLenDelta=0, PvsiStep
    Dim As uByte HadHashTag=1, istep=this.bHashLen, IsLast=0, IsPt2Swp=0, IsPtSwp=0, bSeekMethod_TMP=bSeekMethod, bAutoCursor_TMP=bAutoCursor
    Dim As zString Ptr zp1, zp2, Listptemp2_b, Listptemp_b : Dim As String str_testTMP
    If iLen>MAX_KEYLEN Then : Listptemp2_b=_CAllocate(iLen+1) : Swap Listptemp2,Listptemp2_b : IsPt2Swp=1 : End If
    str_testTMP=str_Tag : If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute : End If

    If pFirstNode<>pFirstFIRSTNode Then 'Déclenchement optimisation // Si pFirstNode=pFirstFIRSTNode il est possible que la liste soit vide ou que le node en cours soit en cours d'envoi au garbage collector
        If pLatestHTag=pNode Then : Str_tmp=sLatestHTag '  Algo optimisation 1 : basé sur la récupération la + rapide possible de la position dans l'arbre // And bPVSmethod=0 //  l'algo d'optimisation le plus simple est souvent le + efficace et reste prioritaire sur PVS
        Else : pNode=pFirstNode->pNext : If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
        End If
        iLenStrTmp=Len(Str_tmp)         
        If iLenStrTmp>MAX_KEYLEN Then : Listptemp_b=_CAllocate(iLenStrTmp+1) : Swap Listptemp,Listptemp_b : IsPtSwp=1 : End If
        If iLen>iLenStrTmp Then : iLenDiff=iLen-iLenStrTmp : End If
       
        *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
        *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=istep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
        If *Listptemp=*Listptemp2  And bPVSmethod<1 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs) // And bPVSmethod=0
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
       '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
            iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
            Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
            iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
            If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode             
           
        ElseIf bPVSmethod>-1 Then ' Algo optimisation 2 : basé sur l'enregistrement à un niveau PvsiStep càd (lngClef/n)+1 de la longueur de la clef, d'un pointeur "prédictif" vers une branche plus basse de l'arbre
            PvsiStep=iLen/PVS_ratio+1
            *Listptemp=Str_tmp : zp1=Listptemp : zp1+=PvsiStep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=PvsiStep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)       
            If  *Listptemp<>*Listptemp2 Then' *Alternative to If Left(Str_tmp,istep)<>Left(str_tag,istep) Then   *Listptemp<>*Listptemp2     
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage
                this.HashTag(*Listptemp2 ) 'youpi
                If pNode->BranchCount<>0 Then : pFirstNode=Cast(ListNode Ptr, pNode->BranchCount) : pLastNode=pFirstNode->pBranchLastNode : End If :  pTemp04=pNode : PVS_Count+=1               
                pNode=pFirstNode->pNext : pNode=pFirstNode->pNext
                If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
                *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            End If
            If *Listptemp=*Listptemp2 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs)
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
                pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
           '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
                iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                    Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                    iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
                Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
                iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
                If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode   
            Else               
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1               
            End If 
           
        Else
            pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
            this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1
        End If
    Else
        pTemp02=pGarbage : bSeekMethod_TMP=1
    End If ' Fin algo optimisation   
   
    iLenCumul=0 : *Listptemp2=str_Tag : zp1=Listptemp2 ' * Alternative to Mid
    For i=1 to Len(str_Tag) step istep
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid :  Str_tmp=Mid(str_Tag,i, istep)
        iLenCumul+=iStep
        If bHTmethod=0 Then
            If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
            Else : pTemp = pTemp02 : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
            End If
        Else
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                While ( pTemp->Tag(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else
                pTemp=pTemp02 : While (pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend               
                If pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
            End If
        End If       
        If pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp  'bHashKeyUnique
        ElseIf pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=0 And iLenCumul<iLen Then : this.pNode = pTemp
        ElseIf bHTmethod=1 And IsLast=0 Then
            pTemp03=AllowCake : this.uCount+=1
            pTemp03->pNext=pTemp : pTemp03->pPrev=pTemp->pPrev : pTemp->pPrev->pNext=pTemp03 : pTemp->pPrev=pTemp03         
            If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pTemp03->Tag(uTag) = Str_tmp : HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03           
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If           
        Else ' If pTemp=pTemp02 Then : this.BlindTag(Str_tmp)                           
            pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode : pTemp03->pNext->Tag(uTag) = Str_tmp
            this.pLastNode = pTemp03->pNext : this.pNode = pTemp03->pNext : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pLastNode->pPrev = pTemp03 : HadHashTag=0 : pFirstNode->BranchCount+=1
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system
        End If
        If iLenCumul<iLen Then  '  If u*istep<iLen Then   ' this.Branch
            pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : pTemp=pNode
            If this.pNode->pBranch=0 Then ' New 'Hash' : this.BlindTag(LIST_RES) :
                pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
                pTemp03->pNext->pPrev = pTemp03 : pTemp03->pNext->Tag(uTag) = LIST_RES
                pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : pNode=pTemp03
                this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp : pTemp->pBranch=this.pNode
                this.uCount=0 :' pTemp->pBranchLastNode=this.pNode     pTemp->BranchCount=0 :
                this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(str_testTMP, iLenCumul+iLenDelta) : End If      '
            Else 'Branche déjà créée
                this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
                this.pLastNode = this.pNode->pBranch->pBranchLastNode : this.pNode = this.pNode->pBranch
            End If
        End If : pTemp02=pFirstNode
    Next i
    this.pLatestHTag=this.pNode : this.sLatestHTag=str_testTMP :
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag(1)="" And bRHByPass=0 Then : this.pNode->Tag(1)=" " : End If
    If pTemp04<>0 Then : pTemp04->BranchCount=CuInt(pFirstNode)  : End If
    If IsPt2Swp=1 Then : Swap Listptemp2,Listptemp2_b : _Deallocate(Listptemp2_b) : End If : If IsPtSwp=1 Then : Swap Listptemp,Listptemp_b : _Deallocate(Listptemp_b) : End If     
  ' If pNode=pFirstNode Then : Print "Error  : pNode=pFirstNode  !! " : beep : sleep : End IF
 '  If this.HashTag<>str_testTMP Then : Print "Erreur sur " & this.HashTag & " <> " & str_testTMP : beep : sleep : End If ' Debug & tests
    Return HadHashTag
End Property

Property List.HashTag As String
    Dim As ListNode Ptr pTemp01= this.pFirstNode, pTemp02=this.pNode
    If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute :  pTemp01 = this.pFirstNode : pTemp02 = this.pNode : End If     
    Str_tmp = this.Tag(uTag) ' this.pnode->Tag(uTag)
    If pTemp01->pPrev<>0  AndAlso pFirstNode->Tag(1)<>"" AndAlso ubKeysRegister=1 Then : KR_Count+=1 : Return pFirstNode->Tag(1) & pTemp02->Tag(0) : End If
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag(0)  + Str_tmp                 
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasHashTag(str_Tag As String) As Byte
    Dim As zString Ptr  zp1, zp2
    Dim pContextRetour As ListContext
    Dim HadHashTag As Byte=0 : Dim IsEtoile As Byte=0 : Dim i as uByte=1 : Dim t as uByte=Len(str_Tag) : Dim istep As uByte=this.bHashLen
   
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode 'this.RootPrivate
    this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode
    zp1=Listptemp+Len(str_Tag)+1 : (*zp1)[0]=0 :
    *Listptemp=str_Tag : zp1=Listptemp' * Alternative to Mid
    Do
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid : Str_tmp=Mid(str_Tag,i, istep)
        If this.HasTag(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            If this.pNode->Tag(1)="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf this.pNode->Tag(1)="!*" Then : HadHashTag=0 : i=t
            ElseIf this.pNode->Tag(1)="!" And i=t Then : HadHashTag=0
            ElseIf i>=t Then : HadHashTag=1
            Else :  HadHashTag=0 : End If   
        ElseIf IsEtoile=0 Then : HadHashTag=0 : i=t
        End If
        If i<t Then
            If this.pNode->pBranch=0 Then
                If bAutoCursor<3 Then : pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount : End If
                Return -1
            Else : this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode : this.pNode = this.pFirstNode
            End If : this.bSearchRes = 0
        End If
        i+=istep
    Loop Until i>t
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag(1)="" Then : HadHashTag=0 : Else : Return 1 : End If
        End If
    End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
   Return HadHashTag
End Property

Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : Else : Return 0 : End If : Else : Return -1 : End If : End Property
Property List.BranchCount As uInteger : If this.pNode->pBranch<>0 Then : Return pNode->BranchCount : Else : Return 0 : End If : End Property ' Return this.pNode->BranchCount

Property List.NodeFlat As Byte 'Réallocation sélective dynamique multimodes rétro-récursive (virtuelle/reelle glissante 0/-n) de la structure de l'index en memoire virtuelle (Reduce) - Compatible HashStep, HashStepRev(?), KeyStep, KeyStepRev(?), fStep, TrackStep
    Dim As ListContext pContext, pContextRetour : Dim  As ListNode Ptr pTemp1, pTemp2, pTemp3, pTemp4, pTemp5, pTemp6, pTemp7 : Dim As uByte IsLastNode=0
    this.NodeRecycle : NodeRecycle2
    'Contrôle multimode en entrée + contrôle du Token de fin de liste + gestion continuité des ptr
    If pNode->Tag(0)=LIST_RES OrElse pNode->Tag(0)=LIST_DEL OrElse pNode=pWhyteMove OrElse pNode=pGarbage Then : Return 0
    ElseIf bTracking=1 Then
        If pFirstNode->pBranch=pFlatRoot Then : Return 0 : End If
        If bTrackingMethod=0 Then : this.TrackCompute : pLastNode->pNext=0 : End If : pTemp6=pNode->pBranchLastNode
    End If : pTemp5=pFirstNode : pTemp2 = this.pNode : If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag(uTag) : End If : pLatestHTag=0
    'Gestion (swapping) des nodes parents                                                   ---------------------------------------------------------------------------
    If this.pNode->pBranch<>0  Then
        'Validation du mouvement mémoire : ' Fonctionnalité Tree List =>FlatList / ByPass Garbage ou 'Déjà swappé 
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag(1)=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag(0)=LIST_DEL Then : Return 0 : End If  ' PATCHED !!
        pTemp1=AllowCake : pTemp4=this.pFlatRoot->pBranch : If this.pNode->pPrev<>0 Then : this.pNode->pPrev->pNext=pTemp1 : End If
        If this.pNode->pNext->pPrev=this.pNode Then this.pNode->pNext->pPrev=pTemp1 : End If       
        pTemp1->pPrev=this.pNode->pPrev : pTemp1->pNext=this.pNode->pNext : pTemp1->pBranch=this.pNode->pBranch
        pTemp1->BranchCount=this.pNode->BranchCount : pTemp1->Tag(0)=this.pNode->Tag(0) : pTemp1->Tag(1)=LIST_DEL
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0 : this.pNode->Tag(0) = Str_tmp
        this.pNode->pPrev=pTemp4 : pTemp4->pNext->pPrev=this.pNode : this.pNode->pNext=pTemp4->pNext : pTemp4->pNext=this.pNode : this.pNode=pTemp1
    Else : this.uCount-=1 : pFirstNode->BranchCount-=1 :  If bBranchCountDown=1 Then : this.BCountDown(-1) : End If
    End If   
    'Gestion (/optimisation) du parsing (rétro-récursivité) ds le HashStep       ---------------------------------------------------------------------------       
    If pNode->pPrev<>pFirstNode Then
        If this.pNode->pNext->Tag(0)=LIST_DEL Then : This.pLastNode=this.pNode->pPrev : This.pFirstNode->pBranchLastNode=this.pNode->pPrev : End If
        If bHashStepRev=1 Then : pContextRetour.pNode=pNode->pNext : Else : pContextRetour.pNode=pNode->pPrev : End If
        pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount   
    Else
        pContext.pNode=This.pNode : pContext.pFirstNode=This.pFirstNode : pContext.pLastNode=This.pLastNode : pContext.uCount=This.uCount       
        If pNode=pLastNode Then : pTemp3=this.pFirstNode->pBranch->pPrev : Else : pTemp3=this.pFirstNode->pBranch : End If
        If pTemp3->Tag(0)=LIST_RES Then
            If pNode=pLastNode Then : this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : End If
            pTemp3=this.pFirstNode->pBranch
        End If
        this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount ' This.UpLevel         
        pContextRetour.pNode = pTemp3 : pContextRetour.pFirstNode = This.pFirstNode : pContextRetour.pLastNode = This.pLastNode : pContextRetour.uCount=This.uCount
        This.pNode=pContext.pNode : This.pFirstNode=pContext.pFirstNode : This.pLastNode=pContext.pLastNode : this.uCount=pContext.uCount                 
    End If
    If this.pNode->pNext=0 And this.pNode->pPrev->Tag(0)=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag(1)="" :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag(0)=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag(1)="" :  pLocalRoot->Tag(0)=LIST_DEL
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
   ' pFirstNode->Tag(1)=""
  ' Swapping / MAJ des pointeurs - depend de IsLastNode                        --------------------------------------------------------------------------     
  ' Envoi d'un ancien node parent déjà swappé vers le garbage collector OU envoi d'un node non parent vers le GarbageCollector (si NFmethod=-1)
    If (pTemp2->Tag(1)=LIST_DEL Or this.bNFmethod=-1) And pTemp2->pBranch=0   Then ' And bNFmethod<>3
        If IsLastNode=0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext : End If
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag(0)=LIST_DEL : pTemp2->Tag(1)="" : uGarbCt+=1 : pTemp2->pBranchLastNode=0
        If pTemp2->ListData<>0 Then : pTemp2->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp2->ListData : pTemp2->ListData=0 : uContainerGarbCt+=1 : End If
        This.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
        If IsLastNode=0 And  bHashStepRev=1 Then : If this.Up=0 Then : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext  : End If : End If
        ElseIf IsLastNode=1 Then       
            this.pNode=pTemp5->pBranch : this.uCount=pTemp5->pPrev->BranchCount : pLastNode=pTemp5->pPrev->pBranchLastNode : this.pFirstNode = pTemp5->pPrev           
            If bTracking=1 Or bPickReduce=1 Then : If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If : '  this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    Else ' Envoi vers la Flat list - Optimisation, à voir                                      --------------------------------------------------------------------------                 
        pFlatRoot->pBranch->BranchCount+=1         
        pNode=pFirstNode->pNext : this.UpLevel
        this.pFirstNode = this.pFirstFIRSTNode : this.pLastNode = this.pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
        this.pNode=this.pFlatRoot : this.Branch ' this.FlatStack
        If pFlatRoot->pBranch->BranchCount=0 Then : pFlatRoot->pBranch->BranchCount=1 : this.uCount=1 :  End If
        pTemp1 = this.pLastNode
        If IsLastNode=0 Then
            If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If
            If pTemp2->pPrev<>0 And pTemp2->Tag(0)<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            pTemp2->pPrev= this.pLastNode : pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->Tag(uTag) = Str_tmp : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            this.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount     
            If bHashStepRev=1 Then : If this.Up=0 Then : this.BlindStep : End If : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If : Return 1 :  End If             
        Else
            pTemp1->pNext=pTemp2  : pTemp2->pNext=0 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2  : pTemp2->Tag(uTag)=Str_tmp : pTemp2->pPrev=pTemp1  '
            this.pNode=pTemp5->pBranch : this.pFirstNode = pTemp5->pPrev : pLastNode=pTemp5->pPrev->pBranchLastNode : this.uCount=pTemp5->pPrev->BranchCount 
            If bTracking=1 Or bPickReduce=1 Then :  If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL  Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If  : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If ' this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL : Return 1 : End If
    Return 1
End Property

Property List.RestoreHash As Byte
    Dim As ListNode Ptr pTemp,  pTmpPrev, pTmpNext, pMove
    Dim str_tmp as string=this.Tag : Dim bTagExists As Byte : Dim uTagTmp As Byte=uTag
    pTemp=this.pnode : str_tmp=this.Tag(uTag) : If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : Return 0 : End If
    'HashTagging
    uTag=0 : bRHByPass=1 : bTagExists=this.HashTag(str_tmp) : bRHByPass=0 :
    'Gestion des modes (RHmethod)
    If bTagExists=1 And pNode->Tag(1)<>""  Then ' tag deja existant et "vraie" clef
        If bRHmethod=-1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
        ElseIf bRHmethod=1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
        Else : If pNode->Tag(1)=LIST_DEL Then : pNode->Tag(1)=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
        End If       
    Else : pTemp->Tag(0)= this.pnode->Tag(uTag) : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext
  '  If bNFmethod<>3 Then : pTemp->pBranch=this.pnode->pBranch : End If
    this.pnode->pPrev->pNext=pTemp
    If this.pnode->pNext<>0 Then : If this.pnode->pNext->pPrev=this.pnode Then : this.pnode->pNext->pPrev=pTemp : End If : End If
    If this.pnode=this.pLastNode Then : this.pLastNode=pTemp : End If : If this.pnode=this.pFirstNode Then : this.pFirstNode=pTemp : End If     
    If this.pnode->pBranch<>0 Then  '  pFirstNode->Tag(1)=""  '  pnode->pBranch->Tag(1)=""
        If this.pnode=this.pFirstNode->pBranchLastNode Then : this.pFirstNode->pBranchLastNode=pTemp : End If
        If this.pnode->pBranch->pBranch=this.pnode Then : this.pnode->pBranch->pBranch=pTemp : End If       
        pTemp->pBranch=this.pnode->pBranch : pTemp->pBranchLastNode=this.pnode->pBranchLastNode : pTemp->BranchCount=this.pnode->BranchCount
    End If
    'Reprise ds Flat List
    this.FlatStack(1)
    If bTagExists<>2 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext
    End If
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - PROPERTIES PARAMETERS
Property List.AutoCursor(b As Byte) As Byte : If 0<=b<=3 Then : bAutoCursor=b : Return 1 : End If : Return 0 : End Property
Property List.BranchCountDown(i as Byte) As Byte
    If i<>0 And i<>1 Then : Print "BranchCountDown : invalid parameter" : Return 0 : ElseIf i=0 Or (i=1 And bColBcountLocked=0) Then : bBranchCountDown=i : bColBcountLocked=i : Return 1 : Else : Print "Branch count vector already booked" : Return 0 : End If
End Property
Property List.CopyCatMethod(i As Byte) As Byte : If i=0 Or i=1 Then : bCopyCatMethod=i : Return 1 : Else : Print "CopyCatMethod : invalid parameter" : Return 0 : End If : End Property
Property List.HashKeyUnique(ub as Byte) As Byte : If ub=0 Or ub=1 Then : bHashKeyUnique=ub : Return 1 : Else : Print "HashKeyUnique : invalid parameter" :  Return 0 : End If : End Property
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>0 And bHashLen<255 Then : this.bHashLen = bHashLen : Return 1 : Else : Print "HashLen : invalid parameter" :  Return 0 : End If : End Property
Property List.KeysRegister(ub As uByte) As Byte :  If ub=0 Or ub=1 Then : ubKeysRegister=ub : Return 1 : Else : Print "KeysRegister : invalid parameter" :  Return 0 : End If : End Property
Property List.NFmethod(i As Byte) As Byte : If i=-1 Or i=0 Or i=1 Then : this.bNFmethod=i : Return 1 : Else : Print "NFmethod : invalid parameter" : Return 0 : End If : End Property
Property List.NFrecursive(i As Byte) As Byte : If i=1 Then : this.bPickReduce=1 : Else : this.bPickReduce=0 : End If : Return 1 : End Property
Property List.PVSmethod(ub As Byte) As Byte :
    If ub=-1 Then : bPVSmethod=ub : Return 1
    ElseIf bColBcountLocked=0 and ub<2 Then : bPVSmethod=ub : bColBcountLocked=1 : Return 1
    Else : Print "PVSmethod : Branch count vector already booked or invalid parameter" : Beep : sleep : Return 0 : End If
End Property
Property List.PVSratio(ub As uByte) As Byte : If ub>1 Then : PVS_ratio=ub : Return 1 : Else : Return 0 : End If : End Property
Property List.RHmethod(i As Byte) As Byte : If -2<i<2 Then : this.bRHmethod=i : Return 1 : Else : this.bRHmethod=-1 : Return 0 : End If : End Property
Property List.SeekMethod(i as Byte) As Byte : If i=0 Or i=1 Or i=2 Then : this.bSeekMethod=i : Return 1 : Else : Return 0 : End If : End Property
Property List.SnatchBLmethod(i As Byte) As Byte : If i=0 Or i=1 Then : bSnatchBLMethod=i : Return 1 : Else : Print "SnatchBeMethod : invalid parameter" : Return 0 : End If : End Property
Property List.TrackMethod(by As Byte) As Byte : If by=0 Or by=1 Then : bTrackingMethod=by : Return 1 : Else : Return 0 : End If: End Property
Property List.TrackMultiKeys(uB as uByte) As Byte : If -1<=uB<=MAX_COLS Then : bTrackMultiKeys=uB : Return 1 : End If : Return 0 : End Property
Property List.VectorUnlock As Byte : bColBcountLocked=0 : bColTrackLocked=0 : Return 1 : End Property
Property List.VectorClear As Byte
    Dim As ListNode Ptr Ptemp1=pNode, pTemp2 : Dim As Byte IsUp=0
    pTemp2=pTemp1->pNext
    If pTemp2=0 Or pNode->Tag(0)=LIST_RES  Or pNode->Tag(0)=LIST_DEL Then : Return 0 : End If
    If bColBcountLocked=1 Or bPVSmethod=1 Then : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : Wend
    End If : pNode=pTemp1 : Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLOW CONTROL
Property List.Up As Byte : If pFirstNode=pFirstFIRSTnode Then : Return 0 : Else :  this.UpLevel : Return 1: End If : End Property
Property List.Down As Byte
    If pnode->pBranch=0 Or pNode->Tag(0)=LIST_RES Then  : Return 0 : End If
    If pnode->pBranch->pPrev<>pFirstNode Then : Return 0 :
    Else : pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pNode->pBranch : uCount=pFirstNode->BranchCount : pLastNode=pNode->pBranch->pBranchLastNode : pNode=pNode->pBranch : Return 1
    End If
End Property
Property List.HoldBack As Byte : Return this.HoldBack(0) : End Property
Property List.HoldBack(by As Byte) As Byte   
    If pNode->Tag(0)=LIST_RES Or bColTrackLocked=1 Then : Return 0
    ElseIf TrackTrace(by)<>0 Then : TrackTrace(by)->pBranchLastNode=pNode : TrackTrace(by)=this.pNode : Return 1
    Else : this.TrackSet(by) : pNode->pBranchLastNode=0 : TrackTrace(by)=pNode : Return 1
    End If
End Property
Property List.TrackStep As Byte
    Dim As ListNode Ptr pTemp1 : bAlrdyTracked=0
    If pNode->pBranchLastNode->Tag(0)=LIST_DEL Or bColTrackLocked=1 Then : this.Root : bTracking=0 : Return 0 : End If ' Or pNode->pBranchLastNode->Tag(0)=LIST_RES
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag(0)<>LIST_RES Then           
        pNode=pNode->pBranchLastNode : bTracking=1
        If bTrackingMethod=1 Then : this.TrackCompute ': pLastNode->pNext=0
        End If : Return 1
    End If : this.TrackCompute : bTracking=0 : Return 0
End Property
Property List.Track As Byte : Return this.Track(0) : End Property
Property List.Track(by As Byte) As Byte
    this.Root : If bColTrackLocked=1 Then : Print "Tracking vector already in use (internal) by CopyCat/Follow" & chr(10) & "Use HashStep or other iterator" & chr(10) & "Attempt to use incompatible vectors may lead to crash" : Return 0 : End If : bAlrdyTracked=0
    If pNode->Tag(0)<>LIST_DEL And pNode->Tag(0)<>LIST_RES And pNode<>pLocalMove Then : This.TrackCompute : End If : bTracking=1 : this.Root ': This.TrackMethod(1)
    If this.Tracks(by).pNode=0 Then : this.TrackSet(by)  : Return 0
    Else
        pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : this.NodeRecycle : pNode=AllowCake : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL
        If this.Tracks(by).pNode->Tag(0)=LIST_DEL Then : pNode->pBranchLastNode=this.Tracks(by).pNode->pBranchLastNode
        Else : pNode->pBranchLastNode=this.Tracks(by).pNode
        End If
        pFirstNode=this.Tracks(by).pFirstNode : pLastNode=pFirstNode->pBranchLastNode : bHashLen=this.Tracks(by).bLcHashLen
        pNode->pBranch=0 : pNode->pPrev=0 : pNode->Tag(0)=""
        Return 1
    End If
End Property
Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte
    this.NodeRecycle : If pNode->pBranchLastNode<>0 Then : this.Tracks(by).pNode=pNode->pBranchLastNode  : Else : this.Tracks(by).pNode=pNode : End If
    this.Tracks(by).pFirstNode=pFirstNode : this.Tracks(by).bLcHashLen=bHashLen : TrackTrace(by)=0 : Return 1
End Property
Property List.TrackClear As Byte : Return this.TrackClear(0) : End Property
Property List.TrackClear(by As Byte) As Byte : TrackTrace(by)=0 : Return 1  : End Property
Property List.IsTracked As Byte : Dim i As Byte : If pNode->pBranchLastNode<>0 And pNode->Tag(0)<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS-1 : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : End Property

Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    Lcontext(by).pNode=pNode : Lcontext(by).pFirstNode=pFirstNode : Lcontext(by).pLastNode=pLastNode : Lcontext(by).uCount=this.uCount : Lcontext(by).LcHashTag=pNode->Tag(0) : Lcontext(by).bLcHashLen=this.bHashLen
    Return 1
End Property
Property List.Recover As Byte : Return this.Recover(1) : End Property
Property List.Recover(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pNode=Lcontext(by).pNode : pFirstNode=Lcontext(by).pFirstNode : this.bHashLen=Lcontext(by).bLcHashLen
    pLastNode=pFirstNode->pBranchLastNode : this.uCount= this.pFirstNode->BranchCount : this.bHashLen=Lcontext(by).bLcHashLen
    Return 1
End Property
Property List.Follow(pList As List) As Byte
    Dim As ListNode Ptr pTemp1=pList.Relation : bAlrdyTracked=0
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode : bTracking=1
    If pTemp1<>0 Then : this.pNode=pTemp1 : Else : Return 0 : End If
    this.pLastNode=pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
    Return 1
End Property

'==========================================================================================MEMORY MANAGEMENT
Property List.FlatCount As uInteger : Return this.pFlatRoot->pBranch->BranchCount : End Property
Property List.GarbageCount As uInteger : Return this.uGarbCt : End Property
Property List.ContainerCount As uInteger : Return this.uContainerGarbCt : End Property
Property List.NodeCount As uInteger : Return this.uNodeCOUNT : End Property

Property List.GarbageFlat As Byte
    Dim L_Context As ListContext : Dim As ListNode Ptr pTemp1, pTemp2, pTemp3 : Dim i as Byte
    If pFlatRoot->pBranch=0 Then : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then : pLocalMove=pFlatRoot->pBranch : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : this.NodeRecycle : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev
    If pTemp2=0 Then
        L_Context.pNode=pNode : L_Context.pFirstNode=pFirstNode : L_Context.pLastNode=pLastNode : L_Context.uCount=this.uCount
        this.FlatStack : pTemp2=pEndFlat->pPrev
        pNode=L_Context.pNode : pFirstNode=L_Context.pFirstNode : pLastNode=L_Context.pLastNode : this.uCount=L_Context.uCount
    End If :  If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext
    pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot
    Do
        pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If
        pNode=pTemp3
        pTemp1=pTemp1->pNext
    Loop Until pTemp1=pTemp2
    pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ': pTemp1->ListData.sData=""
    pTemp3=pNode : pNode=pTemp1 : this.Val("") : pNode=pTemp3
    uGarbCt+=pFlatRoot->pBranch->BranchCount
    pFlatRoot->pBranch->pNext=pFlatRoot->pBranchLastNode : pFlatRoot->pBranchLastNode->pPrev=pFlatRoot->pBranch : pFlatRoot->pBranch->BranchCount=0
    If pFirstNode=pFlatRoot->pBranch Then : uCount=0 : this.RootPrivate : End If
    Return 1
End Property

Property List.Recycle As uInteger : this.Up : this.Root : this.AllOf : Return this.AllRecycle : End Property  '

Property List.DropAll As uInteger  'pRoot principal + pFlatRoot + pFlatRoot->pBranch + pGarbage + pLastLAST/pWhyte = 5 nodes déalloues ds destructor     
    If this.IsDestroyed=1 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
    this.Root : this.GarbageFlat :  this.AllOf : this.AllRecycle : this.NodeRecycle : this.NodeRecycle2
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext  : Dim iLong As uInteger=0     
    While pTemp<>pGarbage And pTemp<>0 And pTemp<>pFlatRoot
        If pFlatRoot->pNext->ListData<>0 Then : _Deallocate(pFlatRoot->pNext->ListData) : End If
        _Deallocate(AllowCake) : pTemp=pFlatRoot->pNext : this.uNodeCOUNT-=1 : iLong+=1
    Wend
    Dim pPanTemp As ListContainer Ptr =pPanCakeGarbage->pNextContainer : Dim SeekMt As Byte=this.bSeekMethod
    While pPanTemp<>pPanCakeGarbage : _Deallocate(AllowPanCake) : pPanTemp=pPanCakeGarbage->pNextContainer : Wend  ' pPanCakeGarbage->pNextContainer=pPanCakeGarbage       
    this.bSeekMethod=SeekMt : uCount=0 : this.pFirstNode->BranchCount=0   
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then :  _Deallocate(pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1 : iLong+=1 : End If
    this.AllOfPrivate
    Return iLong   
End Property


Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.993 -

Post by Lost Zergling »

Archive Beta 0.993 Part 3

Code: Select all


Property List.Destroy As Byte
    If bPVSmethod<>-1 Then : Print "PVS_Count=" & PVS_Count  : End If '& " (the bigger, the most the optimization algo was used)" : End If
    If ubKeysRegister=1 Then : Print "KR_Count=" & KR_Count  : End If
    If this.IsDestroyed=1 Then : Return 0 : End If
    this.Root : this.DropAll : IsDestroyed=1
    If pPanCakeGarbage<>0 Then _Deallocate(pPanCakeGarbage) : pPanCakeGarbage=0 :  End If  :
    If this.pFlatRoot<>0 Then
        If this.pFlatRoot->ListData<>0 Then : _Deallocate this.pFlatRoot->ListData : this.pFlatRoot->ListData=0 :  End If
        If this.pFlatRoot->pBranch<>0 Then
            If this.pFlatRoot->pBranch->pNext<>0 And pFlatRoot->pBranch->pNext<>pEndFlat Then               
                _Deallocate(this.pFlatRoot->pBranch->pNext) : pFlatRoot->pBranch->pNext=0 :   this.uNodeCOUNT-=1
            End If
            _Deallocate(this.pFlatRoot->pBranch) : pFlatRoot->pBranch=0 :  this.uNodeCOUNT-=1
        End If
        _Deallocate(this.pFlatRoot) : pFlatRoot=0 :  this.uNodeCOUNT-=1
    End If
    If this.pEndFlat->ListData<>0 Then : _Deallocate this.pEndFlat->ListData : this.pEndFlat->ListData=0 :  End If
    If this.pLastLASTNode->ListData<>0 Then : _Deallocate this.pLastLASTNode->ListData : this.pLastLASTNode->ListData=0 :  End If
    If this.pGarbage->ListData<>0 Then : _Deallocate this.pGarbage->ListData : this.pGarbage->ListData=0 :  End If
    If this.pWhyteMove->ListData<>0 Then : _Deallocate this.pWhyteMove->ListData : this.pWhyteMove->ListData=0 :  End If
    If this.pFirstFIRSTNode->ListData<>0 Then : _Deallocate this.pFirstFIRSTNode->ListData : this.pFirstFIRSTNode->ListData=0 :  End If
    If this.pNode->ListData<>0 Then : _Deallocate this.pNode->ListData : this.pNode->ListData=0 :  End If
    If this.pEndFlat<>0 Then : _Deallocate(this.pEndFlat) : pEndFlat=0 : This.uNodeCOUNT-=1 :  End If   
    If this.pLastLASTNode<>0 And pLastLASTNode<>pWhyteMove And pLastLASTNode<>pFirstFIRSTNode Then : _Deallocate(this.pLastLASTNode) : pLastLASTNode=0 : this.uNodeCOUNT-=1 :  End If
    If this.pGarbage<>0 And pGarbage<>pNode Then : _Deallocate(this.pGarbage) : pGarbage=0 : This.uNodeCOUNT-=1 :  End If
    If this.pWhyteMove<>0 Then : _Deallocate(this.pWhyteMove) : pWhyteMove=0 : This.uNodeCOUNT-=1 :  End If
    If this.pFirstFIRSTNode<>0 Then : _Deallocate(this.pFirstFIRSTNode) : pFirstFIRSTNode=0 :  this.uNodeCOUNT-=1 :  End If
    If this.pNode<>0 Then : _Deallocate(this.pNode) : pNode=0 : this.uNodeCOUNT-=1 :  End If
    If Listptemp<>0 Then : _Deallocate(Listptemp) : Listptemp=0 :  End If : If Listptemp2<>0 Then : _Deallocate(Listptemp2) : Listptemp2=0 :  End If : If zp3<>0 Then :  _Deallocate(zp3) : zp3=0 :  End If
   ' If this.uNodeCount>2 Then : Print "Erreur a reporter : " & Str(this.uNodeCount-2) & " non dealloues !" : sleep : End If   '_Deallocate( New(@this) List )   
    Return 0
End Property

'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
  Dim As ListNode Ptr pTemp1, pTemp2
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode=pLocalMove Or pNode=pLocalRoot Or pNode=pEndFlat Then : Return 0 : End If
    this.NodeRecycle : this.NodeRecycle2
    If bSnatchBLMethod=0 Then       
        If pNode->pBranch=0 Then
            this.Branch : this.BlindTag("") : pTemp1=pNode : pLocalMove=pNode : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL
            If this.Snatch(pList) <> 1 Then : this.NodeRecycle : pLocalMove=pFirstNode : pFirstNode->pBranch->pBranch=0 : pFirstNode->pBranch=0 :  pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : this.NodeRecycle : Return 0
            Else : pTemp1->pPrev->pNext=pTemp1->pNext : pTemp1->pNext->pPrev=pTemp1->pPrev                 
            End If : this.uCount-=1 : pFirstNode->BranchCount-=1 : this.NodeRecycle
        Else : this.Branch : pNode=pFirstNode->pNext : If this.Snatch(pList) <> 1 Then : Return 0 : End If
        End If
 '       pTemp1=pFirstNode ' MAJ des pointeur pFirstNode->pPrev
 '       While pTemp1->pNext<>0 And pTemp1<>pFirstNode->pBranchLastNode : pTemp1=pTemp1->pNext : If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode : End If : Wend 
    Else       
        If pNode->pBranch=0 Then
            pTemp2=pList.GiveBranchDown : If pTemp2=0 Then : Return 0 : End If
            pTemp2->pBranch=pNode : pTemp2->pPrev=pFirstNode
            pNode->pBranch=pTemp2
            pLastNode=pTemp2->pBranchLastNode : pFirstNode=pTemp2 : pNode=pFirstNode->pNext : Return 1
        Else
            pTemp2=pList.GiveBranchDown : If pTemp2=0 Then : Return 0 : End If
            this.Branch :
            pTemp2->pPrev=pFirstNode->pPrev : pTemp2->pBranch=pFirstNode->pBranch : pTemp2->pBranch->pBranch=pTemp2
            pFirstNode->pNext->pPrev=pTemp2->pBranchLastNode : pTemp2->pBranchLastNode->pNext=pFirstNode->pNext
            pTemp2->pBranchLastNode=pFirstNode->pBranchLastNode
            pTemp1=pFirstNode ' MAJ des pointeur pFirstNode->pPrev
            While pTemp1->pNext<>0 And pTemp1<>pFirstNode->pBranchLastNode : pTemp1=pTemp1->pNext : If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pTemp2 : End If : Wend         
            pLocalMove=pFirstNode : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : pFirstNode=pTemp2
        End If
    End If
    this.UpLevel : Return 1
End Property

Property List.Snatch(pList As List) As Byte
    Dim As ListNode Ptr pTemp1, pTemp2
    this.NodeRecycle : this.NodeRecycle2
    If pNode->Tag(0)=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If
    ElseIf pNode->Tag(0)=LIST_RES Then : pNode=pNode->pNext : Return 0 : End If
   ' If pNode=pWhyteMove Then : Return 0 : End If
    pTemp1=pList.GiveBranch : If pTemp1=0 Then : Return 0 : End If
   ' If pFirstNode=pFirstFIRSTNode Then : pTemp2= : End If
    If bBranchCountDown=1 Then : this.BCountDown(pTemp1->BranchCount) : End If : uCount+=1 : pFirstNode->BranchCount+=1
    If pNode<>pLastNode Then : pNode->pNext->pPrev=pTemp1 : Else : pLastNode=pTemp1 : pFirstNode->pBranchLastNode=pTemp1 : End If
    If pTemp1->pBranch<>0 Then : pTemp1->pBranch->pPrev=pFirstNode  : End If
    pTemp1->pNext=pNode->pNext : pNode->pNext=pTemp1 : pTemp1->pPrev=pNode
    If pNode->pBranch<>0 Then : pNode->pBranch->pBranch=pNode : End If
    pList.AllOfPrivate : pNode=pTemp1 : this.VectorClear : Return 1
End Property

Property List.FlatSnatch(pList As List) As Byte
    Dim pTemp1 As ListNode Ptr : Dim pTemp2 As ListNode Ptr   
    pTemp1=pList.GiveFlat : If pTemp1=0 Then : Return 0 : End If
    pFlatRoot->pBranch->BranchCount+=pTemp1->BranchCount : uNodeCOUNT+=pTemp1->BranchCount : pTemp1->BranchCount=0
    pTemp2=pTemp1->pBranch : pTemp1->pBranch=0 : pFlatRoot->pBranch->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pBranch->pNext
    pFlatRoot->pBranch->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot->pBranch : Return 1
End Property

Property List.GarbageSnatch(pList As List) As Byte
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2 : Dim As ListNode Ptr pTemp1, pTemp2
    pTemp1=pList.GiveGarbage : If pTemp1=0 Then : Return 0 : End If : uNodeCOUNT+=pTemp1->BranchCount : uGarbCt+=pTemp1->BranchCount
    pTemp2=pTemp1->pBranch : pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext : pTemp1->pBranch=0 : pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot   
    pPanTemp1=pPanCakeGarbage->pNextContainer
    pPanTemp2=pList.GivePanCake : If pPanTemp2=0 Then : Return 0 : End If :  pPanCakeGarbage->pNextContainer=pPanTemp2
    pPanTemp2=pList.GiveLastPanCake : uContainerGarbCt+=pList.GivePanCakeCount : pPanTemp2->pNextContainer=pPanTemp1 : Return 1
End Property

Property List.CopyCat(pList As List) As Byte
    Dim As ListNode Ptr pTmp1, pTmp2=pNode : Dim as byte by=1 : this.NodeRecycle
    pTmp1=pNode->pNext : pList.HashKeyUnique(0) : pList.HashSort(1) : pList.fSortMethod(1)
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pList.SetRelation(bCopyCatMethod)
    If this.uTag=0 Then
        If this.bCopyCatMethod=1 Then : While pNode<>pTmp1 and by=1 : pList.HashTag(this.HashTag) : pList.RwTag1(this.Tag(1)) : pList.SetRelation1(this.pNode) : by=this.HashStep : Wend
        Else : pList.BranchCountDown(0) : While pNode<>pTmp1 and by=1 : pList.HashTag(this.HashTag) : pList.RwTag1(this.Tag(1)) : pList.SetRelation2(this.pNode) : by=this.HashStep : Wend   
        End If
    Else
        If this.bCopyCatMethod=1 Then : While pNode<>pTmp1 and by=1 : pList.HashTag(this.Tag(uTag)) : pList.SetRelation1(this.pNode) : by=this.HashStep : Wend
        Else : pList.BranchCountDown(0) : While pNode<>pTmp1 and by=1 : pList.HashTag(this.Tag(uTag)) : pList.SetRelation2(this.pNode) : by=this.HashStep : Wend
        End If
    End If
    pNode=pTmp2 : pList.HashKeyUnique(1) : Return 1
End Property

Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.994 -

Post by Lost Zergling »

Archive Beta 0.994 Part 1/3

Code: Select all

' NOTICE : Thank you to remove first single quote on the line below once you accepted the licence.
 /'   In case redistribution of SOURCES you may ensure to reactivate the acceptance of the license. This notice may be anywhere in source code till licensed user is aware it exists.
CONST PRODUCT_LIC =_
"_______________________________________________________________________________" & chr(10) &_
"  LZListsEngine/ListsVM by Etienne Carfagnini - contact:etienne.carfa@gmail.com" & chr(10) &_
"  Bd Henri Barbusse 92700 Colombes France 01 46 49 99 02" & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  This Freeware/Openware licence specify the rights to use the software" & chr(10) &_
"* Distribution of derivating software : " & chr(10) & "  The information access to the original software must be guaranteed to" & chr(10) & "  developers and users (https://freebasic.net/forum/ or alternative mentionned)" & chr(10) &_
"* Right to use the software and its derivating : 2 options : " & chr(10) & " >OPTION 1 (Openware) :"  & chr(10) & "  The software is free for any use (under FreeBasic)." & chr(10) &_
"  'LZLE Openware licence' is mentionned in licence contributors." & chr(10) &_
"  The software must be compiled using any official GPL FreeBasic Compiler." & chr(10) & "  https://freebasic.net/forum/viewforum.php?f=1 Or" & chr(10) & "  http://users.freebasic-portal.de/stw/builds/)" & chr(10) &_
" >OPTION 2 (Freeware) (any language) :"  & chr(10) & "  The software is free for any use except the following limitation as to its"  & chr(10) & "  fields of application : not for use on virtual machine or on virtual server." & chr(10) &_
"  'LZLE Freeware licence' is mentionned in licence contributors." & chr(10) &_
"* Apart from the restrictions of use (options 1 and 2) which are not compatible"  & chr(10) & "  with the rights of uses specified in clause 5.1, the legal clauses whenever"  & chr(10) &_
"  compatible will be those specified by the CeCILL-C license"  & chr(10) & "  ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )" & chr(10) &_
"  Disclaimer :"  & chr(10) & "  This licence refers to CeCILL-C but is NOT a CeCILL-C because the right to"  & chr(10) & "  use the software with no restriction is limited to the FreeBasic ecosystem." & chr(10) &_
"  This because it aims to be an extension of the language instructions set."  & chr(10) &_
"  LZLE (instruction set architecture,coding style) is dedicated to FreeBasic."  & chr(10) &_
"  This notice constitutes a whole that must be present in the source code." & chr(10) &_
"-------------------------------------------------------------------------------"  & chr(10) &_
"  Cette licence Freeware/Openware precise les droits a utiliser le logiciel" & chr(10) &_
"* Distribution de logiciels derives :" & chr(10) & "  L'acces informatif au logiciel original doit etre garanti aux" & chr(10) & "  developpeurs et aux utilisateurs (https://freebasic.net/forum/ ou autre)." & chr(10) &_
"* Droit d'utiliser le logiciel et ses derives : 2 options : " & chr(10) & " >OPTION 1 (Libre) :"  & chr(10) & "  Le logiciel est gratuit pour toute utilisation (sous FreeBasic)." & chr(10) &_
"  'LZLE licence Openware' est mentionne dans les contributions." & chr(10) &_
"  Le logiciel doit etre compile en utilisant n'importe quel compilateur GPL" & chr(10) & "  FreeBasic 'officiel' " & chr(10) & "  https://freebasic.net/forum/viewforum.php?f=1 ou bien" & chr(10) & "  http://users.freebasic-portal.de/stw/builds/" & chr(10) &_
" >OPTION 2 (Gratuiciel) (tout langage):"  & chr(10) & "  Le logiciel est gratuit pour tout usage sauf la limitation suivante quant a"  & chr(10) & "  son champs d'application : pas d'utilisation sur machine ou serveur virtuel." & chr(10) &_
"  'LZLE licence Freeware' est mentionne dans les contributions." & chr(10) &_
"* En dehors des restrictions d'utilisation (options 1 et 2) lesquelles ne sont "  & chr(10) & "  pas compatibles avec les droits d'utilisation prevus a la clause 5.1, les"  & chr(10) &_
"  clauses applicables seront celles compatibles specifiees par la licence"  & chr(10) & "  CeCILL-C ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-fr.txt )" & chr(10) &_
"  Avertissement :"  & chr(10) & "  Cette licence fait reference a la licence CeCILL-C mais n'en est PAS une car"  & chr(10) & "  le droit a utiliser librement le logiciel est limite a l'ecosysteme FreeBasic" & chr(10) &_
"  Ce moteur de liste a jeu d'instructions est dedie au langage FreeBasic" & chr(10) &_
"  Cette notice constitue un tout lequel doit etre present dans le code source." & chr(10) &_
"_______________________________________________________________________________"
Dim k As String
Print PRODUCT_LIC : Print
Print "Please press 'Y' (Yes) to accept the licence or Esc to abort"
Print "Merci d'appuyer sur 'O' (Oui) pour accepter la licence ou echap pour annuler"
Do : k = Inkey : Select Case k : Case "Y" : Exit Do : Case "y" : Exit Do : Case "O" : Exit Do : Case "o" : Exit Do : Case Chr(27) : System : End Select : Loop
Print "Removing first single quote on line 2 in source code will activate the licence" : Print "Retirer la premiere simple quote en ligne 2 du code source activera la licence" : Print "Thank you for chosing this software - Merci d'avoir choisi ce logiciel" : Print
'/ ' END NOTICE

Dim Shared As uInteger AllocateDeallocateCounter=0
Function _Callocate(Byval n As Integer) As Any Ptr : AllocateDeallocateCounter += 1 : Return Callocate(n) : End Function
Sub _Deallocate(Byval p As Any Ptr) : AllocateDeallocateCounter -= 1 : Deallocate(p) : End Sub

CONST MAX_KEYLEN=50
CONST RUP_COLS=2 : CONST MAX_COLS=7 : CONST MAX_TRACKS=20 ' RUP_COLS = ListNode ArraySize / MAX_COLS = Extended range ListNode ArraySize / MAX_TRACKS = all tracks are on a same single track beware not to overwrite elements otherwise overwritten track will be rerouted
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4)

Type ListContainer 'Data Segment Level
    Dim str_tag_C(RUP_COLS+1 to MAX_COLS-1) As String
    Dim str_item as String : Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag(0 to RUP_COLS) As String : Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode : Dim BranchCount As uInteger=0
End Type
Type ListContext ' Branch context Level   
    Dim  As ListNode Ptr pNode, pFirstNode, pLastNode : Dim As String LcHashTag : Dim  As uInteger  uCount : Dim As uByte bLcHashLen
End Type

Type List
    Declare Constructor() : Declare Destructor()   
   
    Private:
    Dim As zString Ptr Listptemp=_Callocate(MAX_KEYLEN), Listptemp2=_Callocate(MAX_KEYLEN), zp3=_Callocate(1)
    Dim  As ListContext Lcontext(0 to MAX_COLS-1), Tracks(0 to MAX_COLS-1)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt, PVS_Count=0, KR_Count=0 ' uSortThreshold=300 ', iLenDelta  ', iLenStrTmp, iLenpNode, iLenCumul, iLenDiff
    Dim As Byte uTag=0, bSearchRes=0, bRHByPass=0, bHashStepRev=0, bfStepZero=0, bTrackingMethod=0, bTracking=0, bHTMethod=1, bHashKeyUnique=1, uSortTag=0,_
                        bSortMT=1, bNFmethod=1, bRHmethod=-1, bAutoCursor=1, bSeekMethod=2, bBranchCountDown=0, bPickReduce=0, bCopyCatMethod=0, bCopyCatRelation=0,_
                        bColBcountLocked=0, bColTrackLocked=0, bAlrdyTracked=0, bSnatchBLMethod=0, bHStepTrace=0, bTrackMultiKeys=1, bPVSmethod=-1, bnStepByPass=0
                       
    Dim As uByte bHashLen=1, IsDestroyed=0, PVS_ratio=3, ubKeysRegister=0, uB_CurLevel=1, uB_Level=1, uB_KeyStepCumul=1, uB_MaxLevel=1, uB_BottomLevel=255, uB_BottomByPass=0, uB_tmp ', nbloops=0
    Dim As String  sSearchTag, sLatestHTag, Str_tmp, str_arbo , Str_tmp2, str_testTMP, sMV_Tag
    Declare Property AllowCake() As ListNode Ptr                      ' Cooking here
    Declare Property AllowPanCake() As ListContainer Ptr          ' No comment
    Declare Property AllRecycle() As uInteger   
    Declare Property Branch() As Byte                                        ' Descend dans la liste enfants, creation de nouvelles entrées
    Declare Property UpLevel() As Byte                                      ' Revient à la liste parente   
    Declare Property NodeRecycle() as Byte                              ' Supression en décalé (NodeFlat)
    Declare Property NodeRecycle2() as Byte                            ' Supression en décalé (RestoreHash)
    Declare Property RootPrivate As Byte                                   ' Accès direct rapide à la racine
    Declare Property FlatStack(uB as uByte) As Byte                 ' Construction de la Flat List avec retour à la racine(0) ou accès à la flat liste (1)
    Declare Property BCountDown(i As Byte) As Byte                ' CountDown calculation   
    Declare Property ValPrivate(str_Value As String) As Byte
    Declare Property ValPrivate As String
    Declare Property AllOfPrivate As uInteger
    Declare Property TrackCompute As Byte
    Declare Property HashStepTrace As Byte                              ' Required by Sort (for optimization)   
   
    Public:   
    'Special features - Private declared Public   
    Declare Property SetRelation(by as Byte) as Byte
    Declare Property SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr
    Declare Property SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr
    Declare Property Relation As ListNode Ptr   
    Declare Property GiveBranchDown As ListNode Ptr
    Declare Property GiveBranch As ListNode Ptr
    Declare Property GiveFlat As ListNode Ptr
    Declare Property GiveGarbage As ListNode Ptr
    Declare Property GivePanCake As ListContainer Ptr
    Declare Property GiveLastPanCake As ListContainer Ptr
    Declare Property GivePanCakeCount As uInteger
    'Flat control
    Declare Property Tag(str_Tag As String) As Byte                 ' Create a new ListNode with Key=str_Tag OR retrieve position of an existing Tag
    Declare Property Tag As String                                            ' Return current Tag value in a list =Tag(0)
    Declare Property Tag(iTag As Integer) As String                  ' Return current Tag value of the specified entry in array
    Declare Property HasTag(str_Tag As String) As Byte           ' Return 1 if Tag exists
    Declare Property BlindTag(str_Tag As String) As Byte          ' Create a new ListNode with Key=str_Tag at end of the list
    Declare Property RwTag(s_Tag As String) As Byte               ' Rewrite Tag Value of current Node : if current node is Hashed, just rewrite HashTag Value not effective Key value
    Declare Property RwTag0(s_Tag As String) As Byte                ' Rewrite Tag Value(0)
    Declare Property RwTag1(s_Tag As String) As Byte                ' Rewrite Tag Value(1) => eqivalent to MyList.ColTags(1) : MyList.RwTag("Label") : MyList.ColTags(0)
    Declare Property RwTag2(s_Tag As String) As Byte                ' Rewrite Tag Value(2)
    Declare Property RwTag3(s_Tag As String) As Byte                ' Rewrite Tag Value(3)
    Declare Property RwTag4(s_Tag As String) As Byte                ' Rewrite Tag Value(4)
    Declare Property ColTags As Byte                                       ' Renvoie le numéro de la colonne de tag active       
    Declare Property ColTags(i as Byte) As Byte                        ' Définie la colonne de tag active de 0 à MAX_COLS, par défaut 0   
    Declare Property AllOf As uInteger                                       ' Return number of node in  considered Flat List (root or branch), set position to the first node of current branch
    Declare Property Count As uInteger                                     ' Return current node Count of considered Flat List
    Declare Property First As Byte                                              'Set current node to first node considering flat list (root or branch)   
    Declare Property Last As Byte                                              'Set current node to Last node considering flat list (root or branch)       
    Declare Property Val(str_value As String) As Byte                ' Assign a string (+50 len) to the current node that is identified by a Tag
    Declare Property Val As String                                             ' Return current node string datas   
    Declare Property ValTag(str_value As String) As String        ' Considering current Flat list (root or branch as a flat list) return string data identified by Key=str_Tag
    Declare Property fStep As Byte                                            ' FOR EACH - While MyList.fStep : .. : Wend Jump to next node till current flat list end
    Declare Property fStepRev As Byte                                     ' FOR EACH - Idem fStep Jump to previous node till current flat list reach firstnode
    Declare Property bStep As Byte                                           ' FOR NEXT - For i=1 to MyList.AllOf : MyList.bStep : ..... : Next i    -> Jump to next node (NO CHECK)
    Declare Property BlindStep As Byte                                     ' FOR EACH - While MyList.BlindStep : .. : Wend -And- FOR NEXT - For i=1 to MyList.AllOf : MyList.BlindStep : ..... : Next i  Jump to next node  (check)   
    Declare Property BlindStep(i As Integer) As Byte                  ' Jump to +/-n nodes BlindStep(0) equiv Last : goto LastNode  (NO CHECK)
    Declare Property fMove(i As Integer) As Byte                      ' Move a node +/- n positions
    'Sorting
    Declare Property ColSort(i as Byte) As Byte                          'The column number to sort on (0-n) col 0 is indexed. Définie la colonne de tri active de 0 à MAX_COLS, par défaut 0
    Declare Property fSortMethod(bsortM As Byte) As Byte        'FLAT  1=ascending / -1=descending
    Declare Property fSort As Byte                                              'FLAT sort
    Declare Property HashSort(ub as Byte) as Byte                   '0=No sort on mapping, 1=ascending sort on HashTag mapping or on RestoreHash remapping
    Declare Property Sort As Byte
    Declare Property Sort(bSortmt As Byte) As Byte                  ' CASCADED : 1=ascending / -1=descending : sort(-1) returns a sorted list that is same result as sort(1)+HashStepRev except that sort impacts in memory tree structure
    'Hash control handling
    Declare Property Root As Byte                                           ' Check/Restore List integrity & set cursor to First node of root flat list - Shall be called before HashStep or After NodeFlat or RestoreHash
    Declare Property FlatStack As Byte                                    ' Flat List Access : use it before RestoreHash
    Declare Property RootNode As Byte                                  ' Set cursor to Root node of root flat list
    Declare Property EndNode As Byte                                   ' Set cursor to the last logical node  ( = While MyList.HashStep : Wend ) which is the last node of the last branch of last root flat node
    Declare Property HashStep As Byte                                   ' FOR EACH - recursive  parse property : syntax : While MyList.HashStep=1 : ... : Wend
    Declare Property HashStepRev As Byte                            ' FOR EACH - idem HashStep
    Declare Property KeyStep As Byte                                      ' FOR EACH - While MyList.KeyStep=1 : ... : Wend idem HashStep but show only Keys tagged by user, not the tree structure
    Declare Property KeyStepRev As Byte                               ' FOR EACH - idem KeyStep
    Declare Property nCurLevel(t as uByte) As Byte                 ' used by numericKeyStep & numericKeyStepRev
    Declare Property nHashStep(t as uByte) As Byte                ' used by numericKeyStep
    Declare Property nKeyStep(t as uByte) As Byte                  ' used by numericKeyStep
    Declare Property nKeyStep As Byte                                   ' numericKeyStep : numeric order
    Declare Property nHashStepRev(t as uByte) As Byte        ' used by numericKeyStepRev
    Declare Property nKeyStepRev(t as uByte) As Byte           ' used by numericKeyStepRev
    Declare Property nKeyStepRev as Byte                             ' numericKeyStepRev : numeric order
    Declare Property HashTag(str_Tag As String) As Byte       ' Build a hash Key on str_Tag, Return 1 if already exits otherwise return 0   
    Declare Property HashTag As String                                  ' Return Hash key value of current node 
    Declare Property HasHashTag(str_Tag As String) As Byte ' Return 1 if str_Tag is a hash key otherwise return 0
    Declare Property HasKey(str_Tag As String) As Byte          ' Idem HasHashTag Return 1 only for values specified with HashTag (not all cascaded index values)
    Declare Property NodeFlat As Byte                                   ' Déréférence une arborescence de clefs (un HashTag), et traite les données en conséquence       
    Declare Property RestoreHash As Byte                             ' Envoi un node de la Flat List en Hash List (réindexation)
    'Hash Control - Object's properties parameters
    Declare Property AutoCursor(i As Byte) As Byte                 'Method for HasTag(string), HasHashTag and HasKey:  0=do nothing current node is unchanged,  1 -DEFAULT- =move current to found on success (HasHashTag), 2=move current to found on success (HasKey), 3=move on partial success
    Declare Property BranchCountDown(i As Byte) As Byte     ' 1/0 Activate(1) or desactivate(0) BranchCountDown, default 0
    Declare Property CopyCatMethod(i As Byte) As Byte          '0 or 1 : CopyCat(1) : tracking is using tracking (no HoldBack/track) OR CopyCat(0) : tracking to source is on BranchCount (no BranchCountDown enabled) but tracking possible inside index !
    Declare Property HashKeyUnique(ub as Byte) As Byte      ' Default=1  HashKeyUnique(0)=>HashTag always create a new key even though a key already exists
    Declare Property HashLen(bHashLen As uByte) As Byte  ' Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' Enregistrement du hashTag parent en premier node caché : optimise l'enregistrement et la récupération de la clef (propriété hashTag) mais ralenti le mapping hashTag("key")
    Declare Property NFmethod(i As Byte) As Byte                  ' Determine le fonctionnement de NodeFlat : NFmethod=-1 node=>GarbageCollector  NFmethod=0 node=>FlatList sauf parents reliquataires NFmethod=1 node=>FlatList même les nodes parents contenant toujours des dépendances
    Declare Property NFrecursive(i As Byte) As Byte               ' NFrecursive=0 Standard / NFrecursive=1 parents nodes auto send to garbage collector till no other child and till they are not keys
    Declare Property PVSmethod(ub As Byte) As Byte            ' Predictive Vectors Static (optimization algo for HashTag) -1=no PVS / disabled (default), 0= PVS on, 1=PVS with priority forced
    Declare Property PVSratio(ub As uByte) As Byte               ' Static coeff for PVS dynamic adjustement
    Declare Property RHmethod(i As Byte) As Byte                 ' Determine le fonctionnement de RestoreHash par rapport aux doublons : RHmethod=-1 : Hashnode->GarbageCollector  / RHmethod=0 : no swap / RHmethod=1 : Hashnode->FlatList - RHmethod has no effect on multivalues lists ( HashKeyUnique(0) )
    Declare Property SeekMethod(i as Byte) As Byte              ' Method for Tag(string), HasTag(string), HashTag(string), HasHashTag and HasKey: 1(default)=seek from First to Last | 2: seek from Lastnode to firstNode | 0 :seek from currentnode to last node (Flat multikeys)
    Declare Property SnatchBLmethod(i As Byte) As Byte      ' For SnatchBelow 0=Source ParentNode snatched below target / 1=Source Child Nodes snatched below target (leaving ex-parent node in source list) (for intuitive key pairing between source & target)
    Declare Property TrackMethod(by As Byte) As Byte          ' MyList.TrackMethod(0)=might be faster (Default) / MyList.TrackMethod(1)=slow, might be more secure in specific cases (Pretty useless)
    Declare Property TrackMultiKeys(uB as uByte) As Byte    ' If <>0 multikeys will be automatically tracked (Track & TrackStep) on specified track each HashTag : working with CopyCat and RestoreHash as well
    Declare Property VectorUnlock As Byte                            ' Unlock auto security : Track vector is ONE choice between HoldBack/Track OR CopyCatMethod(1)/Follow - BranchCount vector is ONE choice between CopyCatMethod(0)/Follow OR BranchCountDown(1) OR PVSmethod(1+) - Using CopyCat index let you one choice left between Tracking, CountDown or PVS optimization
    Declare Property VectorClear As Byte                               ' If list structure has been changed (ie snatch, NodeFlat), tracking links or others (count down, PVS, or Follow) might be corrupted : working like CopyCat targeting current node and the whole child tree, clearing corrupted (or so called) links
    'Flow control
    Declare Property BranchCount As uInteger                        'Return Branch Count
    Declare Property Up As Byte                                              'idem UpLevel
    Declare Property Down As Byte                                         'idem Branch but prevent from creating an orphan sublist entry   
    Declare Property HoldBack As Byte                                  ' Works with Track : First Holback is initialiazing tracking, then each HolBack is recording a new tracked node. Track indicates to set cursor to first holbacked node & TrackStep is tracking all holbacked nodes in chronological order
    Declare Property HoldBack(i As Byte) As Byte                  ' Works with Track : indicates the number the track working with
    Declare Property TrackStep As Byte                                ' -SELECTIVE- FOR EACH - While MyList.TrackStep=1 : ... : Wend : selective PARSE only Keys marked for tracking by HoldBack
    Declare Property Track As Byte                                      ' Set track pointer to first tracked node
    Declare Property Track(i As Byte) As Byte                       ' Only one track but several track pointers
    Declare Property TrackSet As Byte                                 ' Create a breaking point in tracking : next List.Track+TrackStep will iterate from next tracked node just following breaking point / does not break track list, just replacing track starting point
    Declare Property TrackSet(i As Byte) As Byte
    Declare Property IsTracked As Byte                                ' When working with several tracks (pointers) it can be usefull to know wether a node has been already tracked or not to control tracking overwrite
    Declare Property TrackClear As Byte
    Declare Property TrackClear(i As Byte) As Byte              ' Indicates to reinitialize Track n°i : next HolBack will initialize a track to current node
    Declare Property Aside As Byte                                      ' Memorise ListNode ptr dans le pointeur n°0
    Declare Property Aside(i As Byte) As Byte                       ' Memorise ListNode ptr dans le pointeur n°i
    Declare Property Recover As Byte                                 ' Repositionne l'élément courant de la liste sur celui mémorisé par Take, si cet élément existe toujours, sinon renvoie False
    Declare Property Recover(i As Byte) As Byte                  ' Repositionne l'élément courant de la liste sur celui mémorisé par Take(i)
    Declare Property Follow(pList As List) As Byte
    'Memory management
    Declare Property FlatCount As uInteger                         ' Return number of values stored in Flat List
    Declare Property GarbageCount As uInteger                 ' Return number of nodes available in garbage collector
    Declare Property ContainerCount As uInteger                ' Return number of nodes container available in hidden garbage collector
    Declare Property NodeCount As uInteger                      ' Return number of nodes including not visible ones
    Declare Property GarbageFlat As Byte                            'Send all Flat List to GarbageCollector
    Declare Property Recycle As uInteger                            'AllFlat+GarbageCollector : détruit une arborescence et envoi tout en GarabgeCollector - do NOT garbage protected flat list
    Declare Property DropAll As uInteger                              'Remove all elements in list, except a 5/6 listnodes subset                         
    Declare Property Destroy As Byte                                   'Manual destructor
    'List Data Links & Exchange   
    Declare Property Snatch(pList As List) As Byte                  'Snatch a whole branch from another List to next node
    Declare Property SnatchBelow(pList As List) As Byte        'Snatch a whole branch from another List Below current node
    Declare Property FlatSnatch(pList As List) As Byte            'Target's Flat list is transfered to current list
    Declare Property GarbageSnatch(pList As List) As Byte    'Target's Garbage Collector is transfered to current list
    Declare Property CopyCat(pList As List) As Byte                'Create an index (linked to source)  from a flat (node per node) or indexed column (if so current node + its whole child tree), element by element (auto support multivalues) can work from loops (filtering)   
    'Debug
  '  Declare Property NextNode As String       
  '  Declare Property PrevNode As String   
End Type
'Shared
Dim Shared gCollector As List
' Improvments : RestoreHash and HasKey now support Multivalues /  FlatSnatch : BugFix /
' to do : Code Review+doc /   CopyCat+HashStep KO / Check tracking / Check Snatch & Snatch Below /
' BUGs :
'
' Property List.NextNode As String : Dim str_tmp as string="-" : If pNode->pNext<>0 Then : this.Aside : pNode=pNode->pNext : str_tmp= "next tag=" & pNode->Tag(0) & " & next hashtag=" & this.HashTag : this.Recover : Return str_tmp : End If : End Property
' Property List.PrevNode As String : Dim str_tmp as string="-" : If pNode->pPrev<>0 Then : this.Aside : pNode=pNode->pPrev : str_tmp= " prev tag=" & pNode->Tag(0) & " & prev hashtag=" & this.HashTag  & "  branch=" & Str(pNode->pBranch) : this.Recover : Return str_tmp : End If : End Property

'==========================================================================================CONSTRUCTOR & DESTRUCTOR  :  this.pFirstNode->pBranch->pBranchLastNode=0
Constructor List
    pFlatRoot = _Callocate(Len(ListNode)) : pNode = _Callocate(Len(ListNode)) : this.uNodeCOUNT+=2  ' Moment angulaire(petite masse)
    pPanCakeGarbage=_Callocate(Len(ListContainer)) : pPanCakeGarbage->pNextContainer=pPanCakeGarbage ': pTestContainer=pPanCakeGarbage ' Moment Angulaire(petite masse)
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag(0) = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag(0)=LIST_ROOT
    this.Root : this.AllOf
End Constructor
Destructor List : this.Destroy : End Destructor

'==========================================================================================TYPE LIST PRIVATE PROPERTIES
Property List.AllowCake As ListNode Ptr ' This.Vralloc
    Dim pTemp as ListNode Ptr=pFlatRoot->pNext ' uGarbCt>1 ' If pTemp<>0 Then : If pTemp->pNext=0  Then  : pTemp=pGarbage : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 :  Return pTemp : End If  : End If
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1 : ' And pTemp<>0 ' pTemp->pNext=0 : pTemp->pPrev=0 : pTemp->pBranch=0 :
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ': this.pLastLASTNode=pTemp ' Moment Angulaire(petite masse)         
    End If : Return pTemp
End Property
Property List.AllowPanCake As ListContainer Ptr
    Dim pPanTemp As ListContainer Ptr : dim uB As uByte
    If pPanCakeGarbage->pNextContainer<>pPanCakeGarbage Then
        pPanTemp=pPanCakeGarbage->pNextContainer : pPanTemp->str_item="" : For uB=RUP_COLS+1 To MAX_COLS-1 : pPanTemp->str_tag_C(uB)="" : Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else : pPanTemp=_Callocate(Len(ListContainer)) ': If pTestContainer2=0 Then : pTestContainer2=pPanTemp : End If  ' : pPanTemp->str_item=""  ' Moment Angulaire(petite masse)
    End If : Return pPanTemp
End Property

Property List.AllRecycle As uInteger
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext       
    Dim NbCollected As uInteger=0 : Dim as uByte ub1
    If this.pNode->pNext=0 Or this.pGarbage->pNext=0 Then : Return 0 : End If
    If pGarbage->ListData<>0 Then : pGarbage->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pGarbage->ListData : pGarbage->ListData=0 : uContainerGarbCt+=1 : End If
    If pLocalMove=pLastLASTNode Then : pLastLASTNode=pLastLASTNode->pPrev : End If : this.NodeRecycle : This.RootPrivate
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode= this.pGarbage->pNext : Else : pNode= this.pFirstNode->pNext : End If  : If pNode=0 Then : Return 0 : End If
    If pNode <>0 Then
        Do
            If pNode->Tag(0)<>LIST_RES And pNode->pBranch<>0 Then   
                pNode->pNext->pPrev=pNode->pBranch->pBranchLastNode : pNode->pBranch->pBranchLastNode->pNext=pNode->pNext
                pNode->pNext=pNode->pBranch : pNode->pBranch->pBranch=0 : pNode->pBranch=0 : pNode->BranchCount=0
                pNode->pNext->pPrev=pNode : pNode->pNext->pBranchLastNode=0 ':  pNode->pBranchLastNode=0
            Else
                If this.pNode->pNext<>0 Then
                    pNode->Tag(0) = LIST_DEL : For ub1=1 To RUP_COLS : pNode->Tag(ub1)="" : Next ub1 : pNode->BranchCount=0 : NbCollected +=1 ':  pNode->pBranchLastNode=0 ': iLong+=1
                    If pNode->ListData<>0 Then : pNode->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pNode->ListData : pNode->ListData=0 : uContainerGarbCt+=1 : End If                           
                    this.pNode=this.pNode->pNext
                End If               
            End If
        Loop Until pNode->pNext=0 Or pNode->pNext->Tag(0) = LIST_DEL
    End If
    If NbCollected>0 Then : This.uGarbCt+=NbCollected : uCount=0 : this.pFirstNode->BranchCount=this.uCount : pLastNode=pNode : If pFirstNode=pFirstFIRSTNode Then : pLastLASTNODE=pNode : End If : End If   
    This.RootPrivate : pGarbage=pLastNode->pPrev :pTemp=pNode : pNode=pGarbage : this.Val(LIST_DEL) : pNode=pTemp
    Return NbCollected
End Property

Property List.Branch As Byte
    Dim pTemp As ListNode Ptr :  Dim pTemp1 As ListNode Ptr   
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp = this.pNode
    If this.pNode->pBranch=0 Then ' this.NewHash(this.pNode)
        pTemp1 = this.pLastNode : this.uCount+=1 : pTemp1->pNext = this.AllowCake 'And eat it
        pTemp1->pNext->pPrev = pTemp1 : pTemp1->pNext->Tag(uTag) = LIST_RES
        pTemp1 = pTemp1->pNext : this.pLastNode = pTemp1 : pNode=pTemp1  ' this.BlindTag(LIST_RES) :
        this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp
        pTemp->pBranch=this.pNode : pTemp->BranchCount=0 : this.uCount=0 : pTemp->pBranchLastNode=this.pNode     
        this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : this.bSearchRes = 0 : Return 0
    Else 'Branche déjà créée
        this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
        this.pLastNode = this.pNode->pBranch->pBranchLastNode         
        this.pNode = this.pNode->pBranch : this.bSearchRes = 0 : Return 1
    End If   
End Property

Property List.UpLevel As Byte   
    If this.pFirstNode->pPrev = 0 Then : Return 0 : End If
    If this.pFirstNode->pBranch <> 0 Then ' Retour node de départ pour faciliter un parcours éventuel
        this.pNode = this.pFirstNode->pBranch : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
        this.pFirstNode = this.pFirstNode->pPrev : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode         
        this.bSearchRes = 0 ': this.sSearchTag = ""
        Return 1
    Else : Return 0
    End If               
End Property

Property List.NodeRecycle as Byte
    If pLocalMove<>0 Then 'pLocalMove est un node à suppression décalée       
        pLocalMove->pPrev=this.pFlatRoot : pLocalMove->pNext=this.pFlatRoot->pNext : pLocalMove->BranchCount=0 ' :  pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL :
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pLocalMove->ListData : pLocalMove->ListData=0 : uContainerGarbCt+=1 : End If
        this.pFlatRoot->pNext->pPrev=pLocalMove : this.pFlatRoot->pNext=pLocalMove : this.uGarbCt+=1
        pLocalMove = 0       
    End If
    Return 1
End Property
Property List.NodeRecycle2 as Byte
    If pLocalRoot<>0 Then 'pLocalRoot est un node LIST_RES             
        pLocalRoot->pPrev=this.pFlatRoot : pLocalRoot->pNext=this.pFlatRoot->pNext : pLocalRoot->Tag(0)=LIST_DEL  : pLocalRoot->BranchCount=0
        this.pFlatRoot->pNext->pPrev=pLocalRoot : this.pFlatRoot->pNext=pLocalRoot : This.uGarbCt+=1
        pLocalRoot->pBranch->pBranch=0 : pLocalRoot->pBranch->pBranchLastNode=0 : pLocalRoot->pBranch->BranchCount=0 :
        pLocalRoot->BranchCount=0 : pLocalRoot->pBranch=0 : pLocalRoot = 0
    End If
    Return 1
End Property

Property List.RootPrivate As Byte   
    this.AllOfPrivate : While UpLevel : Wend    ' While this.pFirstNode->pBranch <> 0 : this.UpLevel : Wend   '
    this.pFirstNode = this.pFirstFIRSTNode : this.bSearchRes = 0 : this.sSearchTag = ""
    this.pNode = this.pGarbage   
    Return 1
End Property

Property List.FlatStack(uB As Ubyte) As Byte
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc   
    Dim pTemp1 As ListNode Ptr   
    This.RootPrivate
    this.pNode=this.pFlatRoot : this.Branch
    If this.pLastNode=this.pFlatRoot->pBranch Then
        If this.pEndFlat<>0 Then : this.pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=this.pFlatRoot->pBranch : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1         
        End If
    ElseIf this.pLastNode<>this.pEndFlat Then           
        If this.pEndFlat<>0 Then
            this.pEndFlat->pPrev->pNext=this.pEndFlat->pNext : this.pEndFlat->pNext->pPrev=this.pEndFlat->pPrev
            this.pEndFlat->pPrev=this.pLastNode : this.pLastNode->pNext=this.pEndFlat : this.pEndFlat->pNext=0 : this.pLastNode=this.pEndFlat
        Else : this.BlindTag("") : this.pEndFlat=this.pNode : this.uCount -=1
        End If                       
    End If     
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If uB=0 Then : this.UpLevel : End If : this.AllOfPrivate
    Return 1
End Property
Property List.BCountDown(i As Byte) As Byte : Dim pTemp As ListNode Ptr=pFirstNode : While pTemp->pPrev<>0 : If pTemp->pBranch<>0 Then : pTemp->pBranch->BranchCount+=i : End If : pTemp=pTemp->pPrev : Wend : Return 1 : End Property
Property List.ValPrivate(str_value As String) As Byte : If this.pValTmp->ListData=0 Then : this.pValTmp->ListData=this.AllowPanCake : End If : this.pValTmp->ListData->str_item=str_value : Return 1 : End Property
Property List.ValPrivate As String : If this.pValTmp->ListData=0 Then : Return "" : End If : Return this.pValTmp->ListData->str_item : End Property

Property List.AllOfPrivate As uInteger
    this.pNode = this.pFirstNode
    If this.pFirstNode=this.pFirstFIRSTNode Then           
        this.pNode = this.pGarbage
        If pWhyteMove<>0 And pWhyteMove<>pLastNode Then  'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc
            If pWhyteMove->pNext<>0 Then : pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode :  End If     
            pLastNode=pWhyteMove : pLastNode->pNext=pFirstFIRSTNode '0
        End If   
    End If : Return this.Count
End Property

Property List.TrackCompute As Byte
    Dim As ListNode Ptr pTemp1=pNode
    If bAlrdyTracked=1 Then : Return 1 : End If
    While pTemp1->Tag(0)<>LIST_RES And pTemp1<>pGarbage
        If pTemp1->pBranch<>0 Then : pTemp1=pTemp1->pBranch->pPrev : Exit While : End If ' This code is naturally using one Swap, Cast and Exit for aesthetic and legitimate reasons, Gosub @ Extends are unfortunately missing.
        pTemp1=pTemp1->pPrev
    Wend
    If pTemp1=pGarbage Then : pTemp1=pFirstFIRSTNode : End If
    pFirstNode=pTemp1 : pLastNode=pTemp1->pBranchLastNode : uCount=pTemp1->BranchCount : bAlrdyTracked=1 : Return 1
End Property

Property List.HashStepTrace As Byte
    While this.pnode->pBranch<>0
        bHStepTrace=-1
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount
        this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : bHStepTrace=0 : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
         bHStepTrace=1 : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES destination is PRIVATE USE
Property List.SetRelation(by as Byte) as Byte : If by=0 Then : bColBcountLocked=1 : ElseIf by=1 Then : bColTrackLocked=1 : Else : Return 0 : End If : bCopyCatRelation=by : Return 1  : End Property
Property List.SetRelation1(pRelNode As ListNode Ptr) As ListNode Ptr : pNode->pBranchLastNode=pRelNode : Return pNode : End Property
Property List.SetRelation2(pRelFirstNode As ListNode Ptr) As ListNode Ptr : this.pNode->BranchCount=CuInt(pRelFirstNode) : Return pNode : End Property
Property List.Relation As ListNode Ptr : If this.bCopyCatRelation=1 Then : Return pNode->pBranchLastNode : ElseIf this.bCopyCatRelation=0 Then : Return Cast(ListNode Ptr, pNode->BranchCount) : Else : Return 0 : End If : End Property

Property List.GiveBranchDown As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2   
    If pNode->pBranch=0 Or pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag(0)="" Then : Return 0
    ElseIf pNode->pBranch->Tag(0)<>LIST_RES Then : Return 0 : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    this.NodeRecycle : this.NodeRecycle2 : this.VectorClear
    pTemp1=pNode->pBranch : pNode->pBranch=0 :
    Return pTemp1
End Property

Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp4
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Then : Return 0 : End If     
    bfStepZero=0 : this.NodeRecycle : this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp4=pNode->pPrev : pTemp1=pNode :
    If bBranchCountDown=1 Then : this.BCountDown(-pNode->BranchCount) : End If
    If pTemp1=pLastNode  Then : this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel : this.NodeRecycle2 : bfStepZero=1 :  Return pTemp1
    Else
        pNode->pPrev->pNext=pNode->pNext : pNode->pNext->pPrev=pNode->pPrev : uCount-=1 : pFirstNode->BranchCount-=1       
        If pTemp1=pLastNode And pFirstNode<>pFirstFIRSTNode Then
            this.NodeRecycle2 : pFirstNode->pBranch->pBranch=0 : pLocalRoot=pFirstNode : pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : this.UpLevel :  this.NodeRecycle2 : bfStepZero=1 : Return pTemp1
        End If         
    End If
    If pTemp4<>pFirstNode Then : pNode=pTemp4 : Else : pNode=pFirstNode->pNext : End If
    Return pTemp1
End Property

Property List.GiveFlat As ListNode Ptr       
    Dim As ListNode Ptr pTemp1, pTemp2
    If pNode->pPrev->Tag(0)=LIST_DEL Then : this.FlatStack(0) : End If
    If pFirstNode->pNext->Tag(0)=LIST_ROOT Then : this.Root : End If
    If pFlatRoot->pBranch=0 Then : Return 0 : End If         
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Or pFlatRoot->pBranch->pNext=pFlatRoot->pBranch  Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev : If pTemp2=0 Or pTemp1=pTemp2 Then : Return 0 : End If
    pTemp1->pBranch=pTemp2 : pFlatRoot->pBranch->pNext=pEndFlat : pEndFlat->pPrev=pFlatRoot->pBranch
    pTemp1->BranchCount=pFlatRoot->pBranch->BranchCount : uNodeCOUNT-=pFlatRoot->pBranch->BranchCount 'this.FlatCount :
    this.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If  ' this.FlatStack : uCount=0
    Return pTemp1   
End Property

Property List.GiveGarbage As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp2
    If uGarbCt<2 Then : Return 0 : End If : pTemp1=pFlatRoot->pNext : pTemp2=pGarbage->pPrev : If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext=pGarbage : pGarbage->pPrev=pFlatRoot : pTemp1->pBranch=pTemp2 : pTemp1->BranchCount=uGarbCt
    uNodeCOUNT-= uGarbCt : uGarbCt=0
    Return pTemp1
End Property
Property List.GivePanCake As ListContainer Ptr
    Dim As ListContainer Ptr pPanTemp1, pPanTemp2
    If uContainerGarbCt<2 Then : Return 0 : End If : pLastPanCake=0
    pPanTemp1=pPanCakeGarbage->pNextContainer : pPanTemp2=pPanTemp1
    While pPanTemp2->pNextContainer<>pPanCakeGarbage : pPanTemp2=pPanTemp2->pNextContainer : Wend : pPanTemp2->pNextContainer=0 : pLastPanCake=pPanTemp2
    pPanCakeGarbage->pNextContainer=pPanCakeGarbage : uContainerGivenCt=uContainerGarbCt : uContainerGarbCt=0
    Return pPanTemp1
End Property
Property List.GiveLastPanCake As ListContainer Ptr : Return pLastPanCake : End Property
Property List.GivePanCakeCount As uInteger : Return this.uContainerGivenCt : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLAT CONTROL
Property List.Tag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer Ptr
    If this.sSearchTag = str_Tag Then
        If this.bSearchRes=1 Then
            this.pNode = this.pSearchNode : Return 1 'pNode
        Else
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->Tag(uTag) = str_Tag ' pTemp->pNext->ListData = item :
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            this.pNode = pTemp : Return 0
        End If
    Else
        If this.bSeekMethod=1 Then : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then : pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
        Else
            pTemp = this.pNode : If pTemp->pNext <> 0 Then : pTemp = pTemp->pNext : End If
            While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag) : pTemp = pTemp->pNext : Wend
        End If
        If pTemp->Tag(uTag)<>str_Tag then ' New node
            pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
            pTemp->pNext->pPrev = pTemp : pTemp->pNext->ListData = item : pTemp->pNext->Tag(uTag) = str_Tag
            pTemp = pTemp->pNext : this.pLastNode = pTemp : If bBranchCountDown=1 Then : this.BCountDown(1) : End If           
            If pFirstNode=pFirstFIRSTNode And pWhyteMove<>pLastNode Then
                pWhyteMove->pPrev->pNext=pWhyteMove->pNext : pWhyteMove->pNext->pPrev=pWhyteMove->pPrev : pLastNode->pNext=pWhyteMove : pWhyteMove->pPrev=pLastNode : pLastNode=pWhyteMove : pLastNode->pNext=0
            End If : this.pNode = pTemp : Return 0
        End If   
    End If
    this.pNode = pTemp : Return 1 'pTemp
End Property

Property List.Tag As String
 '  Return this.pNode->Tag(uTag)
    If uTag<=RUP_COLS Then : Return this.pNode->Tag(uTag)
    ElseIf pNode->ListData=0 Then : Return ""
    Else : Return pNode->ListData->str_tag_C(uTag)
    End If
End Property
Property List.Tag(i As Integer) As String
    If i<=RUP_COLS Then : Return this.pNode->tag(i) : Else : If pNode->ListData<>0 Then : Return pNode->ListData->str_tag_C(i) : Else : Return "" : End If : End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag(uTag) <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
    Else
        pTemp = this.pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If
        While (pTemp->pNext <> 0  And pTemp->Tag(uTag) <> str_Tag AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag(uTag) = str_Tag Then
        this.pSearchNode=pTemp : this.bSearchRes=1 : If this.bAutoCursor=1 Then : pNode=pTemp : End If  : Return 1
    Else : this.bSearchRes = 0 : Return 0 : End If   
End Property

Property List.BlindTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pLastNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pLastNode : pTemp->pNext->Tag(uTag) = str_Tag
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte : If uTag<=RUP_COLS Then : this.pNode->tag(this.uTag)=s_Tag : Return 1 : Else : If pNode->ListData=0 Then : this.pValTmp=this.pNode : this.ValPrivate("") : End If : pNode->ListData->str_tag_C(uTag)=s_Tag : Return 1 : End If : End Property
Property List.RwTag0(s_Tag As String) As Byte : this.pNode->tag(0)=s_Tag : Return 1 : End Property
Property List.RwTag1(s_Tag As String) As Byte : this.pNode->tag(1)=s_Tag : Return 1 : End Property
Property List.RwTag2(s_Tag As String) As Byte : uB_tmp=uTag : uTag=2 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property
Property List.RwTag3(s_Tag As String) As Byte : uB_tmp=uTag : uTag=3 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property
Property List.RwTag4(s_Tag As String) As Byte : uB_tmp=uTag : uTag=4 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property

Property List.ColTags As Byte : Return(this.uTag) : End Property
Property List.ColTags(i as Byte) As Byte : this.sSearchTag = "" : this.bSearchRes=0 : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uTag=i : Return 1 : End If : End Property

Property List.AllOf As uInteger
    Dim pContextRetour As ListContext
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Return 0 : End If :
    Dim  As ListNode Ptr pTemp, pTemp2 : If bTracking=1 Then : this.TrackCompute :  bTracking=0 : End If
    If pFirstNode=pFIRSTFIRSTNode Then : If pLastNode<>pWhyteMove Then : this.Root : End If : End If
    this.NodeRecycle : this.NodeRecycle2
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.AllOfPrivate
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : uCount=pContextRetour.uCount
    pNode=AllowCake : pLocalMove=pNode
    If this.pFirstNode=this.pFirstFIRSTNode Then : pNode->pNext=pGarbage->pNext : Else : pNode->pNext=pFirstNode->pNext : End If
    If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    Return this.Count
End Property

Property List.Count As uInteger
    Dim pTemp As ListNode Ptr
    If pWhyteMove=0 And pFirstNode=pFIRSTFIRSTNode Then : pTemp=this.pNode : this.uCount-=2 : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : Return this.uCount
End Property

Property List.First As Byte : If pFirstNode=pFirstFIRSTNode Then : pNode=pGarbage : Else : this.pNode=This.pFirstNode->pNext : End If : Return 1 : End Property
Property List.Last As Byte : this.pNode=This.pLastNode : Return 1 : End Property

Property List.Val(str_value As String) As Byte : this.pValTmp=this.pNode : this.ValPrivate(str_value) : Return 1 : End Property
Property List.Val As String : pValTmp=pNode : Return this.ValPrivate : End Property
Property List.ValTag(str_value As String) As String
    If bSearchRes=1 Then : If str_value=this.Tag(0) Then : pValTmp=pSearchNode : Return this.ValPrivate : End If
    ElseIf this.HasTag(str_value)=1 Then : pValTmp=pSearchNode : Return this.ValPrivate
    End If : Return("")
End Property

Property List.fStep As Byte : If pNode=pLastNode Or bfStepZero=1 Or pNode->pNext=pWhyteMove Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pNext : Return 1 : End If : End Property '
Property List.fStepRev As Byte : If pNode->pPrev=pFirstNode Or pNode->pPrev=pGarbage Or bfStepZero=1 Then : bfStepZero=0 : Return 0 : Else : pNode = pNode->pPrev : Return 1 : End If : End Property
Property List.bStep As Byte : this.pNode = this.pNode->pNext : Return 1 : End Property
Property List.BlindStep As Byte : If this.pNode->pNext<>0 Then : this.pNode = this.pNode->pNext : Return 1 : Else   : Return 0 : End If : End Property ' : Print "*Warning : list parse or count down error"
Property List.BlindStep(top As Integer) As Byte
    Dim As Integer i : Dim As Byte istep
    If top>0 Then : istep=1 : For i=1 To top step istep : this.pNode = this.pNode->pNext : Next i : ElseIf top = 0 Then : this.pNode = this.pLastNode : Return 1 : Else : istep=-1 : For i=-1 To top step istep : this.pNode = this.pNode->pPrev : Next i : End If
    Return 1
End Property
Property List.fMove(nbMove As Integer) As Byte
    Dim As ListNode Ptr pFirst, pTemp : Dim i As Integer=0
    If pNode->Tag(0)=LIST_DEL Or pNode->Tag(0)=LIST_RES Or pNode=pWhyteMove Or pNode=pEndFlat  Or pNode=pLocalMove Or pNode=pLocalRoot Then : Return 0 : End If
    If pFirstNode=pFirstFIRSTnode Then : pFirst=pGarbage : Else : pFirst=pFirstNode : End If
    If pNode=pLastNode Then : pLastNode=pNode->pPrev : Else : pNode->pNext->pPrev=pNode->pPrev : End If
    pNode->pPrev->pNext=pNode->pNext : pTemp=pNode
    If nbMove>0 Then : For i=0 To nbMove-1 : If pNode<>pLastNode Then : pTemp=pTemp->pNext : End If : Next i
    Else : For i=nbMove To 0 : If pTemp<>pFirstNode Then : pTemp=pTemp->pPrev : End If : Next i
    End If
    If pTemp<>pLastNode Then : pTemp->pNext->pPrev=pNode : pNode->pNext=pTemp->pNext
    Else : If  pTemp->pNext<>0 Then : pNode->pNext=pTemp->pNext : End If : pLastNode=pNode
    End If
    pTemp->pNext=pNode : pNode->pPrev=pTemp
    Return 1
End Property
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.994 -

Post by Lost Zergling »

Archive Beta 0.994 Part 2/3

Code: Select all

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS-1 then : this.uTag=MAX_COLS-1 : Return 0 : Else : this.uSortTag=i : Return 1 : End If : End Property
Property List.fSortMethod(bsortM As Byte) As Byte : If bsortM=-1 Then : this.bSortMT=-1 : Else : this.bSortMT=1 : End If : Return 1 : End Property
Property List.fSort As Byte
    Dim As ListNode Ptr pTemp1=pFirstNode, pTemp2, pTemp3, pTemp4, pTemp5=pLastNode->pNext : Dim as byte  by=1
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If   
    'Trie+Insert Sort - non recursive   
    gCollector.SetRelation(1) : gCollector.HashKeyUnique(1) : gCollector.HashSort(1) : gCollector.fSortMethod(1) : gCollector.HashLen(1) : gCollector.GarbageSnatch(this)
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pTemp3=pTemp1 : pNode=pTemp1->pNext : If pNode=pFirstNode Then : pTemp4=pFirstNode->pNext : Else : pTemp4=pNode : End If
    While pNode<>pLastNode and by=1 : gCollector.HashTag( this.Tag) : gCollector.SetRelation1(this.pNode) : by=this.fStep : Wend ' gCollector.HashTag( this.pNode->Tag(uTag) ) <> gCollector.HashTag( this.Tag ) wheras pNode->Tag(uTag) = this.Tag ?
    If pFirstNode<>pFirstFIRSTnode Then : gCollector.HashTag( this.Tag ) : gCollector.SetRelation1(this.pNode)  : End If
    gCollector.Root
    If this.bSortMT=1 Then : While gCollector.KeyStep : If this.Follow(gCollector) Then : pTemp3->pNext=this.pNode : pNode->pPrev=pTemp3 : pTemp3=pNode : End If : Wend         
    Else : While gCollector.KeyStepRev : If this.Follow(gCollector) Then : pTemp3->pNext=this.pNode : pNode->pPrev=pTemp3 : pTemp3=pNode : End If : Wend
    End If
    pFirstNode->pBranchLastNode=pTemp3 : this.pLastNode=pTemp3 : pNode=pTemp4
    If pFirstNode=pFirstFIRSTnode Then : pWhyteMove->pPrev=pLastNode : End If
    gCollector.Recycle : this.AllOf : this.GarbageSnatch(gCollector)
    Return 1
End Property

Property List.Sort as Byte : this.Sort(this.bSortMT) : Return 1 : End Property
Property List.Sort(bSortMth As Byte) as Byte
    Dim As ListNode Ptr s_pNode=pNode, s_pFirstNode=pFirstNode
    Dim As uInteger s_uCount=uCount
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If   
    this.Root : this.fSort : this.pNode=pGarbage
    While this.HashStepTrace : If bHStepTrace=-1 Then : this.fSort : pNode=this.pFirstNode->pNext : End If : Wend
    pNode=s_pNode : pFirstNode=s_pFirstNode : pLastNode=pFirstNode->pBranchLastNode : uCount=s_uCount
    Return 1
End Property
Property List.HashSort(ub as Byte) As Byte : If ub=1 And this.bSortMT=-1 Then : this.bSortMT=1 : End If : If ub=0 Or ub=1 Then : bHTmethod=ub : uSortTag=uTag : Return 1 : Else : Return 0 : End If : End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - HASH CONTROL
Property List.Root As Byte
    Dim pTemp As ListNode Ptr : Dim pTemp2 As ListNode Ptr : Dim pContextRetour As ListContext     
    If bTracking=1 Or pFirstNode->Tag(0)<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If :' this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode   
    If this.IsDestroyed=1 Then : Print "Error List destroyed : instance can't be re-used" : Beep : Return 0 : End If
    this.RootPrivate : If pLocalMove<>0 Then : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL : End If
    this.NodeRecycle : this.NodeRecycle2 : bSearchRes=0 : pTemp2=0 : this.bHashStepRev=0 : pLatestHTag=0
    'Changement de fonctionnement - Patch de compatibilité - : il faut un dernier node logique à blanc qui ne soit jamais 'flaté'
    If this.pWhyteMove<>0 Then
        pWhyteMove->Tag(0)=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag(0)<>LIST_RES Then           
            If pWhyteMove->pPrev<>0 Then : this.pWhyteMove->pPrev->pNext=this.pWhyteMove->pNext : End If
            If pWhyteMove->pNext<>0 Then :this.pWhyteMove->pNext->pPrev=this.pWhyteMove->pPrev : End If         
        End If       
    End If ' If pPanCakeGarbage=0 Then : pPanCakeGarbage=AllowPanCake : pPanCakeGarbage->pNextContainer=pPanCakeGarbage : End If   
    If pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : this.Val(LIST_DEL) : pGarbage->pPrev=pFlatRoot
        If pFlatRoot->pNext<>pGarbage Then : pGarbage->pNext=pFlatRoot->pNext : End If : pFlatRoot->pNext=pGarbage
        If pGarbage->pNext<>0 Then : pGarbage->pNext->pPrev=pGarbage : End If : this.pNode = pGarbage
    End If
    If pFirstNode->pPrev=0 And pNode->pNext=0 Then : pTemp=pNode : this.AllOf : pNode=pTemp : End If
    'Gestion du contexte de la Flat List qui doit contenir un dernier node à blanc
    this.FlatStack(0)
    'Corrections  - Patch de compatibilité - : pFlatRoot se balade, il faut le remettre au début -
    If pFlatRoot->pPrev<>0 Then : pFlatRoot->pPrev->pNext=pFlatRoot->pNext : End If : If pFlatRoot->pNext<>0 Then :  pFlatRoot->pNext->pPrev=pFlatRoot->pPrev : End If
    pFlatRoot->pPrev=this.pFirstFIRSTNode : pFlatRoot->pNext=this.pFirstFIRSTNode->pNext : If this.pFirstFIRSTNode->pNext<>0 Then : this.pFirstFIRSTNode->pNext->pPrev=pFlatRoot : End If : this.pFirstFIRSTNode->pNext=pFlatRoot
    'Changement de fonctionnement - Patch de compatibilité - pLastLAST devient dernier node LOGIQUE : on le remet à jour
    If this.pFirstFIRSTNode->pBranchLastNode<>0 Then
        pTemp=this.pFirstFIRSTNode->pBranchLastNode : While pTemp->pBranchLastNode<>0 And pTemp<>pTemp2 : pTemp2=pTemp : pTemp=pTemp->pBranchLastNode : Wend : this.pLastLASTNode=pTemp       
    End If     
    'NodeFlat+Restorehash nécessite la présence d'un dernier node fictif
    If this.pLastNode->Tag(0)<>"" Then : If pWhyteMove<>0 Then : this.AllOf  : Else : pTemp=this.pNode : this.pFirstNode->BranchCount=this.uCount : this.BlindTag("") : this.pWhyteMove=this.pNode : this.pNode=pTemp : End If : End If
    this.pNode=pGarbage : this.uCount=this.pFirstFIRSTNode->BranchCount : this.pLastLASTNode->pPrev->pNext=this.pLastLASTNode
    If this.pLastLASTNode->pNext->Tag(0)=LIST_RES Then : this.pLastLASTNode->pNext=0 : End If
  ' Option for .Root become compatible with Rev parse with no need to jump to Last node (List.Last)
    this.pNode=AllowCake : pNode->Tag(0)="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext : pLocalMove->Tag(1)="" : pLocalMove->pBranch=0 :  pLocalMove->Tag(0)=LIST_DEL
    If pLastNode=pWhyteMove Then : pNode->pPrev=pLastNode->pPrev : Else : pNode->pPrev=pLastNode : End If
    this.NodeRecycle2 : this.pFirstNode->BranchCount=this.uCount : this.pFirstNode->pBranchLastNode=this.pLastNode
    uB_CurLevel=1 : uB_Level=1 : If bnStepByPass=0 Then :  uB_BottomLevel=255 : uB_MaxLevel=1 : uB_KeyStepCumul=1 : End If
    Return 1
End Property

Property List.FlatStack As Byte : this.FlatStack(1) : this.AllOf : bSearchRes=0 : Return 1 : End Property
Property List.RootNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pFirstFIRSTNode : Return 1 : End Property
Property List.EndNode As Byte : bSearchRes=0 : this.Root : this.pNode=This.pLastLASTNode : Return 1 : End Property

Property List.HashStep As Byte
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If ' If pNode=pWhyteMove Then : Return 0 : Else : Return 1 : End If
    Wend : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend : this.RootPrivate : Return 0
End Property

Property List.HashStepRev As Byte
    this.bHashStepRev=1
    While this.pnode->pBranch<>0
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode=pLastNode->pPrev : Else : pnode=pLastNode : End If : Return 1
    Wend : If pnode->pPrev=pGarbage Then : bHashStepRev=0 : Return 0 : End If : If pnode->pPrev<>pFirstNode Then : this.pnode = this.pnode->pPrev : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    While pFirstNode->pBranch<>0
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : bHashStepRev=0 : Return 0 : End If : Return 1 : End If ' And pnode->pPrev->Tag(0)<>LIST_RES
    Wend : this.bHashStepRev=0 : Return 0
End Property

Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : End Property

'Numeric parse optimization
Property List.nCurLevel(uB_len as uByte) As Byte : If uB_len=uB_CurLevel Then : Return 1 : Else : Return 0 : End If : End Property

'Numeric sorted parse
Property List.nHashStep(uB_len as uByte) As Byte   
    While this.pnode->pBranch<>0 And uB_CurLevel<=uB_len
        uB_CurLevel +=1 : If uB_CurLevel>uB_MaxLevel Then : uB_MaxLevel=uB_CurLevel : End If
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pnode<>pLastNode Then : pnode=pnode->pNext : If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If
    Wend :     
    If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : Return 0 : Else : Return 1 : End If : End If   
    While pFirstNode->pBranch<>0
        uB_CurLevel -=1
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If pnode<>pLastNode Then : pnode=pnode->pNext :  If pNode=pWhyteMove Then : this.AllOf : uB_Level+=1 : Return 0 : Else : Return 1 : End If : End If
    Wend :
    this.RootPrivate : Return 0
End Property
Property List.nKeyStep(uB_len as uByte) As Byte : While this.nHashStep(uB_len)=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : Return 0 : End Property
Property List.nKeyStep as Byte
    While uB_KeyStepCumul<=uB_MaxLevel
        While this.nKeyStep(uB_Level) : If this.nCurLevel(uB_Level)=1 Then : Return 1 : End If : Wend
        bnStepByPass=1 : this.Root : bnStepByPass=0 : uB_Level+=uB_KeyStepCumul : uB_KeyStepCumul+=1
    Wend : uB_CurLevel=1 : uB_Level=1 : uB_MaxLevel=1 : uB_KeyStepCumul=1 : Return 0
End Property

'Numeric sorted Reverse parse
Property List.nHashStepRev(uB_len as uByte) As Byte   
    this.bHashStepRev=1
    While this.pnode->pBranch<>0 And uB_CurLevel<=uB_len
        uB_CurLevel +=1 : If uB_CurLevel>uB_MaxLevel Then : uB_MaxLevel=uB_CurLevel : uB_BottomLevel = uB_MaxLevel+1 : End If
        this.pFirstNode=this.pNode->pBranch : this.uCount=this.pFirstNode->BranchCount : this.pLastNode=this.pNode->pBranch->pBranchLastNode : this.pNode=this.pNode->pBranch
        If pLastNode=pWhyteMove And pLastNode->pPrev<>0 Then : pNode=pLastNode->pPrev : Else : pnode=pLastNode : End If : Return 1
    Wend : If pnode->pPrev=pGarbage Then : Return 0 : End If : If pnode->pPrev<>pFirstNode Then : this.pnode = this.pnode->pPrev : Return 1 : End If
    While pFirstNode->pBranch<>0
        uB_CurLevel -=1
        pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : uCount=pFirstNode->BranchCount
        pLastNode=pFirstNode->pBranchLastNode : If this.pnode <> this.pFirstNode->pNext Then : this.pnode = this.pnode->pPrev : If pnode=pGarbage Then : Return 0 : End If : Return 1 : End If
    Wend : Return 0
End Property
Property List.nKeyStepRev(uB_len as uByte) As Byte : While this.nHashStepRev(uB_len)=1 : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : End If : Wend : Return 0 : End Property
Property List.nKeyStepRev as Byte
   Dim t as Integer
   For t=uB_BottomLevel to 1 Step-1
        While this.nKeyStepRev(uB_BottomLevel) : If this.nCurLevel(uB_BottomLevel)=1 Then : Return 1 : End If : Wend : bnStepByPass=1 : this.Root : bnStepByPass=0 : uB_BottomLevel-=uB_KeyStepCumul
    Next t : uB_CurLevel=1 : uB_BottomLevel=255 : uB_KeyStepCumul=1 : Return 0
End Property

Property List.HashTag(str_Tag As String) As Byte
   Dim As ListNode Ptr pTemp,  pTemp02, pTemp03 , pTemp04
    Dim As uInteger i=0, iLen=Len(str_tag), iLenStrTmp, iLenpNode, iLenCumul, iLenDiff, iLenDelta=0, PvsiStep
    Dim As uByte HadHashTag=1, istep=this.bHashLen, IsLast=0, IsPt2Swp=0, IsPtSwp=0, bSeekMethod_TMP=bSeekMethod, bAutoCursor_TMP=bAutoCursor
    Dim As zString Ptr zp1, zp2, Listptemp2_b, Listptemp_b : Dim As String str_testTMP
    If iLen>MAX_KEYLEN Then : Listptemp2_b=_CAllocate(iLen+1) : Swap Listptemp2,Listptemp2_b : IsPt2Swp=1 : End If
    str_testTMP=str_Tag : If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute : End If

    If pFirstNode<>pFirstFIRSTNode Then 'Déclenchement optimisation // Si pFirstNode=pFirstFIRSTNode il est possible que la liste soit vide ou que le node en cours soit en cours d'envoi au garbage collector
        If pLatestHTag=pNode Then : Str_tmp=sLatestHTag '  Algo optimisation 1 : basé sur la récupération la + rapide possible de la position dans l'arbre // And bPVSmethod=0 //  l'algo d'optimisation le plus simple est souvent le + efficace et reste prioritaire sur PVS
        Else : pNode=pFirstNode->pNext : If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
        End If
        iLenStrTmp=Len(Str_tmp)         
        If iLenStrTmp>MAX_KEYLEN Then : Listptemp_b=_CAllocate(iLenStrTmp+1) : Swap Listptemp,Listptemp_b : IsPtSwp=1 : End If
        If iLen>iLenStrTmp Then : iLenDiff=iLen-iLenStrTmp : End If
       
        *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
        *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=istep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)
        If *Listptemp=*Listptemp2  And bPVSmethod<1 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs) // And bPVSmethod=0
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
       '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
            iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
            pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
            While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
            Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
            iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
            If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode             
           
        ElseIf bPVSmethod>-1 Then ' Algo optimisation 2 : basé sur l'enregistrement à un niveau PvsiStep càd (lngClef/n)+1 de la longueur de la clef, d'un pointeur "prédictif" vers une branche plus basse de l'arbre
            PvsiStep=iLen/PVS_ratio+1
            *Listptemp=Str_tmp : zp1=Listptemp : zp1+=PvsiStep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            *Listptemp2=str_tag : zp2=Listptemp2 : zp2+=PvsiStep : (*zp2)[0]=0 ' *Alternative to *Listptemp2=Left(str_tag,istep)       
            If  *Listptemp<>*Listptemp2 Then' *Alternative to If Left(Str_tmp,istep)<>Left(str_tag,istep) Then   *Listptemp<>*Listptemp2     
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage
                this.HashTag(*Listptemp2 ) 'youpi
                If pNode->BranchCount<>0 Then : pFirstNode=Cast(ListNode Ptr, pNode->BranchCount) : pLastNode=pFirstNode->pBranchLastNode : End If :  pTemp04=pNode : PVS_Count+=1               
                pNode=pFirstNode->pNext : pNode=pFirstNode->pNext
                If pFirstNode->Tag(1)<>"" Then : Str_tmp=pFirstNode->Tag(1) & pNode->Tag(0) : Else : Str_tmp=this.HashTag : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(Str_tmp, Len(Str_tmp)-istep) : End If : End If
                *Listptemp=Str_tmp : zp1=Listptemp : zp1+=istep : (*zp1)[0]=0 ' *Alternative to *Listptemp=Left(Str_tmp,istep)
            End If
            If *Listptemp=*Listptemp2 Then  ' Algo optimisation 1 & 2 : on cale la longueur de la clef predictive sur celle de la clef à atteindre ou à créer, en remontant dans l'arbre le cas échéant (en utilisant la fonction d'upwelling de l'arbre : pointeurs directs)
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                iLenpNode=Len(pNode->Tag(uTag)) 'iLenpNode=iLen :
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : iLenpNode=Len(pNode->Tag(uTag)) :  Wend   
                pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
           '     While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext :
                iLenStrTmp=Len(Str_tmp) ': i=1 ': iLenpNode=Len(pNode->Tag(uTag)) :
                pFirstNode->BranchCount=uCount :  pFirstNode->pBranchLastNode=pLastNode
                While Left(str_tag, iLenStrTmp)<>Str_tmp  ' Algo optimisation 1 & 2 : on redescendra ensuite dans l'arbre depuis le point de l'arbre le plus bas commun aux deux clefs = économie de lookup si la prédiction est réalisée
                    Str_tmp=Left(Str_tmp, iLenStrTmp-iLenpNode)
                    iLenStrTmp-=iLenpNode : iLenCumul +=iLenpNode : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenpNode=istep
                Wend : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
                iLen=iLenCumul+istep+iLenDiff : str_Tag=Right(str_Tag, iLen) : pTemp02=pFirstNode : iLenDelta=iLenStrTmp-iLenpNode
                If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : End If ' And pLatestHTag=pNode   
            Else               
                pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
                this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1               
            End If 
           
        Else
            pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode
            this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode : pTemp02=pGarbage : bSeekMethod_TMP=1
        End If
    Else
        pTemp02=pGarbage : bSeekMethod_TMP=1
    End If ' Fin algo optimisation   
   
    iLenCumul=0 : *Listptemp2=str_Tag : zp1=Listptemp2 ' * Alternative to Mid
    For i=1 to Len(str_Tag) step istep
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid :  Str_tmp=Mid(str_Tag,i, istep)
        iLenCumul+=iStep
        If bHTmethod=0 Then
            If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
            Else : pTemp = pTemp02 : While ( pTemp->Tag(uTag)<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
            End If
        Else
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                While ( pTemp->Tag(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else
                pTemp=pTemp02 : While (pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend               
                If pTemp->Tag(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
            End If
        End If       
        If pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp  'bHashKeyUnique
        ElseIf pTemp->Tag(uTag)=Str_tmp And bHashKeyUnique=0 And iLenCumul<iLen Then : this.pNode = pTemp
        ElseIf bHTmethod=1 And IsLast=0 Then
            pTemp03=AllowCake : this.uCount+=1
            pTemp03->pNext=pTemp : pTemp03->pPrev=pTemp->pPrev : pTemp->pPrev->pNext=pTemp03 : pTemp->pPrev=pTemp03         
            If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pTemp03->Tag(uTag) = Str_tmp : HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03           
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If           
        Else ' If pTemp=pTemp02 Then : this.BlindTag(Str_tmp)                           
            pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode : pTemp03->pNext->Tag(uTag) = Str_tmp
            this.pLastNode = pTemp03->pNext : this.pNode = pTemp03->pNext : If bBranchCountDown=1 Then : this.BCountDown(1) : End If
            pLastNode->pPrev = pTemp03 : HadHashTag=0 : pFirstNode->BranchCount+=1
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If pTemp->Tag(uTag)=Str_tmp Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : this.HoldBack(bTrackMultiKeys) : End If
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system
        End If
        If iLenCumul<iLen Then  '  If u*istep<iLen Then   ' this.Branch
            pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : pTemp=pNode
            If this.pNode->pBranch=0 Then ' New 'Hash' : this.BlindTag(LIST_RES) :
                pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
                pTemp03->pNext->pPrev = pTemp03 : pTemp03->pNext->Tag(uTag) = LIST_RES
                pTemp03 = pTemp03->pNext : this.pLastNode = pTemp03 : pNode=pTemp03
                this.pNode->pPrev=this.pFirstNode : pNode->pBranch = pTemp : pTemp->pBranch=this.pNode
                this.uCount=0 :' pTemp->pBranchLastNode=this.pNode     pTemp->BranchCount=0 :
                this.pFirstNode=pTemp->pBranch : this.pNode = this.pFirstNode : If ubKeysRegister=1 Then : pFirstNode->Tag(1)=Left(str_testTMP, iLenCumul+iLenDelta) : End If      '
            Else 'Branche déjà créée
                this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount
                this.pLastNode = this.pNode->pBranch->pBranchLastNode : this.pNode = this.pNode->pBranch
            End If
        End If : pTemp02=pFirstNode
    Next i
    this.pLatestHTag=this.pNode : this.sLatestHTag=str_testTMP :
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag(1)="" And bRHByPass=0 Then : this.pNode->Tag(1)=" " : End If
    If pTemp04<>0 Then : pTemp04->BranchCount=CuInt(pFirstNode)  : End If
    If IsPt2Swp=1 Then : Swap Listptemp2,Listptemp2_b : _Deallocate(Listptemp2_b) : End If : If IsPtSwp=1 Then : Swap Listptemp,Listptemp_b : _Deallocate(Listptemp_b) : End If     
  ' If pNode=pFirstNode Then : Print "Error  : pNode=pFirstNode  !! " : beep : sleep : End IF
 '  If this.HashTag<>str_testTMP Then : Print "Erreur sur " & this.HashTag & " <> " & str_testTMP : beep : sleep : End If ' Debug & tests
'  If bHashKeyUnique=0 Then : HadHashTag=0 : End If
    Return HadHashTag
End Property

Property List.HashTag As String
    Dim As ListNode Ptr pTemp01= this.pFirstNode, pTemp02=this.pNode
    If bTracking=1 And bTrackingMethod=0 Then : This.TrackCompute :  pTemp01 = this.pFirstNode : pTemp02 = this.pNode : End If     
    Str_tmp = this.Tag(uTag) ' this.pnode->Tag(uTag)
    If pTemp01->pPrev<>0  AndAlso pFirstNode->Tag(1)<>"" AndAlso ubKeysRegister=1 Then : KR_Count+=1 : Return pFirstNode->Tag(1) & pTemp02->Tag(0) : End If
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag(0)  + Str_tmp                 
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasHashTag(str_Tag As String) As Byte
    Dim As zString Ptr  zp1, zp2
    Dim pContextRetour As ListContext
    Dim HadHashTag As Byte=0 : Dim IsEtoile As Byte=0 : Dim i as uByte=1 : Dim t as uByte=Len(str_Tag) : Dim istep As uByte=this.bHashLen
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pFirstFIRSTNode :  'this.RootPrivate
    this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode   
    zp1=Listptemp+Len(str_Tag)+1 : (*zp1)[0]=0 : *Listptemp=str_Tag : zp1=Listptemp' * Alternative to Mid
    Do
        zp2=zp1 : zp1+=istep : (*zp3)[0]=(*zp1)[0] : (*zp1)[0]=0 : Str_tmp=*zp2 : (*zp1)[0]=(*zp3)[0] ' * Alternative to Mid : Str_tmp=Mid(str_Tag,i, istep)
        If this.HasTag(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            If this.pNode->Tag(1)="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf this.pNode->Tag(1)="!*" Then : HadHashTag=0 : i=t
            ElseIf this.pNode->Tag(1)="!" And i=t Then : HadHashTag=0
            ElseIf i>=t Then : HadHashTag=1
            Else :  HadHashTag=0 : End If   
        ElseIf IsEtoile=0 Then : HadHashTag=0 : i=t
        End If
        If i<t Then
            If this.pNode->pBranch=0 Then
                If bAutoCursor<3 Then : pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount : End If
                If bHashKeyUnique=1 Then : pNode=pNode->pNext : Return 1 : Else : If bHashStepRev=1 Then : Return this.KeyStepRev : Else : Return this.KeyStep :  End If  : End If                 
            Else : this.pFirstNode = this.pNode->pBranch : this.uCount = this.pFirstNode->BranchCount : this.pLastNode = this.pFirstNode->pBranchLastNode : this.pNode = this.pFirstNode
            End If : this.bSearchRes = 0
        End If
        i+=istep
    Loop Until i>t
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag(1)="" Then : HadHashTag=0 : Else : Return 1 : End If
        End If
    End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
    Return HadHashTag   
End Property

Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag(1)<>"" And pNode->Tag(1)<>LIST_DEL Then : Return 1 : Else : Return 0 : End If : Else : Return 0 : End If : End Property
Property List.BranchCount As uInteger : If this.pNode->pBranch<>0 Then : Return pNode->BranchCount : Else : Return 0 : End If : End Property ' Return this.pNode->BranchCount

Property List.NodeFlat As Byte 'Réallocation sélective dynamique multimodes rétro-récursive (virtuelle/reelle glissante 0/-n) de la structure de l'index en memoire virtuelle (Reduce) - Compatible HashStep, HashStepRev(?), KeyStep, KeyStepRev(?), fStep, TrackStep
    Dim As ListContext pContext, pContextRetour : Dim  As ListNode Ptr pTemp1, pTemp2, pTemp3, pTemp4, pTemp5, pTemp6, pTemp7 : Dim As uByte IsLastNode=0       
    this.NodeRecycle : NodeRecycle2 ': If pFirstNode->pPrev=0 And pNode->pNext=0 Then : Print "LZLE : NodeFlat attempted on last written node without previous Root = unsupported feature" : Return 0 : End If
    'Contrôle multimode en entrée + contrôle du Token de fin de liste + gestion continuité des ptr
    If pNode->Tag(0)=LIST_RES Or pNode->Tag(0)=LIST_DEL Or pNode=pWhyteMove Or pNode=pGarbage Then : Return 0
    ElseIf bTracking=1 Then
        If pFirstNode->pBranch=pFlatRoot Then : Return 0 : End If
        If bTrackingMethod=0 Then : this.TrackCompute : pLastNode->pNext=0 : End If : pTemp6=pNode->pBranchLastNode
    ElseIf pFirstNode->pPrev=0 And pNode->pNext=0 Then : pTemp1=pNode : this.AllOf : pNode=pTemp1
    End If : pTemp5=pFirstNode : pTemp2 = this.pNode : If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag(uTag) : End If : pLatestHTag=0
    'Gestion (swapping) des nodes parents                                                   ---------------------------------------------------------------------------
    If this.pNode->pBranch<>0  Then
        'Validation du mouvement mémoire : ' Fonctionnalité Tree List =>FlatList / ByPass Garbage ou 'Déjà swappé 
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag(1)=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag(0)=LIST_DEL Then : Return 0 : End If  ' PATCHED !!
        pTemp1=AllowCake : pTemp4=this.pFlatRoot->pBranch : If this.pNode->pPrev<>0 Then : this.pNode->pPrev->pNext=pTemp1 : End If
        If this.pNode->pNext->pPrev=this.pNode Then this.pNode->pNext->pPrev=pTemp1 : End If       
        pTemp1->pPrev=this.pNode->pPrev : pTemp1->pNext=this.pNode->pNext : pTemp1->pBranch=this.pNode->pBranch
        pTemp1->BranchCount=this.pNode->BranchCount : pTemp1->Tag(0)=this.pNode->Tag(0) : pTemp1->Tag(1)=LIST_DEL
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0 : this.pNode->Tag(0) = Str_tmp
        this.pNode->pPrev=pTemp4 : pTemp4->pNext->pPrev=this.pNode : this.pNode->pNext=pTemp4->pNext : pTemp4->pNext=this.pNode : this.pNode=pTemp1
    Else : this.uCount-=1 : pFirstNode->BranchCount-=1 :  If bBranchCountDown=1 Then : this.BCountDown(-1) : End If
    End If   
    'Gestion (/optimisation) du parsing (rétro-récursivité) ds le HashStep       ---------------------------------------------------------------------------       
    If pNode->pPrev<>pFirstNode Then
        If this.pNode->pNext->Tag(0)=LIST_DEL Then : This.pLastNode=this.pNode->pPrev : This.pFirstNode->pBranchLastNode=this.pNode->pPrev : End If
        If bHashStepRev=1 Then : pContextRetour.pNode=pNode->pNext : Else : pContextRetour.pNode=pNode->pPrev : End If
        pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount   
    Else
        pContext.pNode=This.pNode : pContext.pFirstNode=This.pFirstNode : pContext.pLastNode=This.pLastNode : pContext.uCount=This.uCount       
        If pNode=pLastNode Then : pTemp3=this.pFirstNode->pBranch->pPrev : Else : pTemp3=this.pFirstNode->pBranch : End If
        If pTemp3->Tag(0)=LIST_RES Then
            If pNode=pLastNode Then : this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : End If
            pTemp3=this.pFirstNode->pBranch
        End If
        this.pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount ' This.UpLevel         
        pContextRetour.pNode = pTemp3 : pContextRetour.pFirstNode = This.pFirstNode : pContextRetour.pLastNode = This.pLastNode : pContextRetour.uCount=This.uCount
        This.pNode=pContext.pNode : This.pFirstNode=pContext.pFirstNode : This.pLastNode=pContext.pLastNode : this.uCount=pContext.uCount                 
    End If
    If this.pNode->pNext=0 And this.pNode->pPrev->Tag(0)=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag(1)="" :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag(1)="" : pLocalRoot->Tag(0)=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag(0)=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag(1)="" :  pLocalRoot->Tag(0)=LIST_DEL
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
   ' pFirstNode->Tag(1)=""
  ' Swapping / MAJ des pointeurs - depend de IsLastNode                        --------------------------------------------------------------------------     
  ' Envoi d'un ancien node parent déjà swappé vers le garbage collector OU envoi d'un node non parent vers le GarbageCollector (si NFmethod=-1)
    If (pTemp2->Tag(1)=LIST_DEL Or this.bNFmethod=-1) And pTemp2->pBranch=0   Then ' And bNFmethod<>3
        If IsLastNode=0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : pTemp2->pPrev->pNext=pTemp2->pNext : End If
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag(0)=LIST_DEL : pTemp2->Tag(1)="" : uGarbCt+=1 : pTemp2->pBranchLastNode=0
        If pTemp2->ListData<>0 Then : pTemp2->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp2->ListData : pTemp2->ListData=0 : uContainerGarbCt+=1 : End If
        This.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
        If IsLastNode=0 And  bHashStepRev=1 Then : If this.Up=0 Then : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext  : End If : End If
        ElseIf IsLastNode=1 Then
            'If pTemp5->pPrev=0 Then : pTemp1=pNode : this.BlindTag(" ") : pNode->pNext=0 : pNode=pTemp1: return 0 : End If
            this.pNode=pTemp5->pBranch : this.uCount=pTemp5->pPrev->BranchCount : pLastNode=pTemp5->pPrev->pBranchLastNode : this.pFirstNode = pTemp5->pPrev           
            If bTracking=1 Or bPickReduce=1 Then : If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If : '  this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    Else ' Envoi vers la Flat list - Optimisation, à voir                                      --------------------------------------------------------------------------                 
        pFlatRoot->pBranch->BranchCount+=1         
        pNode=pFirstNode->pNext : this.UpLevel
        this.pFirstNode = this.pFirstFIRSTNode : this.pLastNode = this.pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
        this.pNode=this.pFlatRoot : this.Branch ' this.FlatStack
        If pFlatRoot->pBranch->BranchCount=0 Then : pFlatRoot->pBranch->BranchCount=1 : this.uCount=1 :  End If
        pTemp1 = this.pLastNode
        If IsLastNode=0 Then
            If pTemp2->pNext<>0 Then : pTemp2->pNext->pPrev=pTemp2->pPrev : End If
            If pTemp2->pPrev<>0 And pTemp2->Tag(0)<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            pTemp2->pPrev= this.pLastNode : pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->Tag(uTag) = Str_tmp : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            this.pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount     
            If bHashStepRev=1 Then : If this.Up=0 Then : this.BlindStep : End If : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If : Return 1 :  End If             
        Else
            pTemp1->pNext=pTemp2  : pTemp2->pNext=0 : this.pLastNode=pTemp2
            this.pFirstNode->pBranchLastNode = pTemp2  : pTemp2->Tag(uTag)=Str_tmp : pTemp2->pPrev=pTemp1  '
            this.pNode=pTemp5->pBranch : this.pFirstNode = pTemp5->pPrev : pLastNode=pTemp5->pPrev->pBranchLastNode : this.uCount=pTemp5->pPrev->BranchCount 
            If bTracking=1 Or bPickReduce=1 Then :  If pNode->Tag(1)="" Or pNode->Tag(1)=LIST_DEL  Then : this.NodeFlat : this.NodeRecycle2 : End If
            ElseIf bHashStepRev=1 Then : If this.Up=0 Then : this.Last : End If : this.NodeRecycle2 : If pNode=pNode->pNext <>0 Then : pNode=pNode->pNext : End If  : Return 1
            Else : If pFirstNode<>pFirstFIRSTNode Then : this.UpLevel : Else : pNode=pGarbage : End If  : this.NodeRecycle2 : Return 1 : End If ' this.NodeFlat : this.NodeRecycle2 ' RECURSIF
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL : Return 1 : End If
    Return 1
End Property

Property List.RestoreHash As Byte
    Dim As ListNode Ptr pTemp,  pTmpPrev, pTmpNext, pMove
    Dim str_tmp as string=this.Tag : Dim bTagExists As Byte : Dim uTagTmp As Byte=uTag
'    If pNode=pEndFlat then : this.Root : Return 0 : End If
    pTemp=this.pnode : str_tmp=this.Tag(uTag) : If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : Return 0 : End If
    'HashTagging
    uTag=0 : bRHByPass=1 : bTagExists=this.HashTag(str_tmp) : bRHByPass=0     
    If bHashKeyUnique=0 Then 'Multikeys=>1 seul mode possible car pas de conflit possible
        pTemp->Tag(0)= this.pnode->Tag(uTag)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
    ElseIf bTagExists=1 And pNode->Tag(1)<>""  Then ' tag deja existant et "vraie" clef
        'Gestion des modes (RHmethod)
        If bRHmethod=-1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
        ElseIf bRHmethod=1 Then : pTemp->Tag(0)= this.pnode->Tag(uTag)  : pMove=this.pnode : pMove->Tag(0)=str_tmp : bTagExists=2 ' swap
        Else : If pNode->Tag(1)=LIST_DEL Then : pNode->Tag(1)=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
        End If       
    Else : pTemp->Tag(0)= this.pnode->Tag(uTag) : pLocalMove=this.pnode : pLocalMove->Tag(0)=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext
  '  If bNFmethod<>3 Then : pTemp->pBranch=this.pnode->pBranch : End If  ' Deprecated : "flat" list is not designed to support a hierarchy - would be too complex to manage - use snatch instead
    this.pnode->pPrev->pNext=pTemp
    If this.pnode->pNext<>0 Then : If this.pnode->pNext->pPrev=this.pnode Then : this.pnode->pNext->pPrev=pTemp :  End If : End If
    If this.pnode=this.pLastNode Then : this.pLastNode=pTemp : End If : If this.pnode=this.pFirstNode Then : this.pFirstNode=pTemp : End If     
    If this.pnode->pBranch<>0 Then  '  pFirstNode->Tag(1)=""  '  pnode->pBranch->Tag(1)=""
        If this.pnode=this.pFirstNode->pBranchLastNode Then : this.pFirstNode->pBranchLastNode=pTemp : End If
        If this.pnode->pBranch->pBranch=this.pnode Then : this.pnode->pBranch->pBranch=pTemp : End If       
        pTemp->pBranch=this.pnode->pBranch : pTemp->pBranchLastNode=this.pnode->pBranchLastNode : pTemp->BranchCount=this.pnode->BranchCount
    End If
    'Reprise ds Flat List
    this.FlatStack(1)
    If bTagExists<>2 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL :
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext :
    End If
    Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - PROPERTIES PARAMETERS
Property List.AutoCursor(b As Byte) As Byte : If 0<=b<=3 Then : bAutoCursor=b : Return 1 : End If : Return 0 : End Property
Property List.BranchCountDown(i as Byte) As Byte
    If i<>0 And i<>1 Then : Print "BranchCountDown : invalid parameter" : Return 0 : ElseIf i=0 Or (i=1 And bColBcountLocked=0) Then : bBranchCountDown=i : bColBcountLocked=i : Return 1 : Else : Print "Branch count vector already booked" : Return 0 : End If
End Property
Property List.CopyCatMethod(i As Byte) As Byte : If i=0 Or i=1 Then : bCopyCatMethod=i : Return 1 : Else : Print "CopyCatMethod : invalid parameter" : Return 0 : End If : End Property
Property List.HashKeyUnique(ub as Byte) As Byte : If ub=0 Or ub=1 Then : bHashKeyUnique=ub : bSeekMethod=ub : Return 1 : Else : Print "HashKeyUnique : invalid parameter" :  Return 0 : End If : End Property
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>0 And bHashLen<255 Then : this.bHashLen = bHashLen : Return 1 : Else : Print "HashLen : invalid parameter" :  Return 0 : End If : End Property
Property List.KeysRegister(ub As uByte) As Byte :  If ub=0 Or ub=1 Then : ubKeysRegister=ub : Return 1 : Else : Print "KeysRegister : invalid parameter" :  Return 0 : End If : End Property
Property List.NFmethod(i As Byte) As Byte : If i=-1 Or i=0 Or i=1 Then : this.bNFmethod=i : Return 1 : Else : Print "NFmethod : invalid parameter" : Return 0 : End If : End Property
Property List.NFrecursive(i As Byte) As Byte : If i=1 Then : this.bPickReduce=1 : Else : this.bPickReduce=0 : End If : Return 1 : End Property
Property List.PVSmethod(ub As Byte) As Byte :
    If ub=-1 Then : bPVSmethod=ub : Return 1
    ElseIf bColBcountLocked=0 and ub<2 Then : bPVSmethod=ub : bColBcountLocked=1 : Return 1
    Else : Print "PVSmethod : Branch count vector already booked or invalid parameter" : Beep : sleep : Return 0 : End If
End Property
Property List.PVSratio(ub As uByte) As Byte : If ub>1 Then : PVS_ratio=ub : Return 1 : Else : Return 0 : End If : End Property
Property List.RHmethod(i As Byte) As Byte : If -2<i<2 Then : this.bRHmethod=i : Return 1 : Else : this.bRHmethod=-1 : Return 0 : End If : End Property
Property List.SeekMethod(i as Byte) As Byte : If i=0 Or i=1 Or i=2 Then : this.bSeekMethod=i : Return 1 : Else : Return 0 : End If : End Property
Property List.SnatchBLmethod(i As Byte) As Byte : If i=0 Or i=1 Then : bSnatchBLMethod=i : Return 1 : Else : Print "SnatchBeMethod : invalid parameter" : Return 0 : End If : End Property
Property List.TrackMethod(by As Byte) As Byte : If by=0 Or by=1 Then : bTrackingMethod=by : Return 1 : Else : Return 0 : End If: End Property
Property List.TrackMultiKeys(uB as uByte) As Byte : If -1<=uB<=MAX_COLS Then : bTrackMultiKeys=uB : Return 1 : End If : Return 0 : End Property
Property List.VectorUnlock As Byte : bColBcountLocked=0 : bColTrackLocked=0 : Return 1 : End Property
Property List.VectorClear As Byte
    Dim As ListNode Ptr Ptemp1=pNode, pTemp2 : Dim As Byte IsUp=0
    pTemp2=pTemp1->pNext
    If pTemp2=0 Or pNode->Tag(0)=LIST_RES  Or pNode->Tag(0)=LIST_DEL Then : Return 0 : End If
    If bColBcountLocked=1 Or bPVSmethod=1 Then : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag(1)="" : End If : Wend
    End If : pNode=pTemp1 : Return 1
End Property

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - FLOW CONTROL
Property List.Up As Byte : If pFirstNode=pFirstFIRSTnode Then : Return 0 : Else :  this.UpLevel : Return 1: End If : End Property
Property List.Down As Byte
    If pnode->pBranch=0 Or pNode->Tag(0)=LIST_RES Then  : Return 0 : End If
    If pnode->pBranch->pPrev<>pFirstNode Then : Return 0 :
    Else : pFirstNode->BranchCount=uCount : pFirstNode->pBranchLastNode=pLastNode : pFirstNode=pNode->pBranch : uCount=pFirstNode->BranchCount : pLastNode=pNode->pBranch->pBranchLastNode : pNode=pNode->pBranch : Return 1
    End If
End Property
Property List.HoldBack As Byte : Return this.HoldBack(0) : End Property
Property List.HoldBack(by As Byte) As Byte   
    If pNode->Tag(0)=LIST_RES Or bColTrackLocked=1 Then : Return 0
    ElseIf TrackTrace(by)<>0 Then : TrackTrace(by)->pBranchLastNode=pNode : TrackTrace(by)=this.pNode : Return 1
    Else : this.TrackSet(by) : pNode->pBranchLastNode=0 : TrackTrace(by)=pNode : Return 1
    End If
End Property
Property List.TrackStep As Byte
    Dim As ListNode Ptr pTemp1 : bAlrdyTracked=0
    If pNode->pBranchLastNode->Tag(0)=LIST_DEL Or bColTrackLocked=1 Then : this.Root : bTracking=0 : Return 0 : End If ' Or pNode->pBranchLastNode->Tag(0)=LIST_RES
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag(0)<>LIST_RES Then           
        pNode=pNode->pBranchLastNode : bTracking=1
        If bTrackingMethod=1 Then : this.TrackCompute ': pLastNode->pNext=0
        End If : Return 1
    End If : this.TrackCompute : bTracking=0 : Return 0
End Property
Property List.Track As Byte : Return this.Track(0) : End Property
Property List.Track(by As Byte) As Byte
    this.Root : If bColTrackLocked=1 Then : Print "Tracking vector already in use (internal) by CopyCat/Follow" & chr(10) & "Use HashStep or other iterator" & chr(10) & "Attempt to use incompatible vectors may lead to crash" : Return 0 : End If : bAlrdyTracked=0
    If pNode->Tag(0)<>LIST_DEL And pNode->Tag(0)<>LIST_RES And pNode<>pLocalMove Then : This.TrackCompute : End If : bTracking=1 : this.Root ': This.TrackMethod(1)
    If this.Tracks(by).pNode=0 Then : this.TrackSet(by)  : Return 0
    Else
        pFirstNode->BranchCount=this.uCount : pFirstNode->pBranchLastNode=pLastNode : this.NodeRecycle : pNode=AllowCake : pLocalMove=pNode : pLocalMove->Tag(0)=LIST_DEL
        If this.Tracks(by).pNode->Tag(0)=LIST_DEL Then : pNode->pBranchLastNode=this.Tracks(by).pNode->pBranchLastNode
        Else : pNode->pBranchLastNode=this.Tracks(by).pNode
        End If
        pFirstNode=this.Tracks(by).pFirstNode : pLastNode=pFirstNode->pBranchLastNode : bHashLen=this.Tracks(by).bLcHashLen
        pNode->pBranch=0 : pNode->pPrev=0 : pNode->Tag(0)=""
        Return 1
    End If
End Property
Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte
    this.NodeRecycle : If pNode->pBranchLastNode<>0 Then : this.Tracks(by).pNode=pNode->pBranchLastNode  : Else : this.Tracks(by).pNode=pNode : End If
    this.Tracks(by).pFirstNode=pFirstNode : this.Tracks(by).bLcHashLen=bHashLen : TrackTrace(by)=0 : Return 1
End Property
Property List.TrackClear As Byte : Return this.TrackClear(0) : End Property
Property List.TrackClear(by As Byte) As Byte : TrackTrace(by)=0 : Return 1  : End Property
Property List.IsTracked As Byte : Dim i As Byte : If pNode->pBranchLastNode<>0 And pNode->Tag(0)<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS-1 : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : End Property

Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    Lcontext(by).pNode=pNode : Lcontext(by).pFirstNode=pFirstNode : Lcontext(by).pLastNode=pLastNode : Lcontext(by).uCount=this.uCount : Lcontext(by).LcHashTag=pNode->Tag(0) : Lcontext(by).bLcHashLen=this.bHashLen
    Return 1
End Property
Property List.Recover As Byte : Return this.Recover(1) : End Property
Property List.Recover(by As Byte) As Byte
    If by > MAX_COLS-1 Or By < 1 Then : Return 0 : End If : If bTrackingMethod=1 Then : This.TrackCompute : End If
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode
    pNode=Lcontext(by).pNode : pFirstNode=Lcontext(by).pFirstNode : this.bHashLen=Lcontext(by).bLcHashLen
    pLastNode=pFirstNode->pBranchLastNode : this.uCount= this.pFirstNode->BranchCount : this.bHashLen=Lcontext(by).bLcHashLen
    Return 1
End Property
Property List.Follow(pList As List) As Byte
    Dim As ListNode Ptr pTemp1=pList.Relation : bAlrdyTracked=0
    this.pFirstNode->BranchCount = this.uCount : this.pFirstNode->pBranchLastNode = this.pLastNode : bTracking=1
    If pTemp1<>0 Then : this.pNode=pTemp1 : Else : Return 0 : End If
    this.pLastNode=pFirstNode->pBranchLastNode : this.uCount=this.pFirstNode->BranchCount
    Return 1
End Property

'==========================================================================================MEMORY MANAGEMENT
Property List.FlatCount As uInteger : Return this.pFlatRoot->pBranch->BranchCount : End Property
Property List.GarbageCount As uInteger : Return this.uGarbCt : End Property
Property List.ContainerCount As uInteger : Return this.uContainerGarbCt : End Property
Property List.NodeCount As uInteger : Return this.uNodeCOUNT : End Property

Property List.GarbageFlat As Byte
    Dim L_Context As ListContext : Dim As ListNode Ptr pTemp1, pTemp2, pTemp3 : Dim i as Byte
    If pFlatRoot->pBranch=0 Then : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then : pLocalMove=pFlatRoot->pBranch : pLocalMove->pBranch=0 : pLocalMove->Tag(1)="" : pLocalMove->Tag(0)=LIST_DEL : this.NodeRecycle : Return 0 : End If
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch->pBranchLastNode Then : Return 0 : End If
    pTemp1=pFlatRoot->pBranch->pNext : pTemp2=pEndFlat->pPrev
    If pTemp2=0 Then
        L_Context.pNode=pNode : L_Context.pFirstNode=pFirstNode : L_Context.pLastNode=pLastNode : L_Context.uCount=this.uCount
        this.FlatStack : pTemp2=pEndFlat->pPrev
        pNode=L_Context.pNode : pFirstNode=L_Context.pFirstNode : pLastNode=L_Context.pLastNode : this.uCount=L_Context.uCount
    End If :  If pTemp1=pTemp2 Then : Return 0 : End If
    pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pNext=pFlatRoot->pNext
    pFlatRoot->pNext=pTemp1 : pTemp1->pPrev=pFlatRoot
    Do
        pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then : pTemp1->ListData->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pTemp1->ListData : pTemp1->ListData=0 : uContainerGarbCt+=1 : End If
        pNode=pTemp3
        pTemp1=pTemp1->pNext
    Loop Until pTemp1=pTemp2
    pTemp1->Tag(0)=LIST_DEL : For i=1 to RUP_COLS : pTemp1->Tag(i)="" : Next i : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ': pTemp1->ListData.sData=""
    pTemp3=pNode : pNode=pTemp1 : this.Val("") : pNode=pTemp3
    uGarbCt+=pFlatRoot->pBranch->BranchCount
    pFlatRoot->pBranch->pNext=pFlatRoot->pBranchLastNode : pFlatRoot->pBranchLastNode->pPrev=pFlatRoot->pBranch : pFlatRoot->pBranch->BranchCount=0
    If pFirstNode=pFlatRoot->pBranch Then : uCount=0 : this.RootPrivate : End If
    Return 1
End Property

Property List.Recycle As uInteger : Dim As ListNode Ptr pTemp=pNode : this.BlindTag(" ") : pNode=pTemp : this.Up : this.Root : this.AllOf :  Return this.AllRecycle : End Property  '

Property List.DropAll As uInteger  'pRoot principal + pFlatRoot + pFlatRoot->pBranch + pGarbage + pLastLAST/pWhyte = 5 nodes déalloues ds destructor     
    If this.IsDestroyed=1 Then : Return 0 : End If : this.NodeRecycle : this.NodeRecycle2
    Dim As ListNode Ptr pTemp=pNode : this.BlindTag(" ") : pNode=pTemp : this.Up : this.Root : this.GarbageFlat :  this.AllOf : this.AllRecycle : this.NodeRecycle : this.NodeRecycle2
    pTemp=pFlatRoot->pNext  : Dim iLong As uInteger=0   
    While pTemp<>pGarbage And pTemp<>0 And pTemp<>pFlatRoot
        If pFlatRoot->pNext->ListData<>0 Then : _Deallocate(pFlatRoot->pNext->ListData) : End If
        _Deallocate(AllowCake) : pTemp=pFlatRoot->pNext : this.uNodeCOUNT-=1 : iLong+=1
    Wend   
    Dim pPanTemp As ListContainer Ptr =pPanCakeGarbage->pNextContainer : Dim SeekMt As Byte=this.bSeekMethod
    While pPanTemp<>pPanCakeGarbage : _Deallocate(AllowPanCake) : pPanTemp=pPanCakeGarbage->pNextContainer : Wend  ' pPanCakeGarbage->pNextContainer=pPanCakeGarbage           
    this.bSeekMethod=SeekMt : uCount=0 : this.pFirstNode->BranchCount=0   
    If pFlatRoot->pBranch->pNext=pFlatRoot->pBranch Then :  _Deallocate(pFlatRoot->pBranch) : pFlatRoot->pBranch=0 : this.uNodeCOUNT-=1 : iLong+=1 : End If
    this.AllOfPrivate
    Return iLong   
End Property
Post Reply