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 - BETA 0.994 -

Post by Lost Zergling »

Archive Beta 0.994 Part 3/3
Latest release is here viewtopic.php?f=8&t=26533

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.995b -6/04/20

Post by Lost Zergling »

Archive Beta 0.995b Part 1/3
Latest release is here viewtopic.php?f=8&t=26533

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

/' BUGs, taf
    cf restauration contexte hashlen ds tracking et aside, IsKey, MeKey
   'BugsFix : ColSort ???=>ok? | SeekMet 2=>ok? | RestoreHash=>not sorted%HashSort(1)=>Ok? | SortLeaks/Tag(n)=>Ok? | HashTag&Tag(uTag)=>Ok?
'/
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 MIN_COLS=1 : CONST MAX_COLS=6 : CONST MAX_TAGLEN=15 : CONST MAX_VALLEN=50  : CONST MAX_KEYLEN=40 : CONST MAX_HASHLEN=2
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4) : CONST MAX_TRACKS=20 ' MAX_TRACKS = all tracks are on a same single track cros-tracking not managed

Type ListContainer 'Data Segment Level   
    Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN
  '  Dim str_tag_C(MIN_COLS to MAX_COLS) As String '  For unknown max len for Tag(1) to Tag(n),  uncomment this line & comment line above (consumes memory)
    Dim as zString*MAX_VALLEN str_item
 '  Dim As String str_item ' For unknown max len for str_item(.Val Property) ), uncomment this line & comment line above
    Dim as zString*MAX_KEYLEN str_flat_tag
 '  Dim As String str_flat_tag  ' For unknown max len for str_flat_tag (NodeFlat + NFMethod<>-1 on long keys), uncomment this line & comment line above
    Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag0 As zString*(MAX_HASHLEN+1)
    Dim Tag1 As zString*2 '  Whenever you may need to manage inside a tree manually and transparently as a flat list not knowing max hash len, use string instead of zString & set uB_IsTree=1 for full ascending comp. (consumes lot of memory, can generates low level leaks)
    Dim As ListContainer Ptr ListData : Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode
    Dim BranchCount As uInteger=0 ': Dim As uByte bNFflag ', IsKey
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), Tracks(0 to MAX_COLS)
    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
    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, uB_CurLevel=1, uB_Level=1, uB_KeyStepCumul=1, uB_MaxLevel=1, uB_BottomLevel=255, uB_BottomByPass=0, uB_tmp, uB_IsTree=0 ', nbloops=0 ubKeysRegister=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 As Byte
    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   ' 1/2 DEPRECATED (Dynamic=>Static) !! - Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' DEPRECATED !! - 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->Tag0 = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag0=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 : pTemp->Tag1="" ': pTemp->IsKey=0 :
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="" : pPanTemp->str_flat_tag="" : For uB=MIN_COLS To MAX_COLS : 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->Tag0<>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
            Else 'ListData->str_flat_tag
                If this.pNode->pNext<>0 Then
                    pNode->Tag0 = LIST_DEL : pNode->BranchCount=0 : NbCollected +=1 ':  pNode->pBranchLastNode=0 ': iLong+=1  For ub1=1 To RUP_COLS : pNode->Tag1(ub1)="" : Next ub1 :
                    If pNode->ListData<>0 Then
                        For ub1=MIN_COLS To MAX_COLS : pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        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->Tag0 = 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->Tag0 = LIST_RES  ' 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->Tag1="" : 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->Tag0=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 : bfStepZero=0
    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->Tag0<>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->Tag0=LIST_RES Or pNode->Tag0=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag0="" Then : Return 0
    ElseIf pNode->pBranch->Tag0<>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->Tag0=LIST_RES Or pNode->Tag0=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 : If pLocalRoot->ListData<>0 Then : pLocalRoot->ListData->str_tag_C(1)="" : End If
        pLocalRoot->Tag0=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 : If pLocalRoot->ListData<>0 Then : pLocalRoot->ListData->str_tag_C(1)="" : End If
            pLocalRoot->Tag0=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->Tag0=LIST_DEL Then : this.FlatStack(0) : End If
    If pFirstNode->pNext->Tag0=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
    If this.HasTag(str_Tag) Then : this.pNode = this.pSearchNode : uB_tmp=1
    Else
        pNode = this.pLastNode : this.uCount+=1 : pNode->pNext = this.AllowCake 'And eat it
        pNode->pNext->pPrev = pNode : pNode->pNext->Tag0 = str_Tag  : uB_tmp=0
        pNode = pNode->pNext : this.pLastNode = pNode : 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
    End If       
    If  (uTag=0 And uB_IsTree=1) Or str_Tag=""  Then
    ElseIf this.uB_tmp=0 Then
        If pNode->ListData=0 Then : pNode->ListData=AllowPanCake : End If
        If uTag=0 Then : pNode->ListData->str_flat_tag = str_Tag : Else : pNode->ListData->str_tag_C(uTag) = str_Tag : End If       
    End If
    Return uB_tmp
End Property

Property List.Tag As String : Return This.Tag(uTag) : End Property
Property List.Tag(i As Integer) As String ' La propriété devient multicontextuelle (flat & tree) suite chgt implémentation
    If i=0 And uB_IsTree=1 Then : Return this.pNode->Tag0 ' : Else : Return this.pNode->Tag1 : End If
    ElseIf pNode->ListData=0 Then : Return this.pNode->Tag0  ' Tree context mandatory
    ElseIf i=0 Then :  If pNode->ListData->str_flat_tag="" Then : Return this.pNode->Tag0 : Else : Return pNode->ListData->str_flat_tag : End If    '
    Else : Return pNode->ListData->str_tag_C(i)
    End If
End Property

Property List.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag
    If uTag=0 And uB_IsTree=1 Then
        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->Tag0 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
        ElseIf this.bSeekMethod=2 Then
            pTemp = this.pLastNode
            While (pTemp->pPrev <> 0 And pTemp->Tag0 <> 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->Tag0 <> str_Tag AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
        End If   
        If pTemp->Tag0 = 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   
    Else
        If this.bSeekMethod=1 Then
            uB_tmp=0 : pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If           
            'While (pTemp->pNext <> 0 And pTemp->Tag1 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
            If uTag=0 Then
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : Else : If pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode)
                    pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
                Wend
            Else
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext :  If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            End If     
        ElseIf this.bSeekMethod=2 Then
            pTemp = this.pLastNode
        '    While (pTemp->pPrev <> 0 And pTemp->Tag1 <> str_Tag  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : Wend
            If uTag=0 Then
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : Else : If pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage )
                    pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
                Wend
            Else
                uB_tmp=0 : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            End If   
        Else
            pTemp = this.pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If
           ' While (pTemp->pNext <> 0  And pTemp->Tag1 <> str_Tag AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
            If uTag=0 Then :
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : Else : If pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode )
                    pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
                Wend
            Else
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            End If     
        End If   
        If uB_tmp=1  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 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 :
    If uTag=0 And uB_IsTree=1 Then : pTemp->pNext->Tag0 = str_Tag
    Else :
        pTemp->pNext->Tag0=str_Tag
        If pTemp->pNext->ListData=0 Then : pTemp->pNext->ListData=AllowPanCake() : End If :
        If uTag=0 Then : pTemp->pNext->ListData->str_flat_tag=str_Tag : Else : pTemp->pNext->ListData->str_tag_C(uTag)=str_Tag : End If
    End If
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Last edited by Lost Zergling on Apr 20, 2020 21:22, 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.995b -6/04/20

Post by Lost Zergling »

Archive Beta 0.995b Part 2/3
Latest release is here viewtopic.php?f=8&t=26533

Code: Select all


Property List.RwTag(s_Tag As String) As Byte
   ' If uTag=0 Then : this.pNode->Tag0=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
    If uTag=0  Then
        If uB_IsTree=1 Then : this.pNode->Tag0=s_Tag : Return 1 : End If
        If pNode->ListData=0 Then : this.pNode->ListData=AllowPanCake() : End If : pNode->ListData->str_flat_tag=s_Tag : Return 1
    Else : If pNode->ListData=0 Then : this.pNode->ListData=AllowPanCake() : 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->Tag0=s_Tag : Return 1 : End Property
Property List.RwTag0(s_Tag As String) As Byte : uB_tmp=uTag : uTag=0 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property
Property List.RwTag1(s_Tag As String) As Byte : uB_tmp=uTag : uTag=1 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property 'Property List.RwTag1(s_Tag As String) As Byte : this.pNode->Tag1=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 then : this.uTag=MAX_COLS : 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(uTag) 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 ' Or pNode->pNext=pEndFlat
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->Tag0=LIST_DEL Or pNode->Tag0=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

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS then : this.uTag=MAX_COLS : 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 : Dim As uByte tmpIsTree=this.uB_IsTree : this.uB_IsTree=0 ' If this.uSortTag=0 Then : this.uB_IsTree=1 : End If
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If
    'Trie+Insert Sort - non recursive   
    gCollector.SetRelation(1) : gCollector.HashKeyUnique(1) : gCollector.HashSort(1) : gCollector.fSortMethod(this.bSortMT) : gCollector.HashLen(1) : gCollector.GarbageSnatch(this) ': gCollector.HashSort(0)
    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
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : : End If  ' gCollector.SeekMethod(1) :
        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
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : End If  ' gCollector.SeekMethod(1) :
        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) :  this.uB_IsTree=tmpIsTree
    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 : Dim as Byte bHashSort=this.bSortMT : this.bSortMT=0
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If  : this.HashSort(0) :
    this.Root : this.fSort :  this.Root : 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 : bSortMT=bHashSort
    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->Tag0<>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 "LZLE error - List.Root : Error List destroyed : instance can't be re-used" : Sleep : Return 0 : End If
    this.RootPrivate : If pLocalMove<>0 Then : If pLocalMove->ListData<>0 Then : pLocalMove->ListData->str_tag_C(1)="" : End If : pLocalMove->pBranch=0 :  pLocalMove->Tag0=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->Tag0=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag0<>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->Tag0<>"" 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->Tag0=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.NodeRecycle : this.pNode=AllowCake : pNode->Tag0="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext :  If pLocalMove->ListData<>0 Then : pLocalMove->ListData->str_tag_C(1)="" : End If  : pLocalMove->pBranch=0 :  pLocalMove->Tag0=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 : bfStepZero=0
    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->Tag1<>"" And pNode->Tag1<>LIST_DEL Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag1<>"" And pNode->Tag1<>LIST_DEL Then : Return 1 : End If : Wend : End Property

'Numeric parse optimization
Property List.nCurLevel As Byte : Return uB_CurLevel  : End Property
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->Tag1<>"" And pNode->Tag1<>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->Tag1<>"" And pNode->Tag1<>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 : Str_tmp=this.HashTag ' If pFirstNode->Tag1<>"" Then : Str_tmp=pFirstNode->Tag1 & pNode->Tag0 : Else : Str_tmp=this.HashTag  : End If ': If ubKeysRegister=1 Then : pFirstNode->Tag1=Left(Str_tmp, Len(Str_tmp)-istep) : 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
         '   If uTag=0 Then : iLenpNode=Len(pNode->Tag0) : Else : iLenpNode=Len(pNode->Tag1) : End If 'iLenpNode=iLen :
            If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  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
               ' Str_tmp=this.HashTag ' If pFirstNode->Tag1<>"" Then : Str_tmp=pFirstNode->Tag1 & pNode->Tag0 : Else : ': If ubKeysRegister=1 Then : pFirstNode->Tag1=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
              '  If uTag=0 Then : iLenpNode=Len(pNode->Tag0) : Else : iLenpNode=Len(pNode->Tag1) : End If 'iLenpNode=iLen :
                If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  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   
 '  If pFirstNode=pFirstFIRSTNode Then : pTemp02=pGarbage : Else : pTemp02=pFirstNode : 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 uTag=0 Then
                If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else : pTemp = pTemp02 : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                End If
            Else : uB_tmp=0
                If bSeekMethod_TMP=2 Then
                    pTemp = this.pLastNode
                    'While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                    While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                Else
                    pTemp = pTemp02
                    'While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                    If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                    While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                End If
            End If
        Else : uB_tmp=0
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                If uSortTag=0 Then : While ( pTemp->Tag0>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else
                  '  While ( pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  Then : uB_tmp=1 : End If : End If
                    While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                End If
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else
                If uSortTag=0 Then : pTemp=pTemp02 : While (pTemp->Tag0<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->Tag0<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                Else
                    pTemp=pTemp02
                    'While (pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  Then : uB_tmp=1 : End If : End If
                    While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                End If
            End If
        End If
        If uTag=0 Then : Str_tmp2=pTemp- >Tag0 : Else : Str_tmp2=pTemp- >Tag1 : End If
      '  ? "bHashKeyUnique=" & bHashKeyUnique & "Str_tmp=" & Str_tmp & "Str_tmp2=" & Str_tmp2 : sleep
        If Str_tmp2=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp ': Print "??" & Str_tmp  'bHashKeyUnique
        ElseIf Str_tmp2=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
            If uTag=0 Then : pTemp03->Tag0 = Str_tmp : Else : pTemp03->Tag1 = Str_tmp : End If
            HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If Str_tmp2=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 : If uTag=0 Then : pTemp03->pNext->Tag0 = Str_tmp : Else : pTemp03->pNext->Tag1 = Str_tmp : End If
            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 Str_tmp2=Str_tmp Then : this.HoldBack(bTrackMultiKeys) : End If ' If pNode->pNext<>0 Then : If pNode->pNext->pBranchLastNode=0 Then : pNode=pNode->pNext : this.HoldBack(bTrackMultiKeys) : pNode=pTemp03 : End If : End If :
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system               If bSeekMethod_TMP=2 Then : Print "Pt 9" : sleep :  End If
        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 : If uTag=0 Then : pTemp03->pNext->Tag0 = LIST_RES : Else : pTemp03->pNext->Tag1 = LIST_RES : End If ' pTemp03->pNext- >Tag0 = 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->Tag1=Left(str_testTMP, iLenCumul+iLenDelta) : Print "*Tag1=" & Left(str_testTMP, iLenCumul+iLenDelta)  : sleep : 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 : str_Tag=str_testTMP
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag1="" Then :  If HadHashTag=1 Then : HadHashTag=2 : End If : If bRHByPass=0 Then : this.pNode->Tag1=" " : End If : 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     
    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->Tag0 ' this.Tag(uTag) ' this.pnode->Tag(uTag)
    If pFirstNode->pBranch<>pFlatRoot Then : Str_tmp = this.pnode->Tag0 'si pas ds contexte flat root on prends la clef Tag0
    Else : Str_tmp = this.pnode->ListData->str_flat_tag  : End If
  '  If this.pnode->ListData<>0 Then : If pnode->ListData->str_flat_tag<>"" Then :  this.pnode->ListData->str_flat_tag : Else : Str_tmp = this.pnode->Tag0 : End If : Else : Str_tmp = this.pnode->Tag0 : End If 'ko
  '  If pTemp01->pPrev<>0  AndAlso pFirstNode->Tag1<>"" AndAlso ubKeysRegister=1 Then : KR_Count+=1 : Return pFirstNode->Tag1 & pTemp02->Tag0 : End If 'deprecated
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag0  + 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 : uB_tmp=uB_IsTree : uB_IsTree=1
    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 pNode->ListData<>0 Then : str_testTMP=this.pNode->ListData->str_tag_C(1) : Else : str_testTMP="" :  End If
            If str_testTMP="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf str_testTMP="!*" Then : HadHashTag=0 : i=t
            ElseIf str_testTMP="!" 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 : uB_IsTree=uB_tmp : pNode=pNode->pNext : Return 1 : Else : uB_IsTree=uB_tmp : 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 : uB_IsTree=uB_tmp
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag1="" 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

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

Re: LZLE List Engine with user friendly powerfull syntax - BETA 0.995b -6/04/20

Post by Lost Zergling »

Archive Beta 0.995b Part 3/3
Latest release is here viewtopic.php?f=8&t=26533

Code: Select all


Property List.HasKey(str_Tag As String) As Byte : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag1<>"" And pNode->Tag1<>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->Tag0=LIST_RES Or pNode->Tag0=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 : Str_tmp=this.HashTag : pLatestHTag=0  ' If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag1 : 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é  bNFflag
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag1=LIST_DEL Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag0=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->Tag0=this.pNode->Tag0 : pTemp1->Tag1=LIST_DEL ' ->Tag1=LIST_DEL
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0
        If this.pNode->ListData=0 Then : this.pNode->ListData=this.AllowPanCake : End If : this.pNode->ListData->str_flat_tag = Str_tmp  '  : this.pNode->Tag0 = 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->Tag0=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->Tag0=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->Tag0=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag1="" :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag1="" : pLocalRoot->Tag0=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag0=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag1="" :  pLocalRoot->Tag0=LIST_DEL
        Else : this.pLastNode=this.pNode->pPrev : pFirstNode->pBranchLastNode=pLastNode : IsLastNode=1
        End If
    End If
   ' pFirstNode->Tag1=""
  ' 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->Tag1=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
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag0=LIST_DEL : pTemp2->Tag1="" : 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->Tag1="" Or pNode->Tag1=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If ' RECURSIF
            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
        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->Tag0<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pTemp2->ListData->str_flat_tag = Str_tmp ' : pTemp2->pPrev= this.pLastNode :
            pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode=pTemp2 : 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
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pTemp2->ListData->str_flat_tag = Str_tmp
            pTemp1->pNext=pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            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->Tag1="" Or pNode->Tag1=LIST_DEL Then : this.NodeFlat : this.NodeRecycle2 : End If  ' RECURSIF
            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
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag0=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 : Dim bTagExists As Byte : Dim As Byte uTagTmp=uTag, IsLastOne=0
    If this.pNode->ListData=0 Then : Return 0 : End If ' If pNode=pLocalMove Then : Return 0 : Else  Print "LZLE : RestoreHash : failure or non-value" :
    pTemp=this.pnode : If uTag=0 Then : str_tmp=this.pNode->ListData->str_flat_tag : Else :  str_tmp=this.pNode->ListData->str_tag_C(uTag) : End If : If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    If pNode->pNext=pEndFlat And pNode->pPrev=pFirstNode Then : IsLastOne=1 : End If
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : this.Up : 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
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0  : Else : pTemp->Tag0= this.pnode->Tag1  : End If
        pMove=this.pnode : pMove->ListData->str_flat_tag=str_tmp : bTagExists=3 ' swap
    ElseIf bTagExists<>0 And pNode->Tag1<>""  Then ' tag deja existant et "vraie" clef
        'Gestion des modes (RHmethod)
        If uTag=0 Then
            If bRHmethod=-1 Then : pTemp->Tag0= this.pnode->Tag0 : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= this.pnode->Tag0  : pMove=this.pnode : pMove->ListData->str_flat_tag=str_tmp : bTagExists=2 ' swap
            Else : If pNode->Tag1=LIST_DEL Then : pNode->Tag1=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        Else
            If bRHmethod=-1 Then : pTemp->Tag0= this.pnode->Tag1  : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= this.pnode->Tag1  : pMove=this.pnode : pMove->ListData->str_flat_tag=str_tmp : bTagExists=2 ' swap
            Else : If pNode->Tag1=LIST_DEL Then : pNode->Tag1=" " : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        End If
    Else
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0 : Else : pTemp->Tag0=this.pnode->Tag1 : End If
        pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pNode->Tag1=pTemp->Tag1
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext  : pTemp->ListData->str_flat_tag=""
  '  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->Tag1=""  '  pnode->pBranch->Tag1=""
        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<>3 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag1="" : pLocalMove->Tag0=LIST_DEL :
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext :
    End If : If IsLastOne=1 Then : this.Up : bfStepZero=1 : pNode=pLastNode : 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 'DEPRECATED
Property List.HashLen(bHashLen As uByte) As Byte : If bHashLen>MAX_HASHLEN Then : Print "LZLE warning : HashLen Property ignored (deprecated), or must be =< MAX_HASHLEN (constant)" : End If : this.bHashLen=1 : Return 1 : 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.KeysRegister(ub As uByte) As Byte : Print "LZLE warning : KeysRegister Property ignored (deprecated)" :  Return 0 : 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+1 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->Tag0=LIST_RES  Or pNode->Tag0=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->Tag1="" : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag1="" : 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->Tag0=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->Tag0=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->Tag0=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->Tag0<>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->Tag0<>LIST_DEL And pNode->Tag0<>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->Tag0=LIST_DEL
        If this.Tracks(by).pNode->Tag0=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->Tag0=""
        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->Tag0<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS : 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 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->Tag0 : 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 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->Tag1="" : pLocalMove->Tag0=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->Tag0=LIST_DEL : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0 ' : pTemp1->ListData.sData=""  For i=1 to RUP_COLS : pTemp1->Tag1(i)="" : Next i :
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then
            For i=MIN_COLS To MAX_COLS : pTemp1->ListData->str_tag_C(i)="" : Next i
            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->Tag0=LIST_DEL : If pTemp1->ListData<>0 Then : For i=MIN_COLS to MAX_COLS :  pTemp1->ListData->str_tag_C(i)="" : Next i  : End If
    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

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->Tag0=LIST_RES Or pNode->Tag0=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->Tag1="" : pLocalMove->Tag0=LIST_DEL
            If this.Snatch(pList) <> 1 Then : this.NodeRecycle : pLocalMove=pFirstNode : pFirstNode->pBranch->pBranch=0 : pFirstNode->pBranch=0 :  pLocalMove->Tag1="" : pLocalMove->Tag0=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->Tag1="" : pLocalMove->Tag0=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->Tag0=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If
    ElseIf pNode->Tag0=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 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

Archive :

New version Beta 0.993 : (06/2019)
What's new ?
- Dim Shared gCollector As List : Centralization of nodes / memory addresses to recycle (*)
- Several small bugs fixes (kinematic of keywords leading to a crash)(rare).
- Sort feature optimised and using gCollector (sorting nodes in memory) (*).
- New Parsers : nKeyStep & nKeyStepRev : parsing a TRI (retrieve) (cascaded string order) in numeric order (*).
(*)=> will be used especially by array extensions

New version Beta 0.994 : (07/2019)
New features
- Few bug fixes in kinematics (snatch)
- RestoreHash and HasKey now supports Multi-keys features :
can restore a multi key index from flat list, can parse MultiKey tree using while MyList.HasKey("key")
- NodeFlat can target last created entry in tree without having to Root : MyList.HashTag("LastKey") : MyList.NodeFlat does not crash
- Minimum requirements for LZAE (array extensions). Ones may have look to LZAE(https://freebasic.net/forum/viewtopic.php?f=8&t=27695) to get exemples of use of the new features. (ps : Although distinct, lzae must be seen as a "companion" software that establishes a link in terms of integration between lzle lists and FB arrays, between a non-contiguous indexed organization and contiguous direct access. Lzae targets integration with related uses: matrix, data presentation interface and so on).

New version Beta 0.995a : (04/2020)
This new version of LZLE consists essentially of an optimization of the memory load. The functionality, speed (+/- 5%) and overall behavior could be preserved, almost identically. Marginal features not included are always accessible by declaring String instead of zString or by increasing the size of zString in ListContainer and / or ListNode, and / or by setting the IsTree Variable to 1 by default (depending on needs but by retrieving some memory load). Lesser memory consumption is especially noticeable on heavy loads. In addition, deallocation makes it possible to effectively recover most of the unused load available in the task manager.
Fixed some bugs (including one documented in the help which fixes a "strange" behavior).
BUG Fixes Beta 0.995b : (06/04/2020) : bug fixes on Sort,fSort,ColSort (wrong results cases+leak), NFMethod(2)(crash), HashTag(Key)(update). Sorry for these, testing.
Last edited by Lost Zergling on Dec 26, 2020 21:53, 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.996b

Post by Lost Zergling »

Archive Beta 0.996b Part 1/4
=> Latest release : viewtopic.php?f=8&t=26533

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) &_
"  PARIS 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/) or " & chr(10) & " http://users.freebasic-portal.de/sarg/fbcgas64.zip)"&_
" >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/ ou " & chr(10) & " http://users.freebasic-portal.de/sarg/fbcgas64.zip)" & 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

/' ?todo
    'cf restauration contexte hashlen ds tracking et aside,
   ' BugsFix : ColSort ???=>ok? | SeekMet 2=>ok? | RestoreHash=>not sorted%HashSort(1)=>Ok? | SortLeaks/Tag(n)=>Ok? | HashTag&Tag(uTag)=>Ok? | Tag1+ FIXes ds hashTag%list_Res=>Ok?  Checkcompat=>Ok?
   ' Tag1 0="", Tag1 1=" " , Tag1 255=LIST_DEL - CopyCat+HashStep KO / Check tracking / Check Snatch & Snatch Below /  IsKey, MeKey
'/

'-------- PREPROC OPTIMIZATION OPTIONS --------
' # Define TagMode 0    zString Ptr    =>  Tags len (MIN_COLS to MAX_COLS) are Dynamic (zstring Ptr) from DEF_TAGLEN
' # Define TagMode 1    zString         =>  STATIC (consecutive) TAGS LEN (zstring*MAX_TAGLEN) means more speed (10%-30%)(1) and less memory load (20%-80%)(2) but implies :
'                                                               a) maximum len shall not be exceeded (except if it is desired feature) and b) all Tags len shall be as close as possible each others / c) efficient if 'MAX_TAGLEN' can be tuned to fit dataset structure
'                                                               (1) : No need to check len on each tag while setting      (2) : No need to store intermediate array pointer adress and len accessing datas
'' # Define TagMode 2   String           =>  Tags len (MIN_COLS to MAX_COLS) are Dynamic, managed by standard String Datatype

'--------------- SPEED, LOAD & FEATURES ---------------
' TagMode 0 and DEF_TAGLEN=0 VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 is up to 20% slower, but requiring 20-60% less memory and is more robust at deallocation
' TagMode 0 with uB_RedimTagLen=0  and DEF_TAGLEN choosen VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 requires 20-60% less memory, speed 15% faster BUT tags len truncated when exceed DEF_TAGLEN
' TagMode 0 with uB_RedimTagLen=1  and DEF_TAGLEN choosen VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 requires 20-60% less memory, speed 15% faster BUT slowdown when tags len exceed DEF_TAGLEN
' => Using the string type on str_tag_C with TagMode 2 (ie versus TagMode 0)  may only be relevant  if the data you want to enter in Tags arrays  (MIN_COLS To MAX_COLS) are very large and variable in size.
' TagMode 0 VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower (depending on algo) and is requiring 20%-80% more memory (depending on dataset) BUT tags len are not truncated (or slow) when exceed MAX_TAGLEN
' TagMode 0 with uB_RedimTagLen=0  and DEF_TAGLEN choosen VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower and requiring 20%-80% more memory BUT Tags truncation can be customizable
' TagMode 0 with uB_RedimTagLen=1  and DEF_TAGLEN choosen VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower and requiring 20%-80% more memory BUT Tags len can oversize DEF_TAGLEN
' => Using the Zstring type on str_tag_C with TagMode 1 (ie versus TagMode 0)  may only be relevant if the max size of the data is known in advance and varies little
' Important : All given percentages are only as an indication (on tree), you may find out important variations depending on several conditions - 'use of Flat' lists may be slower.

'-------------------------- CONCLUSION  --------------------------
' => Use # Define TagMode 0 to handle "easily" all common datasets & most situations, eventually use DEF_TAGLEN to optimize speed. The most versatile with manual & automatic optimization options.
' => Use # Define TagMode 1 to gain significant speed & memory load (fine tuning) only efficient for fixed (or little variable size data) to store in Tags(MIN_COLS to MAX_COLS), shall not often oversize MAX_TAGLEN (otherwise serious slowdown & possible bugs or compatibility break)
' => Use # Define TagMode 2 to handle large & variable dataset to store in Tag(MIN_COLS to MAX_COLS) or maybe backward compatibility (big size), can sometimes speed faster than TagMode 0, may consumes much more memory, less good deallocation.


'----------------------- PREPROCESSOR -----------------------  ' * 'Standard' setting = # Define TagMode 0 & CONST DEF_TAGLEN=0   ' * 'Fast' setting = # Define TagMode 1 with MAX_TAGLEN as small as possible & no or few oversize
# Define TagMode 0
'------------------ END PREPROCESSOR -------------------  ' * 'BigBuffer' setting is # Define TagMode 2 efficient on flat lists/big strings
'SHARED 1/2
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

'CONSTANTS
# IF TagMode=0
    CONST DEF_TAGLEN=0
# ELSEIF TagMode=1
    CONST MAX_TAGLEN=14 'must be>0, the max len to store to zstring tags
# ENDIF
CONST MIN_COLS=1 : CONST MAX_COLS=6 : CONST MAX_HASHLEN=1 : CONST DEF_KEYLEN=200
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4) : CONST MAX_TRACKS=20 ' MAX_TRACKS = all tracks are on a same single track cros-tracking not managed

'DATA IMPLEMENTATION
Type ListContainer 'Data Segment Level   
    # IF TagMode=0
        Dim As zString Ptr str_tag_C(MIN_COLS to MAX_COLS)
        Dim As uByte TagC_Len(MIN_COLS to MAX_COLS)
    # ELSEIF TagMode=1
        Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*(MAX_TAGLEN+1)
    # ELSE
        Dim str_tag_C(MIN_COLS to MAX_COLS) As String
    # ENDIF
    Dim As zString Ptr str_item, str_flat_tag
    Dim As uShort int_tag_len=0 : Dim As uInteger int_val_len=0
    Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag0 As zString*(MAX_HASHLEN+1) : Dim Tag1 As uByte=0
    Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode
    Dim As ListContainer Ptr ListData : Dim As uInteger BranchCount=0
End Type

'TREE PARSING CONTEXT
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(DEF_KEYLEN), Listptemp2=_Callocate(DEF_KEYLEN), zp3=_Callocate(1)
    Dim  As ListContext Lcontext(0 to MAX_COLS), Tracks(0 to MAX_COLS)
    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, pCurrentPanCakeTMP
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt, PVS_Count=0
    Dim As Byte uTag=0, bSearchRes=0, bRHByPass=0, bHashStepRev=0, bfStepZero=0, bTrackingMethod=0, bTracking=0, bHTMethod=1, bHashKeyUnique=1, uSortTag=-1,_
                        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, uB_CurLevel=1, uB_Level=1, uB_KeyStepCumul=1, uB_MaxLevel=1, uB_BottomLevel=255, uB_BottomByPass=0, uB_tmp, uB_IsTree=0, uB_ind, uB_RedimTagLen=1, uB_TagC_Len(MIN_COLS to MAX_COLS)
    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 FlatTagSet(Str_Tag As String) As Byte
    Declare Property ValSet(Str_Tag As String) As Byte
    Declare Property TagC_Set(Str_Tag As String) As Byte
    # IF TagMode=1
    Declare Property TagC_Get As String
    # ENDIF
    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 HasTagFlat(str_Tag As String) As Byte     ' HasTag alternative (slightly faster) for Flat lists
    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
    'Tree 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 KeyStep(ub as uByte) As Byte                 ' FOR EACH - show only Keys previously manually tagged by user using Check(uByte) matching uByte
    Declare Property KeyStepRev(ub as uByte) As Byte
    Declare Property nCurLevel As Byte
    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 HasTagTree(str_Tag As String) As Byte  ' HasTag alternative (faster) for tree ("Hash") lists
    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)
    Declare Property Check(ub As uByte) As Byte                       ' Set current node IsKey status : 0=not a key, 1=a key (internal, autoset), everything but 0 or 255 : a key, 255 reserved for flag delete
    Declare Property Check As Byte                                            ' return IsKey status
    '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   ' 1/2 DEPRECATED (Dynamic=>Static) !! - Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' DEPRECATED !! - 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 TagLenRedim(ub as uByte) as Byte   ' # Define TagMode 0 or # Define TagMode 1 ONLY : MyList.TagLenRedim(0) forces fixed size TagLen (TagLenDefault on TagMode 0 or MAX_TAGLEN on TagMode 1, wich means automatic truncation on oversize
    Declare Property TagLenDefault(ub as uByte) as Byte  ' # Define TagMode 0 ONLY : MyList.ColTags(4) : MyList.TagLenDefault(4) : MyList.ColTags(0) => All NEWLY created node will instanciated with zString*4 by default on Tag4, wheras others tags still instanciated DEF_TAGLEN by default
    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)   
End Type

'SHARED 2/2
Dim Shared gCollector As List

'==========================================================================================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
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag0 = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag0=LIST_ROOT
    # IF TagMode=0
        For ub as uByte=MIN_COLS To MAX_COLS : uB_TagC_Len( ub ) = DEF_TAGLEN : Next ub
    # ENDIF
    this.Root : this.AllOf : uSortTag=0
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
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ' Moment Angulaire(petite masse)         
End If : pTemp->Tag1=0 : 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="" : *pPanTemp->str_flat_tag=""
        For uB=MIN_COLS To MAX_COLS
            # IF TagMode=0
                *pPanTemp->str_tag_C(uB)=""
            # ELSE
                pPanTemp->str_tag_C(uB)=""
            # ENDIF
        Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else
        pPanTemp=_Callocate(Len(ListContainer))
        # IF TagMode=0
            If DEF_TAGLEN>0 Then : For uB=MIN_COLS To MAX_COLS : pPanTemp->str_tag_C(uB)=_Callocate(uB_TagC_Len( ub ) ) : pPanTemp->TagC_Len(uB)=uB_TagC_Len( ub )  : Next uB : End If
        # ENDIF
    End If : Return pPanTemp
End Property

Property List.FlatTagSet(Str_Tag As String) As Byte
    Dim As uInteger iLen=Len(Str_Tag)+1
    If iLen >= pCurrentPanCakeTMP->int_tag_len Then
        If pCurrentPanCakeTMP->str_flat_tag<>0 Then : _Deallocate(pCurrentPanCakeTMP->str_flat_tag) : End If       
        pCurrentPanCakeTMP->str_flat_tag=_Callocate(iLen)
        pCurrentPanCakeTMP->int_tag_len=iLen
    End If
    *pCurrentPanCakeTMP->str_flat_tag = str_Tag
    Return 1
End Property

Property List.ValSet(Str_Tag As String) As Byte
    Dim As uInteger iLen=Len(Str_Tag)+1
    If iLen >= pCurrentPanCakeTMP->int_val_len Then       
        If pCurrentPanCakeTMP->str_item<>0 Then : _Deallocate(pCurrentPanCakeTMP->str_item) : End If       
        pCurrentPanCakeTMP->str_item=_Callocate(iLen)     
        pCurrentPanCakeTMP->int_val_len=iLen
    End If
    *pCurrentPanCakeTMP->str_item = str_Tag
    Return 1
End Property

Property List.TagC_Set(Str_Tag As String) As Byte
    # IF TagMode=0
        Dim As uShort iLen : Dim As zString Ptr pz=pCurrentPanCakeTMP->str_tag_C(uB_ind)
        If uB_RedimTagLen=1 Or pz=0 Then
            iLen=Len(Str_Tag)+1
            If iLen >= pCurrentPanCakeTMP->TagC_Len(uB_ind) Then
                If pz<>0 Then : _Deallocate(pz) : End If       
                pCurrentPanCakeTMP->str_tag_C(uB_ind)=_Callocate(iLen)
                pCurrentPanCakeTMP->TagC_Len(uB_ind)=iLen
            End If
        End If
        *pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
    # ELSEIF TagMode=1
        If uB_RedimTagLen=1 Then
            Dim As uShort iLen ': Dim As uByte Ptr PuB : Dim As zString Ptr PzS
            iLen=Len(Str_Tag)
            If iLen > MAX_TAGLEN Then
                Dim As uShort uNbLoops
                Dim As zString Ptr Pz1=StrPtr(Str_Tag), Pz2=Pz1
                Pz1+=MAX_TAGLEN
                (*zp3)[0]=(*Pz1)[0] : Pz1[0]=0
                pCurrentPanCakeTMP->str_tag_C(uB_ind) = *Pz2               
                (*Pz1)[0]=(*zp3)[0]               
                uNbLoops=-Int(-iLen/MAX_TAGLEN)-1
                For i as uShort=1 To uNbLoops                   
                    Pz2+=MAX_TAGLEN
                    Pz1+=MAX_TAGLEN
                    (*zp3)[0]=(*Pz1)[0] : Pz1[0]=0
                    If pCurrentPanCakeTMP->pNextContainer=0 Then
                        pCurrentPanCakeTMP->pNextContainer=AllowPanCake
                    End If
                    pCurrentPanCakeTMP->pNextContainer->str_tag_C(uB_ind) = *Pz2
                    (*Pz1)[0]=(*zp3)[0]
                    pCurrentPanCakeTMP=pCurrentPanCakeTMP->pNextContainer
                Next i
            Else
                If iLen = MAX_TAGLEN And pCurrentPanCakeTMP->pNextContainer<>0 Then : pCurrentPanCakeTMP->pNextContainer->str_tag_C(uB_ind) = "" : End If
                pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
            End If
        Else
            pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
        End If       
    # ELSE
        pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
    # ENDIF
    Return 1
End Property

# IF TagMode=1
    Property List.TagC_Get As String
        If uB_RedimTagLen=1 Then
            Dim As ListContainer Ptr pPanTmp=pCurrentPanCakeTMP->pNextContainer
            sMV_Tag=pCurrentPanCakeTMP->str_tag_C(uB_ind)
            If Len(sMV_Tag)=MAX_TAGLEN Then
                uB_tmp=1
                While pPanTmp<>0 And uB_tmp=1
                    If pPanTmp->str_tag_C(uB_ind)<>"" Then : sMV_Tag+= pPanTmp->str_tag_C(uB_ind) : Else : uB_tmp=0 : End If
                    pPanTmp=pPanTmp->pNextContainer
                Wend
            End If
            Return sMV_Tag
        Else
            Return pCurrentPanCakeTMP->str_tag_C(uB_ind)
        End If   
    End Property
# ENDIF

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->Tag0<>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
            Else 'ListData->str_flat_tag
                If this.pNode->pNext<>0 Then
                    pNode->Tag0 = LIST_DEL : pNode->BranchCount=0 : NbCollected +=1 ':  pNode->pBranchLastNode=0 ': iLong+=1  For ub1=1 To RUP_COLS : pNode->Tag1(ub1)="" : Next ub1 :
                    If pNode->ListData<>0 Then
                        # IF TagMode=0
                            For ub1=MIN_COLS To MAX_COLS : *pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ELSEIF TagMode=1
                            Dim As ListContainer Ptr pPanTemp=pNode->ListData->pNextContainer, PNextContTMP=pPanTemp'->pNextContainer
                           ' If pPanTemp<>0 Then : PNextContTMP=pPanTemp->pNextContainer : End If
                            While PNextContTMP<>0             
                                pPanTemp=PNextContTMP
                                For ub1=MIN_COLS To MAX_COLS : pPanTemp->str_tag_C(ub1)="" : Next ub1
                                PNextContTMP=PNextContTMP->pNextContainer
                                pPanTemp->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pPanTemp :  uContainerGarbCt+=1                               
                            Wend
                            For ub1=MIN_COLS To MAX_COLS : pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ELSE
                            For ub1=MIN_COLS To MAX_COLS : pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ENDIF
                        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->Tag0 = 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->Tag0 = LIST_RES  ' 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
        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->Tag1="" : 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->Tag0=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 : 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 : pCurrentPanCakeTMP=this.pValTmp->ListData : this.ValSet(str_value) : Return 1 : End Property 'this.pValTmp->ListData->str_item=str_value :
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 : bfStepZero=0
    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
        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->Tag0<>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->Tag0=LIST_RES Or pNode->Tag0=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag0="" Then : Return 0
    ElseIf pNode->pBranch->Tag0<>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


Last edited by Lost Zergling on Dec 26, 2020 21:50, 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.996b

Post by Lost Zergling »

Archive Beta 0.996b Part 2/4

Code: Select all


Property List.GiveBranch As ListNode Ptr
    Dim As ListNode Ptr pTemp1, pTemp4
    If pNode->Tag0=LIST_RES Or pNode->Tag0=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
        If pLocalRoot->ListData<>0 Then
            # IF TagMode=0
                *pLocalRoot->ListData->str_tag_C(1)=""
            # ELSE
                pLocalRoot->ListData->str_tag_C(1)=""
            # ENDIF
        End If
        pLocalRoot->Tag0=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
            If pLocalRoot->ListData<>0 Then
                # IF TagMode=0
                    *pLocalRoot->ListData->str_tag_C(1)=""
                # ELSE
                    pLocalRoot->ListData->str_tag_C(1)=""
                # ENDIF
            End If
            pLocalRoot->Tag0=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->Tag0=LIST_DEL Then : this.FlatStack(0) : End If
    If pFirstNode->pNext->Tag0=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.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If 
    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
    If this.HasTag(str_Tag) Then : this.pNode = this.pSearchNode : uB_tmp=1
    Else
        pNode = this.pLastNode : this.uCount+=1 : pNode->pNext = this.AllowCake 'And eat it
        pNode->pNext->pPrev = pNode : pNode->pNext->Tag0 = str_Tag  : uB_tmp=0
        pNode = pNode->pNext : this.pLastNode = pNode : 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
    End If       
    If  (uTag=0 And uB_IsTree=1) Or str_Tag=""  Then
    ElseIf this.uB_tmp=0 Then
        If pNode->ListData=0 Then : pNode->ListData=AllowPanCake : End If
        If uTag=0 Then : pCurrentPanCakeTMP=pNode->ListData : this.FlatTagSet(Str_Tag)
        Else : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.TagC_Set(Str_Tag)  '   pNode->ListData->str_tag_C(uTag) = str_Tag
        End If       
    End If
    Return uB_tmp
End Property

Property List.Tag As String : Return This.Tag(uTag) : End Property
Property List.Tag(i As Integer) As String ' La propriété devient multicontextuelle (flat & tree) suite chgt implémentation   "@" + Val(pz)
    If i=0 And uB_IsTree=1 Then : Return this.pNode->Tag0  ' Tree context specified by user
    ElseIf pNode->ListData=0 Then : Return this.pNode->Tag0  ' Tree context mandatory
    ElseIf i=0 Then :  If *pNode->ListData->str_flat_tag="" Then : Return this.pNode->Tag0 : Else : Return *pNode->ListData->str_flat_tag : End If
    Else
        # IF TagMode=0
            Return *pNode->ListData->str_tag_C(i)
        # ELSEIF TagMode=1
            If uB_RedimTagLen=1 Then
                Dim As ListContainer Ptr pPanTmp=pNode->ListData->pNextContainer
                sMV_Tag=pNode->ListData->str_tag_C(i)
                If Len(sMV_Tag)=MAX_TAGLEN Then
                    uB_tmp=1
                    While pPanTmp<>0 And uB_tmp=1
                        If pPanTmp->str_tag_C(i)<>"" Then : sMV_Tag+= pPanTmp->str_tag_C(i) : Else : uB_tmp=0 : End If
                        pPanTmp=pPanTmp->pNextContainer
                    Wend
                End If
                Return sMV_Tag
            Else
                Return pNode->ListData->str_tag_C(i)
            End If           
        # ELSE
            Return pNode->ListData->str_tag_C(i)
        # ENDIF
    End If
End Property

Property List.HasTagFlat(str_Tag As String) As Byte
    If uTag<>0 Then : Return this.HasTagFlat(str_Tag) : End If
    Dim As ListNode Ptr pTemp : uB_tmp=0   
    If bSeekMethod=1 Then
        pTemp=pFirstNode : If this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And  uB_tmp=0  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend
    ElseIf bSeekMethod=2 Then
        pTemp=pLastNode : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If
        While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend 
    Else
        pTemp=pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If ': If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If
        While (pTemp->pNext <> 0 And  uB_tmp=0  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend
    End If   
    If uB_tmp=1  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.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag : uB_tmp=0
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If           
        If uTag=0 Then
            While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode)
                pTemp = pTemp->pNext :
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext :  If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext :  If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If     
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        If uTag=0 Then               
            If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage )
                pTemp = pTemp->pPrev
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                uB_tmp=0 : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                uB_tmp=0 : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And uB_tmp=0 AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                uB_tmp=0 : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If   
    Else
        pTemp = this.pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If
        If uTag=0 Then
            If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode )
                pTemp = pTemp->pNext
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                uB_tmp=0 : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If     
    End If   
    If uB_tmp=1  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 :
    If uTag=0 And uB_IsTree=1 Then : pTemp->pNext->Tag0 = str_Tag
    Else
        pTemp->pNext->Tag0=str_Tag : If pTemp->pNext->ListData=0 Then : pTemp->pNext->ListData=AllowPanCake() : End If : pCurrentPanCakeTMP=pTemp->pNext->ListData
        If uTag=0 Then : this.FlatTagSet(Str_Tag)
        ElseIf uSortTag<>-1 Then : uB_ind=uTag : this.TagC_Set(Str_Tag)  ' pTemp->pNext->ListData->str_tag_C(uTag)=str_Tag
        End If
    End If
    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<>0  Then : If pNode->ListData=0 Then : this.pNode->ListData=AllowPanCake() : End If : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.TagC_Set(s_Tag) : Return 1 ' pNode->ListData->str_tag_C(uTag)=s_Tag
    Else
        this.pNode->Tag0=s_Tag ': If uB_IsTree=1 Then : Return 1 : End If
        If pNode->ListData=0 Then : Return 1 : End If : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.FlatTagSet(s_Tag) : Return 1
    End If
End Property
Property List.RwTag0(s_Tag As String) As Byte : uB_tmp=uTag : uTag=0 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property
Property List.RwTag1(s_Tag As String) As Byte : uB_tmp=uTag : uTag=1 : this.RwTag(s_Tag ) : uTag=uB_tmp : 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 then : this.uTag=MAX_COLS : 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 : this list instance cannot 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(uTag) 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 ' Or pNode->pNext=pEndFlat
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
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->Tag0=LIST_DEL Or pNode->Tag0=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

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS then : this.uTag=MAX_COLS : 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 : Dim As uByte tmpIsTree=this.uB_IsTree : this.uB_IsTree=0
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If
    'Trie+Insert Sort - non recursive   
    gCollector.SetRelation(1) : gCollector.HashKeyUnique(1) : gCollector.HashSort(1) : gCollector.fSortMethod(this.bSortMT) : 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
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : : End If
        gCollector.SetRelation1(this.pNode) : by=this.fStep
    Wend
    If pFirstNode<>pFirstFIRSTnode Then
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : End If
        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) :  this.uB_IsTree=tmpIsTree
    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 : Dim as Byte bHashSort=this.bSortMT : this.bSortMT=0
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If  : this.HashSort(0) :
    this.Root : this.fSort :  this.Root : 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 : bSortMT=bHashSort
    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


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

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

Post by Lost Zergling »

Archive Beta 0.996b Part 3/4

Code: Select all


'==========================================================================================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->Tag0<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If   
    If this.IsDestroyed=1 Then : Print "LZLE error - List.Root : Error List destroyed : instance can't be re-used" : Sleep : Return 0 : End If
    this.RootPrivate
    If pLocalMove<>0 Then
        If pLocalMove->ListData<>0 Then
            # IF TagMode=0
            *pLocalMove->ListData->str_tag_C(1)=""
            # ELSE
            pLocalMove->ListData->str_tag_C(1)=""
            # ENDIF
        End If
        pLocalMove->pBranch=0 :  pLocalMove->Tag0=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->Tag0=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag0<>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 pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : pGarbage->pPrev=pFlatRoot : this.Val(LIST_DEL) :
        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->Tag0<>"" 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->Tag0=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.NodeRecycle : this.pNode=AllowCake : pNode->Tag0="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext
    # IF TagMode=0
        If pLocalMove->ListData<>0 Then : *pLocalMove->ListData->str_tag_C(1)="" : End If
    # ELSE
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->str_tag_C(1)="" : End If
    # ENDIF
    pLocalMove->pBranch=0 :  pLocalMove->Tag0=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 : bfStepZero=0
    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
    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
    Wend : this.bHashStepRev=0 : Return 0
End Property

Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : End If : Wend : End Property
Property List.KeyStep(ub as uByte) As Byte : While this.HashStep=1 : If pNode->Tag1=ub Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev(ub as uByte) As Byte : While this.HashStepRev=1 : If pNode->Tag1=ub Then : Return 1 : End If : Wend : End Property

'Numeric parse optimization
Property List.nCurLevel As Byte : Return uB_CurLevel  : End Property
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->Tag1<>0 And pNode->Tag1<>255 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->Tag1<>0 And pNode->Tag1<>255 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>DEF_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 : Str_tmp=this.HashTag ' If pFirstNode->Tag1<>"" Then : Str_tmp=pFirstNode->Tag1 & pNode->Tag0 : Else : Str_tmp=this.HashTag  : End If ': If ubKeysRegister=1 Then : pFirstNode->Tag1=Left(Str_tmp, Len(Str_tmp)-istep) : End If
        End If
        iLenStrTmp=Len(Str_tmp)
        If iLenStrTmp>DEF_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
            If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
            iLenStrTmp=Len(Str_tmp) ': While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext : 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
                *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
                If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  Wend   
                pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
                iLenStrTmp=Len(Str_tmp) ' 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 uTag=0 Then
                If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else : pTemp = pTemp02 : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                End If
            Else : uB_tmp=0
                If bSeekMethod_TMP=2 Then
                    pTemp = this.pLastNode  ' While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                Else
                    pTemp = pTemp02 ' While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                End If
            End If
        Else : uB_tmp=0
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                If uSortTag=0 Then : While ( pTemp->Tag0>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else  '  While ( pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE                   
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                End If
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else                 
                If uSortTag=0 Then : pTemp=pTemp02 : While (pTemp->Tag0<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->Tag0<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If ': Print "**1" : sleep
                Else  'While (pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    pTemp=pTemp02
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                        If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    # ELSE                   
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                        If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    # ENDIF
                End If
            End If
        End If
        If uTag=0 Then : Str_tmp2=pTemp- >Tag0  ':  Print "**2" : sleep
        Else 'Str_tmp2=Str(pTemp- >Tag1)
            # IF TagMode=0
                Str_tmp2=*pTemp- >ListData->str_tag_C(uTag)
            # ELSE
                Str_tmp2=pTemp- >ListData->str_tag_C(uTag)
            # ENDIF
        End If
        If Str_tmp2=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp
        ElseIf Str_tmp2=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
            If uTag=0 Then : pTemp03->Tag0 = Str_tmp
            Else 'pTemp03->Tag1 = CuByte(Str_tmp)
                # IF TagMode=0
                    *pTemp03->ListData->str_tag_C(uTag) = Str_tmp
                # ELSE
                    pTemp03->ListData->str_tag_C(uTag) = Str_tmp
                # ENDIF
            End If
            HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If Str_tmp2=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
            pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode
            If uTag=0 Then : pTemp03->pNext->Tag0 = Str_tmp
            Else ': pTemp03->pNext->Tag1 = CuByte(Str_tmp)
                # IF TagMode=0
                    *pTemp03->pNext->ListData->str_tag_C(uTag) = Str_tmp
                # ELSE
                    pTemp03->pNext->ListData->str_tag_C(uTag) = Str_tmp
                # ENDIF
            End If
            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 Str_tmp2=Str_tmp Then : this.HoldBack(bTrackMultiKeys) : End If
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system               If bSeekMethod_TMP=2 Then : Print "Pt 9" : sleep :  End If
        End If
       
        If iLenCumul<iLen Then
            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->Tag0 = LIST_RES ' : Else : pTemp03->pNext->Tag1 = 3 : End If ' pTemp03->pNext- >Tag0 = 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 : 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_testTMP : str_Tag=str_testTMP
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag1=0 Then :  If HadHashTag=1 Then : HadHashTag=2 : End If : If bRHByPass=0 Then : this.pNode->Tag1=1 : End If : 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     
    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     
    If pFirstNode->pBranch<>pFlatRoot Then : Str_tmp = this.pnode->Tag0 'si pas ds contexte flat root on prends la clef Tag0
    Else : Str_tmp = *this.pnode->ListData->str_flat_tag  : End If
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag0  + Str_tmp                 
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasTagTree(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->Tag0 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag0 <> 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->Tag0 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag0 = 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.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 : pNode=pGarbage '   
    this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode :' uB_tmp=uB_IsTree : uB_IsTree=1
    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.HasTagTree(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            # IF TagMode=0
                If pNode->ListData<>0 Then : str_testTMP=*this.pNode->ListData->str_tag_C(1) : Else : str_testTMP="" :  End If
            # ELSE
                If pNode->ListData<>0 Then : str_testTMP=this.pNode->ListData->str_tag_C(1) : Else : str_testTMP="" :  End If
            # ENDIF
            If str_testTMP="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf str_testTMP="!*" Then : HadHashTag=0 : i=t
            ElseIf str_testTMP="!" 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 : uB_IsTree=uB_tmp : Return 1 : Else : uB_IsTree=uB_tmp : If bHashStepRev=1 Then : Return this.KeyStepRev : Else : Return this.KeyStep :  End If  : End If      KO !           
            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 ': uB_IsTree=uB_tmp
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag1=0 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
    Dim pContextRetour As ListContext
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.Root : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : Else : Return 0 : End If : Else : Return 0 : End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
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->Tag0=LIST_RES Or pNode->Tag0=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 : Str_tmp=this.HashTag : pLatestHTag=0  ' If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag1 : 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é  bNFflag
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag1=255 Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag0=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->Tag0=this.pNode->Tag0 : pTemp1->Tag1=255
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0
        If this.pNode->ListData=0 Then : this.pNode->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pNode->ListData : this.FlatTagSet(Str_tmp)  ' *this.pNode->ListData->str_flat_tag = 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->Tag0=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->Tag0=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->Tag0=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag1=0 :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag1=0 : pLocalRoot->Tag0=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag0=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag1=0 :  pLocalRoot->Tag0=LIST_DEL
        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->Tag1=255 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
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag0=LIST_DEL : pTemp2->Tag1=0 : 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->Tag1=0 Or pNode->Tag1=255 Then : this.NodeFlat : this.NodeRecycle2 : End If ' RECURSIF
            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
        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->Tag0<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pTemp2->ListData : this.FlatTagSet(Str_tmp) ' *pTemp2->ListData->str_flat_tag = Str_tmp ' : pTemp2->pPrev= this.pLastNode :
            pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode=pTemp2 : 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
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pTemp2->ListData : this.FlatTagSet(Str_tmp) ' *pTemp2->ListData->str_flat_tag = Str_tmp
            pTemp1->pNext=pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            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->Tag1=0 Or pNode->Tag1=255 Then : this.NodeFlat : this.NodeRecycle2 : End If  ' RECURSIF
            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
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then : this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag0=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 : Dim bTagExists As Byte : Dim As Byte uTagTmp=uTag, IsLastOne=0
    If this.pNode->ListData=0 Then : Return 0 : End If ' If pNode=pLocalMove Then : Return 0 : Else  Print "LZLE : RestoreHash : failure or non-value" :
    pTemp=this.pnode
    # IF TagMode=0
        If uTag=0 Then : str_tmp=*this.pNode->ListData->str_flat_tag : Else : str_tmp=*this.pNode->ListData->str_tag_C(uTag) : End If
    # ELSE
        If uTag=0 Then : str_tmp=*this.pNode->ListData->str_flat_tag : Else : str_tmp=this.pNode->ListData->str_tag_C(uTag) : End If
    # ENDIF
    If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    If pNode->pNext=pEndFlat And pNode->pPrev=pFirstNode Then : IsLastOne=1 : End If
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : this.Up : 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
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0  : Else : pTemp->Tag0= Str(this.pnode->Tag1)  : End If
        pMove=this.pnode : pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) ' *pMove->ListData->str_flat_tag=str_tmp :
        bTagExists=3 ' swap
    ElseIf bTagExists<>0 And pNode->Tag1<>0  Then ' tag deja existant et "vraie" clef
        'Gestion des modes (RHmethod)
        If uTag=0 Then
            If bRHmethod=-1 Then : pTemp->Tag0= this.pnode->Tag0 : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= this.pnode->Tag0  : pMove=this.pnode :  pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) : bTagExists=2 ' swap *pMove->ListData->str_flat_tag=str_tmp
            Else : If pNode->Tag1=255 Then : pNode->Tag1=1 : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        Else
            If bRHmethod=-1 Then : pTemp->Tag0= Str(this.pnode->Tag1)  : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= Str(this.pnode->Tag1)  : pMove=this.pnode : pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) : bTagExists=2 ' swap *pMove->ListData->str_flat_tag=str_tmp :
            Else : If pNode->Tag1=255 Then : pNode->Tag1=1 : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        End If
    Else
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0 : Else : pTemp->Tag0=Str(this.pnode->Tag1) : End If
        pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pNode->Tag1=pTemp->Tag1
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext  : *pTemp->ListData->str_flat_tag=""
  '  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->Tag1=""  '  pnode->pBranch->Tag1=""
        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<>3 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag1=0 : pLocalMove->Tag0=LIST_DEL :
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext :
    End If : If IsLastOne=1 Then : this.Up : bfStepZero=1 : pNode=pLastNode : End If '
    Return 1
End Property

Property List.Check(ub As uByte) As Byte : this.pNode->Tag1=ub : Return 1 : End Property
Property List.Check As Byte : Return this.pNode->Tag1 : 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>MAX_HASHLEN Then : Print "LZLE warning : HashLen Property ignored (deprecated), or must be =< MAX_HASHLEN (constant)" : End If : this.bHashLen=1 : Return 1 : End Property
Property List.KeysRegister(ub As uByte) As Byte : Print "LZLE warning : KeysRegister Property ignored (deprecated)" :  Return 0 : 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+1 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->Tag0=LIST_RES  Or pNode->Tag0=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->Tag1=0 : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag1=0 : 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->Tag0=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->Tag0=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->Tag0=LIST_DEL Or bColTrackLocked=1 Then : this.Root : bTracking=0 : Return 0 : End If
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag0<>LIST_RES Then
        pNode=pNode->pBranchLastNode : bTracking=1
        If bTrackingMethod=1 Then : this.TrackCompute
        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->Tag0<>LIST_DEL And pNode->Tag0<>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->Tag0=LIST_DEL
        If this.Tracks(by).pNode->Tag0=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->Tag0=""
        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->Tag0<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS : If TrackTrace(i)=pNode Then : Return 1 : End If : Next i : Return 0 : End If  : 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.996b

Post by Lost Zergling »

Archive Beta 0.996b Part 4/4

Code: Select all


Property List.Aside As Byte : Return this.Aside(1) : End Property
Property List.Aside(by As Byte) As Byte
    If by > MAX_COLS 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->Tag0 : 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 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.TagLenRedim(ub as uByte) as Byte
    If ub=1 Then : uB_RedimTagLen=ub : Return 1 : End If
    # IF TagMode=0 Or  TagMode=1
        uB_RedimTagLen=ub : Return 1
    # ELSE
        Print "Lzle warning : ListTagLenRedim(0) - No Redim - is only valid on # Define TagMode 0 and  # Define TagMode 1" : Return 0
    # ENDIF
End Property

Property List.TagLenDefault(ub as uByte) As Byte
    # IF TagMode=0
        uB_TagC_Len(uTag)=ub : Return 1
    # ELSE
        Print "Lzle warning : TagLenDefault (dynamic) is only valid on # Define TagMode=0" : Return 0
    # ENDIF
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->Tag1=0 : pLocalMove->Tag0=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->Tag0=LIST_DEL : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then           
            For i=MIN_COLS To MAX_COLS
                # IF TagMode=0
                    *pTemp1->ListData->str_tag_C(i)=""
                # ELSE
                    pTemp1->ListData->str_tag_C(i)=""
                # ENDIF
            Next i
            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->Tag0=LIST_DEL
    If pTemp1->ListData<>0 Then         
        For i=MIN_COLS to MAX_COLS
            # IF TagMode=0
                *pTemp1->ListData->str_tag_C(i)=""
            # ELSE
                pTemp1->ListData->str_tag_C(i)=""
            # ENDIF
        Next i 
    End If
    pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0
    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     
    Dim As ListContainer Ptr P_tmp : Dim As uInteger i
    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
            If pFlatRoot->pNext->ListData->str_flat_tag<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_flat_tag) : End If
            If pFlatRoot->pNext->ListData->str_item<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_item) : End If
            # IF TagMode=0
                For i=MIN_COLS To MAX_COLS :  If pFlatRoot->pNext->ListData->str_tag_C(i)<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_tag_C(i)) : End If  : Next i
        '    # ELSE
        '        If pFlatRoot->pNext->ListData->str_tag_C<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_tag_C) : End If
            # ENDIF
            _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
        P_tmp=AllowPanCake : If P_tmp->str_flat_tag<>0 Then : _Deallocate(P_tmp->str_flat_tag) : End If : If P_tmp->str_item<>0 Then : _Deallocate(P_tmp->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If P_tmp->str_tag_C(i)<>0 Then : _Deallocate(P_tmp->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate(P_tmp) : pPanTemp=pPanCakeGarbage->pNextContainer
    Wend
    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
    Dim As uByte i
    If this.IsDestroyed=1 Then : Return 0 : End If
    this.Root : this.DropAll : IsDestroyed=1
    If pPanCakeGarbage<>0 Then
        If pPanCakeGarbage->str_flat_tag<>0 Then : _Deallocate(pPanCakeGarbage->str_flat_tag) : End If
        If pPanCakeGarbage->str_item<>0 Then : _Deallocate(pPanCakeGarbage->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pPanCakeGarbage->str_tag_C(i)<>0 Then : _Deallocate(pPanCakeGarbage->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _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
        If pEndFlat->ListData->str_flat_tag<>0 Then : _Deallocate(pEndFlat->ListData->str_flat_tag) : End If
        If pEndFlat->ListData->str_item<>0 Then : _Deallocate(pEndFlat->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pEndFlat->ListData->str_tag_C(i)<>0 Then : _Deallocate(pEndFlat->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pEndFlat->ListData : this.pEndFlat->ListData=0     
    End If
    If this.pLastLASTNode->ListData<>0 Then
        If pLastLASTNode->ListData->str_flat_tag<>0 Then : _Deallocate(pLastLASTNode->ListData->str_flat_tag) : End If
        If pLastLASTNode->ListData->str_item<>0 Then : _Deallocate(pLastLASTNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pLastLASTNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pLastLASTNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pLastLASTNode->ListData : this.pLastLASTNode->ListData=0
    End If
    If this.pGarbage->ListData<>0 Then
        If pGarbage->ListData->str_flat_tag<>0 Then : _Deallocate(pGarbage->ListData->str_flat_tag) : End If
        If pGarbage->ListData->str_item<>0 Then : _Deallocate(pGarbage->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pGarbage->ListData->str_tag_C(i)<>0 Then : _Deallocate(pGarbage->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pGarbage->ListData : this.pGarbage->ListData=0
    End If
    If this.pWhyteMove->ListData<>0 Then
        If pWhyteMove->ListData->str_flat_tag<>0 Then : _Deallocate(pWhyteMove->ListData->str_flat_tag) : End If
        If pWhyteMove->ListData->str_item<>0 Then : _Deallocate(pWhyteMove->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pWhyteMove->ListData->str_tag_C(i)<>0 Then : _Deallocate(pWhyteMove->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pWhyteMove->ListData : this.pWhyteMove->ListData=0
    End If
    If this.pFirstFIRSTNode->ListData<>0 Then
        If pFirstFIRSTNode->ListData->str_flat_tag<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_flat_tag) : End If :
        If pFirstFIRSTNode->ListData->str_item<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pFirstFIRSTNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pFirstFIRSTNode->ListData : this.pFirstFIRSTNode->ListData=0
    End If
    If this.pNode->ListData<>0 Then
        If pNode->ListData->str_flat_tag<>0 Then : _Deallocate(pNode->ListData->str_flat_tag) : End If : 
        If pNode->ListData->str_item<>0 Then : _Deallocate(pNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _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
    Return 0
End Property

'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
  Dim As ListNode Ptr pTemp1, pTemp2
    If pNode->Tag0=LIST_RES Or pNode->Tag0=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->Tag1=0 : pLocalMove->Tag0=LIST_DEL
            If this.Snatch(pList) <> 1 Then : this.NodeRecycle : pLocalMove=pFirstNode : pFirstNode->pBranch->pBranch=0 : pFirstNode->pBranch=0 :  pLocalMove->Tag1=0 : pLocalMove->Tag0=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->Tag1=0 : pLocalMove->Tag0=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->Tag0=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If
    ElseIf pNode->Tag0=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 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.996c

Post by Lost Zergling »

Archive 0.996c 1/4

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) &_
"  PARIS 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/) or " & chr(10) & " http://users.freebasic-portal.de/sarg/fbcgas64.zip)"&_
" >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/ ou " & chr(10) & " http://users.freebasic-portal.de/sarg/fbcgas64.zip)" & 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

/' ?todo        :
   ' BugsFix    : CopyCat+HashStep KO? / Check tracking / Check Snatch & Snatch Below /
   ' Tag1 is uByte instead string, reserved values : 0,1, 255 previous versions <0.995=> Tag1 0="", Tag1 1=" " , Tag1 255=LIST_DEL -  Meaning : 0=hashtag, not a key, 1=entry is a key, 255=hashtag or key that became a hashtag, key marked as transfered, hashtag to be deleted till no childs
   ' New to 0.996c : major bugs fixes & new features on Holback/Tracking now better supports when mixed with NodeFlat, dynamic otimization, support for easy syntax on indexed buffers - Holdback/Tracking faster and far better consistency
   ' New to 0.996c : NFrecursive : NFrecursive efficient on Tracking
   '    New 0.996c : HoldBackRev for LIFO indexed buffers - WIP
   ' New to 0.996c : MAX_ASIDE is distinct, Inside(=Insert)
   'todo : ++ tests trackings avancés?
   'todo : check TrackMultiKeys, Check
   'todo : documentation + détail
'/

'-------- PREPROC OPTIMIZATION OPTIONS --------
' # Define TagMode 0    zString Ptr    =>  Tags len (MIN_COLS to MAX_COLS) are Dynamic (zstring Ptr) from DEF_TAGLEN
' # Define TagMode 1    zString         =>  STATIC (consecutive) TAGS LEN (zstring*MAX_TAGLEN) means more speed (10%-30%)(1) and less memory load (20%-80%)(2) but implies :
'                                                               a) maximum len shall not be exceeded (except if it is desired feature) and b) all Tags len shall be as close as possible each others / c) efficient if 'MAX_TAGLEN' can be tuned to fit dataset structure
'                                                               (1) : No need to check len on each tag while setting      (2) : No need to store intermediate array pointer adress and len accessing datas
'' # Define TagMode 2   String           =>  Tags len (MIN_COLS to MAX_COLS) are Dynamic, managed by standard String Datatype

'--------------- SPEED, LOAD & FEATURES ---------------
' TagMode 0 and DEF_TAGLEN=0 VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 is up to 20% slower, but requiring 20-60% less memory and is more robust at deallocation
' TagMode 0 with uB_RedimTagLen=0  and DEF_TAGLEN choosen VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 requires 20-60% less memory, speed 15% faster BUT tags len truncated when exceed DEF_TAGLEN
' TagMode 0 with uB_RedimTagLen=1  and DEF_TAGLEN choosen VS TagMode 2 with Dim str_tag_C(MIN_COLS to MAX_COLS) As String : TagMode 0 requires 20-60% less memory, speed 15% faster BUT slowdown when tags len exceed DEF_TAGLEN
' => Using the string type on str_tag_C with TagMode 2 (ie versus TagMode 0)  may only be relevant  if the data you want to enter in Tags arrays  (MIN_COLS To MAX_COLS) are very large and variable in size.
' TagMode 0 VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower (depending on algo) and is requiring 20%-80% more memory (depending on dataset) BUT tags len are not truncated (or slow) when exceed MAX_TAGLEN
' TagMode 0 with uB_RedimTagLen=0  and DEF_TAGLEN choosen VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower and requiring 20%-80% more memory BUT Tags truncation can be customizable
' TagMode 0 with uB_RedimTagLen=1  and DEF_TAGLEN choosen VS TagMode 1 with Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*MAX_TAGLEN : TagMode 0 is 10%-30% slower and requiring 20%-80% more memory BUT Tags len can oversize DEF_TAGLEN
' => Using the Zstring type on str_tag_C with TagMode 1 (ie versus TagMode 0)  may only be relevant if the max size of the data is known in advance and varies little
' Important : All given percentages are only as an indication (on tree), you may find out important variations depending on several conditions - 'use of Flat' lists may be slower.

'-------------------------- CONCLUSION  --------------------------
' => Use # Define TagMode 0 to handle "easily" all common datasets & most situations, eventually use DEF_TAGLEN to optimize speed. The most versatile with manual & automatic optimization options.
' => Use # Define TagMode 1 to gain significant speed & memory load (fine tuning) only efficient for fixed (or little variable size data) to store in Tags(MIN_COLS to MAX_COLS), shall not often oversize MAX_TAGLEN (otherwise serious slowdown & possible bugs or compatibility break)
' => Use # Define TagMode 2 to handle large & variable dataset to store in Tag(MIN_COLS to MAX_COLS) or maybe backward compatibility (big size), can sometimes speed faster than TagMode 0, may consumes much more memory, less good deallocation.


'----------------------- PREPROCESSOR -----------------------  ' * 'Standard' setting = # Define TagMode 0 & CONST DEF_TAGLEN=0   ' * 'Fast' setting = # Define TagMode 1 with MAX_TAGLEN as small as possible & no or few oversize
# Define TagMode 0
'------------------ END PREPROCESSOR -------------------  ' * 'BigBuffer' setting is # Define TagMode 2 efficient on flat lists/big strings
'SHARED 1/2
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
Dim Shared As uInteger TrackCompCounter=0

'CONSTANTS
# IF TagMode=0
    CONST DEF_TAGLEN=0
# ELSEIF TagMode=1
    CONST MAX_TAGLEN=14 'must be>0, the max len to store to zstring tags
# ENDIF
CONST MIN_COLS=1 : CONST MAX_COLS=6 : CONST MAX_HASHLEN=1 : CONST DEF_KEYLEN=200 : CONST MAX_ASIDE=20
CONST LIST_RES=Chr(18) : CONST LIST_DEL=Chr(3)  : CONST LIST_ROOT=Chr(4) : CONST MAX_TRACKS=20 ' MAX_TRACKS = all tracks are on a same single track cros-tracking not managed

'DATA IMPLEMENTATION
Type ListContainer 'Data Segment Level   
    # IF TagMode=0
        Dim As zString Ptr str_tag_C(MIN_COLS to MAX_COLS)
        Dim As uByte TagC_Len(MIN_COLS to MAX_COLS)
    # ELSEIF TagMode=1
        Dim str_tag_C(MIN_COLS to MAX_COLS) As zString*(MAX_TAGLEN+1)
    # ELSE
        Dim str_tag_C(MIN_COLS to MAX_COLS) As String
    # ENDIF
    Dim As zString Ptr str_item, str_flat_tag
    Dim As uShort int_tag_len=0 : Dim As uInteger int_val_len=0
    Dim pNextContainer as ListContainer Ptr
End Type
Type ListNode 'ListNode Level
    Dim Tag0 As zString*(MAX_HASHLEN+1) : Dim Tag1 As uByte=0
    Dim  As ListNode Ptr pNext, pPrev, pBranch, pBranchLastNode
    Dim As ListContainer Ptr ListData : Dim As uInteger BranchCount=0
End Type

'TREE PARSING CONTEXT
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(DEF_KEYLEN), Listptemp2=_Callocate(DEF_KEYLEN), zp3=_Callocate(1)
    Dim  As ListContext Lcontext(0 to MAX_COLS), Tracks(0 to MAX_ASIDE)
    Dim As ListNode Ptr pNode, pFirstNode, pLastNode, pFirstFIRSTNode, pLastLASTNode, pGarbage, pEndFlat, pLocalRoot, pLocalMove, pWhyteMove, pFlatRoot, pSearchNode, pValTmp, TrackTrace(0 to MAX_COLS-1), pLatestHTag, pTrackTmp , pFirstNodeTMP, pLastNodeTMP
    Dim As ListContainer Ptr pPanCakeGarbage, pLastPanCake, pCurrentPanCakeTMP
    Dim As uInteger uNodeCOUNT, uGarbCt, uCount, uContainerGarbCt,  uContainerGivenCt, PVS_Count=0
    Dim As Byte uTag=0, bSearchRes=0, bRHByPass=0, bHashStepRev=0, bfStepZero=0, bTrackingMethod=0, bTracking=0, bHTMethod=1, bHashKeyUnique=1, uSortTag=-1,_
                        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, uB_CurLevel=1, uB_Level=1, uB_KeyStepCumul=1, uB_MaxLevel=1, uB_BottomLevel=255, uB_BottomByPass=0, uB_tmp, uB_IsTree=0, uB_ind, uB_RedimTagLen=1, uB_TagC_Len(MIN_COLS to MAX_COLS)
    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 FlatTagSet(Str_Tag As String) As Byte
    Declare Property ValSet(Str_Tag As String) As Byte
    Declare Property TagC_Set(Str_Tag As String) As Byte
    # IF TagMode=1
    Declare Property TagC_Get As String
    # ENDIF
    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 TrackSecure 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 HasTagFlat(str_Tag As String) As Byte     ' HasTag alternative (slightly faster) for Flat lists
    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 Insert(str_Tag As String) As Byte
    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
    'Tree 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 KeyStep(ub as uByte) As Byte                 ' FOR EACH - show only Keys previously manually tagged by user using Check(uByte) matching uByte
    Declare Property KeyStepRev(ub as uByte) As Byte
    Declare Property nCurLevel As Byte
    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 HasTagTree(str_Tag As String) As Byte  ' HasTag alternative (faster) for tree ("Hash") lists
    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)
    Declare Property Check(ub As uByte) As Byte                       ' Set current node IsKey status : 0=not a key, 1=a key (internal, autoset), everything but 0 or 255 : a key, 255 reserved for flag delete
    Declare Property Check As Byte                                            ' return IsKey status
    '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   ' 1/2 DEPRECATED (Dynamic=>Static) !! - Longueur des clefs en cascade
    Declare Property KeysRegister(ub As uByte) As Byte         ' DEPRECATED !! - 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 (restent en hashtag si enfants)
    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 NFrecurGarbage(ub As Byte) As Byte     ' Only effective if (NFrecursive=1 Or into TrackStep Iterator) And NFMethod<>-1 : when sending a key to Flat list, all hierarchical nodes that are no keys are send to garbage instead of flat list
    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 HoldBackRev As Byte
    Declare Property HoldBackRev(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 TrackStepRev As Byte
    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 TagLenRedim(ub as uByte) as Byte   ' # Define TagMode 0 or # Define TagMode 1 ONLY : MyList.TagLenRedim(0) forces fixed size TagLen (TagLenDefault on TagMode 0 or MAX_TAGLEN on TagMode 1, wich means automatic truncation on oversize
    Declare Property TagLenDefault(ub as uByte) as Byte  ' # Define TagMode 0 ONLY : MyList.ColTags(4) : MyList.TagLenDefault(4) : MyList.ColTags(0) => All NEWLY created node will instanciated with zString*4 by default on Tag4, wheras others tags still instanciated DEF_TAGLEN by default
    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)   
End Type

'SHARED 2/2
Dim Shared gCollector As List

'==========================================================================================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
    pFirstNode = pNode : pLastNode = pNode : bSeekMethod = 1 : uCount = 0 : uTag = 0 :     
    pFirstFIRSTNode = pNode : pLastLASTNode = pNode  : this.pFirstNode->BranchCount=0 : pNode->Tag0 = LIST_RES     
    pFirstFIRSTNode->pNext=pFlatRoot : pFlatRoot->pPrev=pFirstFIRSTNode : pFlatRoot->Tag0=LIST_ROOT
    # IF TagMode=0
        For ub as uByte=MIN_COLS To MAX_COLS : uB_TagC_Len( ub ) = DEF_TAGLEN : Next ub
    # ENDIF
    this.Root : this.AllOf : uSortTag=0
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
    If pTemp<>pGarbage Then : pFlatRoot->pNext=pTemp->pNext : pTemp->pNext->pPrev=pFlatRoot : This.uGarbCt-=1 : pTemp->pBranchLastNode=0
    Else : pTemp=_Callocate(Len(ListNode)) : this.uNodeCOUNT+=1 ' Moment Angulaire(petite masse)         
End If : pTemp->Tag1=0 : 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="" : *pPanTemp->str_flat_tag=""
        For uB=MIN_COLS To MAX_COLS
            # IF TagMode=0
                *pPanTemp->str_tag_C(uB)=""
            # ELSE
                pPanTemp->str_tag_C(uB)=""
            # ENDIF
        Next uB
        pPanCakeGarbage->pNextContainer=pPanCakeGarbage->pNextContainer->pNextContainer : uContainerGarbCt-=1 : pPanTemp->pNextContainer=0
    Else
        pPanTemp=_Callocate(Len(ListContainer))
        # IF TagMode=0
            If DEF_TAGLEN>0 Then : For uB=MIN_COLS To MAX_COLS : pPanTemp->str_tag_C(uB)=_Callocate(uB_TagC_Len( ub ) ) : pPanTemp->TagC_Len(uB)=uB_TagC_Len( ub )  : Next uB : End If
        # ENDIF
    End If : Return pPanTemp
End Property

Property List.FlatTagSet(Str_Tag As String) As Byte
    Dim As uInteger iLen=Len(Str_Tag)+1
    If iLen >= pCurrentPanCakeTMP->int_tag_len Then
        If pCurrentPanCakeTMP->str_flat_tag<>0 Then : _Deallocate(pCurrentPanCakeTMP->str_flat_tag) : End If       
        pCurrentPanCakeTMP->str_flat_tag=_Callocate(iLen)
        pCurrentPanCakeTMP->int_tag_len=iLen
    End If
    *pCurrentPanCakeTMP->str_flat_tag = str_Tag
    Return 1
End Property

Property List.ValSet(Str_Tag As String) As Byte
    Dim As uInteger iLen=Len(Str_Tag)+1
    If iLen >= pCurrentPanCakeTMP->int_val_len Then       
        If pCurrentPanCakeTMP->str_item<>0 Then : _Deallocate(pCurrentPanCakeTMP->str_item) : End If       
        pCurrentPanCakeTMP->str_item=_Callocate(iLen)     
        pCurrentPanCakeTMP->int_val_len=iLen
    End If
    *pCurrentPanCakeTMP->str_item = str_Tag
    Return 1
End Property

Property List.TagC_Set(Str_Tag As String) As Byte
    # IF TagMode=0
        Dim As uShort iLen : Dim As zString Ptr pz=pCurrentPanCakeTMP->str_tag_C(uB_ind)
        If uB_RedimTagLen=1 Or pz=0 Then
            iLen=Len(Str_Tag)+1
            If iLen >= pCurrentPanCakeTMP->TagC_Len(uB_ind) Then
                If pz<>0 Then : _Deallocate(pz) : End If       
                pCurrentPanCakeTMP->str_tag_C(uB_ind)=_Callocate(iLen)
                pCurrentPanCakeTMP->TagC_Len(uB_ind)=iLen
            End If
        End If
        *pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
    # ELSEIF TagMode=1
        If uB_RedimTagLen=1 Then
            Dim As uShort iLen ': Dim As uByte Ptr PuB : Dim As zString Ptr PzS
            iLen=Len(Str_Tag)
            If iLen > MAX_TAGLEN Then
                Dim As uShort uNbLoops
                Dim As zString Ptr Pz1=StrPtr(Str_Tag), Pz2=Pz1
                Pz1+=MAX_TAGLEN
                (*zp3)[0]=(*Pz1)[0] : Pz1[0]=0
                pCurrentPanCakeTMP->str_tag_C(uB_ind) = *Pz2               
                (*Pz1)[0]=(*zp3)[0]               
                uNbLoops=-Int(-iLen/MAX_TAGLEN)-1
                For i as uShort=1 To uNbLoops                   
                    Pz2+=MAX_TAGLEN
                    Pz1+=MAX_TAGLEN
                    (*zp3)[0]=(*Pz1)[0] : Pz1[0]=0
                    If pCurrentPanCakeTMP->pNextContainer=0 Then
                        pCurrentPanCakeTMP->pNextContainer=AllowPanCake
                    End If
                    pCurrentPanCakeTMP->pNextContainer->str_tag_C(uB_ind) = *Pz2
                    (*Pz1)[0]=(*zp3)[0]
                    pCurrentPanCakeTMP=pCurrentPanCakeTMP->pNextContainer
                Next i
            Else
                If iLen = MAX_TAGLEN And pCurrentPanCakeTMP->pNextContainer<>0 Then : pCurrentPanCakeTMP->pNextContainer->str_tag_C(uB_ind) = "" : End If
                pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
            End If
        Else
            pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
        End If       
    # ELSE
        pCurrentPanCakeTMP->str_tag_C(uB_ind) = str_Tag
    # ENDIF
    Return 1
End Property

# IF TagMode=1
    Property List.TagC_Get As String
        If uB_RedimTagLen=1 Then
            Dim As ListContainer Ptr pPanTmp=pCurrentPanCakeTMP->pNextContainer
            sMV_Tag=pCurrentPanCakeTMP->str_tag_C(uB_ind)
            If Len(sMV_Tag)=MAX_TAGLEN Then
                uB_tmp=1
                While pPanTmp<>0 And uB_tmp=1
                    If pPanTmp->str_tag_C(uB_ind)<>"" Then : sMV_Tag+= pPanTmp->str_tag_C(uB_ind) : Else : uB_tmp=0 : End If
                    pPanTmp=pPanTmp->pNextContainer
                Wend
            End If
            Return sMV_Tag
        Else
            Return pCurrentPanCakeTMP->str_tag_C(uB_ind)
        End If   
    End Property
# ENDIF

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->Tag0<>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
            Else 'ListData->str_flat_tag
                If this.pNode->pNext<>0 Then
                    pNode->Tag0 = LIST_DEL : pNode->BranchCount=0 : NbCollected +=1 ':  pNode->pBranchLastNode=0 ': iLong+=1  For ub1=1 To RUP_COLS : pNode->Tag1(ub1)="" : Next ub1 :
                    If pNode->ListData<>0 Then
                        # IF TagMode=0
                            For ub1=MIN_COLS To MAX_COLS : *pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ELSEIF TagMode=1
                            Dim As ListContainer Ptr pPanTemp=pNode->ListData->pNextContainer, PNextContTMP=pPanTemp'->pNextContainer
                           ' If pPanTemp<>0 Then : PNextContTMP=pPanTemp->pNextContainer : End If
                            While PNextContTMP<>0             
                                pPanTemp=PNextContTMP
                                For ub1=MIN_COLS To MAX_COLS : pPanTemp->str_tag_C(ub1)="" : Next ub1
                                PNextContTMP=PNextContTMP->pNextContainer
                                pPanTemp->pNextContainer=pPanCakeGarbage->pNextContainer : pPanCakeGarbage->pNextContainer=pPanTemp :  uContainerGarbCt+=1                               
                            Wend
                            For ub1=MIN_COLS To MAX_COLS : pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ELSE
                            For ub1=MIN_COLS To MAX_COLS : pNode->ListData->str_tag_C(ub1)="" : Next ub1
                        # ENDIF
                        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->Tag0 = 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->Tag0 = LIST_RES  ' 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
        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->Tag1="" : 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->Tag0=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 : 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 : pCurrentPanCakeTMP=this.pValTmp->ListData : this.ValSet(str_value) : Return 1 : End Property 'this.pValTmp->ListData->str_item=str_value :
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 : bfStepZero=0
    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
        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 : TrackCompCounter+=1 ' : ? "Track Compute on " & this.pNode->Tag0
    While pTemp1->Tag0<>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 : pFirstNodeTMP=pTemp1 : pLastNodeTMP=pLastNode : Return 1
End Property
Property List.TrackSecure As Byte
    If bTracking=1 AndAlso bTrackingMethod=0 Then
        If pNode->pPrev->Tag0=LIST_RES Then
        ElseIf pNode->pNext=pTrackTmp Or pNode->pPrev=pTrackTmp Then : bAlrdyTracked=1
        ElseIf pTrackTmp->pBranchLastNode=pNode->pBranchLastNode Then : bAlrdyTracked=1 : pFirstNode=pFirstNodeTMP : pLastNode=pLastNodeTMP : this.uCount=pFirstNode->BranchCount
        End If
        this.TrackCompute ': pTemp01 = this.pFirstNode : pTemp02 = this.pNode
    End If
    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
Lost Zergling
Posts: 538
Joined: Dec 02, 2011 22:51
Location: France

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

Post by Lost Zergling »

Archive 0.996c 2/4

Code: Select all

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->Tag0=LIST_RES Or pNode->Tag0=LIST_DEL Or pNode=pWhyteMove Or pNode=pFlatRoot Or pNode->Tag0="" Then : Return 0
    ElseIf pNode->pBranch->Tag0<>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->Tag0=LIST_RES Or pNode->Tag0=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
        If pLocalRoot->ListData<>0 Then
            # IF TagMode=0
                *pLocalRoot->ListData->str_tag_C(1)=""
            # ELSE
                pLocalRoot->ListData->str_tag_C(1)=""
            # ENDIF
        End If
        pLocalRoot->Tag0=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
            If pLocalRoot->ListData<>0 Then
                # IF TagMode=0
                    *pLocalRoot->ListData->str_tag_C(1)=""
                # ELSE
                    pLocalRoot->ListData->str_tag_C(1)=""
                # ENDIF
            End If
            pLocalRoot->Tag0=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->Tag0=LIST_DEL Then : this.FlatStack(0) : End If
    If pFirstNode->pNext->Tag0=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.pFlatRoot->pBranch->BranchCount=0 : If pFirstNode->pBranch=pFlatRoot Then : uCount=0 : End If
    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
    If this.HasTag(str_Tag) Then : this.pNode = this.pSearchNode : uB_tmp=1
    Else
        pNode = this.pLastNode : this.uCount+=1 : pNode->pNext = this.AllowCake 'And eat it
        pNode->pNext->pPrev = pNode : pNode->pNext->Tag0 = str_Tag  : uB_tmp=0
        pNode = pNode->pNext : this.pLastNode = pNode : 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
    End If       
    If  (uTag=0 And uB_IsTree=1) Or str_Tag=""  Then
    ElseIf this.uB_tmp=0 Then
        If pNode->ListData=0 Then : pNode->ListData=AllowPanCake : End If
        If uTag=0 Then : pCurrentPanCakeTMP=pNode->ListData : this.FlatTagSet(Str_Tag)
        Else : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.TagC_Set(Str_Tag)  '   pNode->ListData->str_tag_C(uTag) = str_Tag
        End If       
    End If
    Return uB_tmp
End Property

Property List.Tag As String : Return This.Tag(uTag) : End Property
Property List.Tag(i As Integer) As String ' La propriété devient multicontextuelle (flat & tree) suite chgt implémentation   "@" + Val(pz)
    If i=0 And uB_IsTree=1 Then : Return this.pNode->Tag0  ' Tree context specified by user
    ElseIf pNode->ListData=0 Then : Return this.pNode->Tag0  ' Tree context mandatory
    ElseIf i=0 Then :  If *pNode->ListData->str_flat_tag="" Then : Return this.pNode->Tag0 : Else : Return *pNode->ListData->str_flat_tag : End If
    Else
        # IF TagMode=0
            Return *pNode->ListData->str_tag_C(i)
        # ELSEIF TagMode=1
            If uB_RedimTagLen=1 Then
                Dim As ListContainer Ptr pPanTmp=pNode->ListData->pNextContainer
                sMV_Tag=pNode->ListData->str_tag_C(i)
                If Len(sMV_Tag)=MAX_TAGLEN Then
                    uB_tmp=1
                    While pPanTmp<>0 And uB_tmp=1
                        If pPanTmp->str_tag_C(i)<>"" Then : sMV_Tag+= pPanTmp->str_tag_C(i) : Else : uB_tmp=0 : End If
                        pPanTmp=pPanTmp->pNextContainer
                    Wend
                End If
                Return sMV_Tag
            Else
                Return pNode->ListData->str_tag_C(i)
            End If           
        # ELSE
            Return pNode->ListData->str_tag_C(i)
        # ENDIF
    End If
End Property

Property List.HasTagFlat(str_Tag As String) As Byte
    If uTag<>0 Then : Return this.HasTagFlat(str_Tag) : End If
    Dim As ListNode Ptr pTemp : uB_tmp=0   
    If bSeekMethod=1 Then
        pTemp=pFirstNode : If this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If
        While (pTemp->pNext <> 0 And  uB_tmp=0  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend
    ElseIf bSeekMethod=2 Then
        pTemp=pLastNode : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If
        While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend
    Else
        pTemp=pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If ': If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If
        While (pTemp->pNext <> 0 And  uB_tmp=0  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : End If : Wend
    End If   
    If uB_tmp=1  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.HasTag(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr
    this.sSearchTag = str_Tag : uB_tmp=0
    If this.bSeekMethod=1 Then
        pTemp = this.pFirstNode : If this.pGarbage<>0 And this.pFirstNode=this.pFirstFIRSTNode Then : pTemp = this.pGarbage  : End If           
        If uTag=0 Then
            While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode)
                pTemp = pTemp->pNext :
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext :  If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0) : pTemp = pTemp->pNext :  If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If     
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        If uTag=0 Then               
            If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage )
                pTemp = pTemp->pPrev
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                uB_tmp=0 : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                uB_tmp=0 : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And uB_tmp=0 AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                uB_tmp=0 : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pPrev <> 0 And  uB_tmp=0  AND pTemp <> this.pGarbage ) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If   
    Else
        pTemp = this.pNode : If pTemp=0 Then : pTemp = this.pFirstNode : End If
        If uTag=0 Then
            If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode )
                pTemp = pTemp->pNext
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_flat_tag=str_Tag Then : uB_tmp=1 : ElseIf *pTemp->ListData->str_flat_tag="" And pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If : ElseIf pTemp->Tag0=str_Tag Then : uB_tmp=1 : End If
            Wend               
        Else
            # IF TagMode=0
                If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSEIF TagMode=1
                pCurrentPanCakeTMP=pTemp->ListData : uB_ind=uTag
                uB_tmp=0 : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : pCurrentPanCakeTMP=pTemp->ListData : If pCurrentPanCakeTMP<>0 Then : If this.TagC_Get = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ELSE
                If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If
                While (pTemp->pNext <> 0 And uB_tmp=0 AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag) = str_Tag Then : uB_tmp=1 : End If : End If : Wend
            # ENDIF
        End If     
    End If   
    If uB_tmp=1  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 :
    If uTag=0 And uB_IsTree=1 Then : pTemp->pNext->Tag0 = str_Tag
    Else
        pTemp->pNext->Tag0=str_Tag : If pTemp->pNext->ListData=0 Then : pTemp->pNext->ListData=AllowPanCake() : End If : pCurrentPanCakeTMP=pTemp->pNext->ListData
        If uTag=0 Then : this.FlatTagSet(Str_Tag)
        ElseIf uSortTag<>-1 Then : uB_ind=uTag : this.TagC_Set(Str_Tag)  ' pTemp->pNext->ListData->str_tag_C(uTag)=str_Tag
        End If
    End If
    pTemp = pTemp->pNext : this.pLastNode = pTemp : this.pNode = pTemp
    If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.Insert(str_Tag As String) As Byte
    Dim pTemp As ListNode Ptr : Dim item As ListContainer
    pTemp = this.pNode : this.uCount+=1 : pTemp->pNext = this.AllowCake 'And eat it
    pTemp->pNext->pPrev = this.pNode :
    If uTag=0 And uB_IsTree=1 Then : pTemp->pNext->Tag0 = str_Tag
    Else
        pTemp->pNext->Tag0=str_Tag : If pTemp->pNext->ListData=0 Then : pTemp->pNext->ListData=AllowPanCake() : End If : pCurrentPanCakeTMP=pTemp->pNext->ListData
        If uTag=0 Then : this.FlatTagSet(Str_Tag)
        ElseIf uSortTag<>-1 Then : uB_ind=uTag : this.TagC_Set(Str_Tag)  ' pTemp->pNext->ListData->str_tag_C(uTag)=str_Tag
        End If
    End If : If pLastNode=pTemp Then : pLastNode = pTemp->pNext : End If
    this.pNode = pTemp->pNext : If bBranchCountDown=1 Then : this.BCountDown(1) : End If : Return 1
End Property

Property List.RwTag(s_Tag As String) As Byte
    If  uTag<>0  Then : If pNode->ListData=0 Then : this.pNode->ListData=AllowPanCake() : End If : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.TagC_Set(s_Tag) : Return 1 ' pNode->ListData->str_tag_C(uTag)=s_Tag
    Else
        this.pNode->Tag0=s_Tag ': If uB_IsTree=1 Then : Return 1 : End If
        If pNode->ListData=0 Then : Return 1 : End If : pCurrentPanCakeTMP=pNode->ListData : uB_ind=uTag : this.FlatTagSet(s_Tag) : Return 1
    End If
End Property
Property List.RwTag0(s_Tag As String) As Byte : uB_tmp=uTag : uTag=0 : this.RwTag(s_Tag ) : uTag=uB_tmp : Return 1 : End Property
Property List.RwTag1(s_Tag As String) As Byte : uB_tmp=uTag : uTag=1 : this.RwTag(s_Tag ) : uTag=uB_tmp : 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 then : this.uTag=MAX_COLS : 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 : this list instance cannot 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(uTag) 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 ' Or pNode->pNext=pEndFlat
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
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->Tag0=LIST_DEL Or pNode->Tag0=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

'==========================================================================================TYPE LIST PUBLIC PROPERTIES - SORTING
Property List.ColSort(i as Byte) As Byte : If i > MAX_COLS then : this.uTag=MAX_COLS : 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 : Dim As uByte tmpIsTree=this.uB_IsTree : this.uB_IsTree=0
    If pFirstNode=pFirstFIRSTnode Then : pTemp1=pGarbage : End If
    'Trie+Insert Sort - non recursive   
    gCollector.SetRelation(1) : gCollector.HashKeyUnique(1) : gCollector.HashSort(1) : gCollector.fSortMethod(this.bSortMT) : 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
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : : End If
        gCollector.SetRelation1(this.pNode) : by=this.fStep
    Wend
    If pFirstNode<>pFirstFIRSTnode Then
        If gCollector.HashTag( this.Tag(this.uSortTag) )=1 Then : gCollector.HashKeyUnique(0) : gCollector.SeekMethod(1) : gCollector.HashTag( this.Tag(this.uSortTag) ) : gCollector.HashKeyUnique(1) : End If
        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) :  this.uB_IsTree=tmpIsTree
    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 : Dim as Byte bHashSort=this.bSortMT : this.bSortMT=0
    If this.Up Then : this.Down : End If : If bSortMth=-1 Then : this.fSortMethod(-1) : Else : this.fSortMethod(1) : End If  : this.HashSort(0) :
    this.Root : this.fSort :  this.Root : 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 : bSortMT=bHashSort
    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

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

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

Post by Lost Zergling »

Archice buggy 0.996c 3/4

Code: Select all

'==========================================================================================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->Tag0<>LIST_RES Then : this.TrackCompute :  bTracking=0 : End If   
    If this.IsDestroyed=1 Then : Print "LZLE error - List.Root : Error List destroyed : instance can't be re-used" : Sleep : Return 0 : End If
    this.RootPrivate
    If pLocalMove<>0 Then
        If pLocalMove->ListData<>0 Then
            # IF TagMode=0
            *pLocalMove->ListData->str_tag_C(1)=""
            # ELSE
            pLocalMove->ListData->str_tag_C(1)=""
            # ENDIF
        End If
        pLocalMove->pBranch=0 :  pLocalMove->Tag0=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->Tag0=""
        If this.pWhyteMove->pNext<>0 And pWhyteMove->pNext->Tag0<>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 pGarbage=0 Then  ' This.Tag(LIST_DEL) :
        This.BlindTag(LIST_DEL) : pGarbage=this.pNode : pGarbage->pPrev=pFlatRoot : this.Val(LIST_DEL) :
        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->Tag0<>"" 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->Tag0=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.NodeRecycle : this.pNode=AllowCake : pNode->Tag0="" : pLocalMove=pNode : pNode->pNext=pGarbage->pNext
    # IF TagMode=0
        If pLocalMove->ListData<>0 Then : *pLocalMove->ListData->str_tag_C(1)="" : End If
    # ELSE
        If pLocalMove->ListData<>0 Then : pLocalMove->ListData->str_tag_C(1)="" : End If
    # ENDIF
    pLocalMove->pBranch=0 :  pLocalMove->Tag0=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 : bfStepZero=0
    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
    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
    Wend : this.bHashStepRev=0 : Return 0
End Property

Property List.KeyStep As Byte : While this.HashStep=1 : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev As Byte : While this.HashStepRev=1 : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : End If : Wend : End Property
Property List.KeyStep(ub as uByte) As Byte : While this.HashStep=1 : If pNode->Tag1=ub Then : Return 1 : End If : Wend : End Property
Property List.KeyStepRev(ub as uByte) As Byte : While this.HashStepRev=1 : If pNode->Tag1=ub Then : Return 1 : End If : Wend : End Property

'Numeric parse optimization
Property List.nCurLevel As Byte : Return uB_CurLevel  : End Property
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->Tag1<>0 And pNode->Tag1<>255 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->Tag1<>0 And pNode->Tag1<>255 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>DEF_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 : Str_tmp=this.HashTag ' If pFirstNode->Tag1<>"" Then : Str_tmp=pFirstNode->Tag1 & pNode->Tag0 : Else : Str_tmp=this.HashTag  : End If ': If ubKeysRegister=1 Then : pFirstNode->Tag1=Left(Str_tmp, Len(Str_tmp)-istep) : End If
        End If
        iLenStrTmp=Len(Str_tmp)
        If iLenStrTmp>DEF_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
            If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
            While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  Wend   
            pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
            iLenStrTmp=Len(Str_tmp) ': While iLen<Len(Str_tmp) : this.UpLevel : Str_tmp=this.HashTag :  Wend  '  pNode=pFirstNode->pNext : 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
                *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
                If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If
                While iLen<iLenStrTmp : pNode=pFirstNode->pBranch : pFirstNode=pFirstNode->pPrev : iLenStrTmp=Len(Str_tmp)-iLenpNode :  Str_tmp=Left(Str_tmp, iLenStrTmp) : If MAX_HASHLEN=1 Then : iLenpNode=1 : Else : iLenpNode=Len(pNode->Tag0) : End If :  Wend   
                pLastNode=pFirstNode->pBranchLastNode : uCount=pFirstNode->BranchCount
                iLenStrTmp=Len(Str_tmp) ' 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 uTag=0 Then
                If bSeekMethod_TMP=2 Then : pTemp = this.pLastNode : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else : pTemp = pTemp02 : While ( pTemp- >Tag0<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                End If
            Else : uB_tmp=0
                If bSeekMethod_TMP=2 Then
                    pTemp = this.pLastNode  ' While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                Else
                    pTemp = pTemp02 ' While ( pTemp->Tag1<>Str_tmp  AndAlso pTemp<>pLastNode ) : pTemp = pTemp->pNext : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uTag)<>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                End If
            End If
        Else : uB_tmp=0
            If bSeekMethod_TMP=2 Then
                pTemp = this.pLastNode : If pTemp=pWhyteMove Then : pTemp = pTemp->pPrev : End If
                If uSortTag=0 Then : While ( pTemp->Tag0>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                Else  '  While ( pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  And pTemp<>pTemp02 ) : pTemp = pTemp->pPrev : Wend
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ELSE                   
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pTemp02) : pTemp = pTemp->pPrev : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)>Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                    # ENDIF
                End If
                If pTemp=pLastNode Then : IsLast=1 : End If : If pTemp=pFirstNode Then : pTemp=pTemp->pNext : End If
            Else                 
                If uSortTag=0 Then : pTemp=pTemp02 : While (pTemp->Tag0<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->Tag0<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If ': Print "**1" : sleep
                Else  'While (pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp<>pLastNode) : pTemp=pTemp->pNext : Wend : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    pTemp=pTemp02
                    # IF TagMode=0
                        If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                        If *pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    # ELSE                   
                        If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  Then : uB_tmp=1 : End If : End If
                        While (uB_tmp=1 AndAlso pTemp<>pLastNode) : pTemp = pTemp->pNext : If pTemp->ListData<>0 Then : If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp Then : uB_tmp=1 : End If : End If : Wend
                        If pTemp->ListData->str_tag_C(uSortTag)<Str_tmp  AndAlso pTemp=pLastNode Then : IsLast=1 : End If
                    # ENDIF
                End If
            End If
        End If
        If uTag=0 Then : Str_tmp2=pTemp- >Tag0  ':  Print "**2" : sleep
        Else 'Str_tmp2=Str(pTemp- >Tag1)
            # IF TagMode=0
                Str_tmp2=*pTemp- >ListData->str_tag_C(uTag)
            # ELSE
                Str_tmp2=pTemp- >ListData->str_tag_C(uTag)
            # ENDIF
        End If
        If Str_tmp2=Str_tmp And bHashKeyUnique=1 Then : this.pNode = pTemp
        ElseIf Str_tmp2=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
            If uTag=0 Then : pTemp03->Tag0 = Str_tmp
            Else 'pTemp03->Tag1 = CuByte(Str_tmp)
                # IF TagMode=0
                    *pTemp03->ListData->str_tag_C(uTag) = Str_tmp
                # ELSE
                    pTemp03->ListData->str_tag_C(uTag) = Str_tmp
                # ENDIF
            End If
            HadHashTag=0 : pFirstNode->BranchCount+=1 : pNode = pTemp03
            If bTrackMultiKeys>0 And bCopyCatRelation=0 Then                 
                If Str_tmp2=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
            pTemp03 = this.pLastNode : this.uCount+=1 : pTemp03->pNext = this.AllowCake 'And eat it
            pTemp03->pNext->pPrev = this.pLastNode
            If uTag=0 Then : pTemp03->pNext->Tag0 = Str_tmp
            Else ': pTemp03->pNext->Tag1 = CuByte(Str_tmp)
                # IF TagMode=0
                    *pTemp03->pNext->ListData->str_tag_C(uTag) = Str_tmp
                # ELSE
                    pTemp03->pNext->ListData->str_tag_C(uTag) = Str_tmp
                # ENDIF
            End If
            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 Str_tmp2=Str_tmp Then : this.HoldBack(bTrackMultiKeys) : End If
            End If
     '  Else : Print "LZLE error - attempt to clean process and aborting."  : Print this.DropAll & " / " & this.NodeCount : sleep : system               If bSeekMethod_TMP=2 Then : Print "Pt 9" : sleep :  End If
        End If
       
        If iLenCumul<iLen Then
            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->Tag0 = LIST_RES ' : Else : pTemp03->pNext->Tag1 = 3 : End If ' pTemp03->pNext- >Tag0 = 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 : 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_testTMP : str_Tag=str_testTMP
    this.pFirstNode->pBranchLastNode = this.pLastNode
    If this.pNode->Tag1=0 Then :  If HadHashTag=1 Then : HadHashTag=2 : End If : If bRHByPass=0 Then : this.pNode->Tag1=1 : End If : 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     
    Return HadHashTag
End Property

Property List.HashTag As String
    Dim As ListNode Ptr pTemp01= this.pFirstNode, pTemp02=this.pNode   
   ' this.TrackSecure
    pTemp01 = this.pFirstNode : pTemp02 = this.pNode
    If pFirstNode->pBranch<>pFlatRoot Then : Str_tmp = this.pnode->Tag0 'si pas ds contexte flat root on prends la clef Tag0
    ElseIf this.pnode->ListData=0 Then : Str_tmp = "Out Of Range"
    Else : Str_tmp = *this.pnode->ListData->str_flat_tag  : End If
    While pTemp01->pPrev<>0
        pTemp02 = pTemp01->pBranch
        Str_tmp = pTemp02->Tag0  + Str_tmp                 
        pTemp01 = pTemp01->pPrev
    Wend   
    Return Str_tmp
End Property

Property List.HasTagTree(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->Tag0 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    ElseIf this.bSeekMethod=2 Then
        pTemp = this.pLastNode
        While (pTemp->pPrev <> 0 And pTemp->Tag0 <> 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->Tag0 <> str_Tag  AND pTemp <> this.pLastNode ) : pTemp = pTemp->pNext : Wend
    End If   
    If pTemp->Tag0 = 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.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 : pNode=pGarbage '   
    this.uCount = this.pFirstNode->BranchCount : pLastNode=this.pFirstNode->pBranchLastNode :' uB_tmp=uB_IsTree : uB_IsTree=1
    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.HasTagTree(Str_tmp)=1 Then           
            this.pNode = this.pSearchNode
            # IF TagMode=0
                If pNode->ListData<>0 Then : str_testTMP=*this.pNode->ListData->str_tag_C(1) : Else : str_testTMP="" :  End If
            # ELSE
                If pNode->ListData<>0 Then : str_testTMP=this.pNode->ListData->str_tag_C(1) : Else : str_testTMP="" :  End If
            # ENDIF
            If str_testTMP="*" Then : HadHashTag=1 : IsEtoile=1 : i=t
            ElseIf str_testTMP="!*" Then : HadHashTag=0 : i=t
            ElseIf str_testTMP="!" 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 : uB_IsTree=uB_tmp : Return 1 : Else : uB_IsTree=uB_tmp : If bHashStepRev=1 Then : Return this.KeyStepRev : Else : Return this.KeyStep :  End If  : End If      KO !           
            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 ': uB_IsTree=uB_tmp
    If HadHashTag=1 Then : bSearchRes=1 : pSearchNode=pNode
        If bAutoCursor=1 Then : Return 1
        ElseIf bAutoCursor=2 Then : If pNode->Tag1=0 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
    Dim pContextRetour As ListContext
    pContextRetour.pNode=pNode : pContextRetour.pFirstNode=This.pFirstNode : pContextRetour.pLastNode=This.pLastNode : pContextRetour.uCount=This.uCount
    this.Root : If this.HasHashTag(str_Tag)=1 Then : If pNode->Tag1<>0 And pNode->Tag1<>255 Then : Return 1 : Else : Return 0 : End If : Else : Return 0 : End If
    pNode=pContextRetour.pNode : This.pFirstNode=pContextRetour.pFirstNode : This.pLastNode=pContextRetour.pLastNode : This.uCount=pContextRetour.uCount
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->Tag0=LIST_RES Or pNode->Tag0=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 pFirstNode->Tag0<>LIST_RES Then : bAlrdyTracked=0 : this.TrackCompute : 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 : Str_tmp=this.HashTag : pLatestHTag=0  ' If uTag=0 Then : Str_tmp=this.HashTag : Else : Str_tmp=pNode->Tag1 : 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é  bNFflag
        If this.bNFmethod<>1 Then : Return 0 : ElseIf this.pNode->Tag1=255 Then : Return 0 : ElseIf bHashStepRev=1 And pNode->pNext->Tag0=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->Tag0=this.pNode->Tag0 : pTemp1->Tag1=255
        pTemp1->pBranchLastNode=this.pNode->pBranchLastNode
        If pTemp2=pLastNode Then : pLastNode=pTemp1 : End If
        this.pNode->pBranch->pBranch=pTemp1 : this.pNode->pBranch=0
        If this.pNode->ListData=0 Then : this.pNode->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pNode->ListData : this.FlatTagSet(Str_tmp)  ' *this.pNode->ListData->str_flat_tag = 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->Tag0=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->Tag0=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->Tag0=LIST_RES Then
        pLocalRoot=this.pNode->pPrev : IsLastNode=1 :  pLocalRoot->Tag1=0 :
        If this.pFirstNode->pBranchLastNode=0 Then : pLocalRoot = this.pFirstNode : pLocalRoot->pBranch->pBranch=0 :  pLocalRoot->Tag1=0 : pLocalRoot->Tag0=LIST_DEL : End If
    ElseIf this.pNode=this.pFirstNode->pBranchLastNode Then       
        If this.pNode->pPrev->Tag0=LIST_RES Then : pLocalRoot=this.pNode->pPrev : IsLastNode=1 : pLocalRoot->Tag1=0 :  pLocalRoot->Tag0=LIST_DEL
        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->Tag1=255 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
        pFlatRoot->pNext->pPrev=pTemp2 : pTemp2->pPrev=pFlatRoot : pTemp2->pNext=pFlatRoot->pNext : pFlatRoot->pNext=pTemp2
        pTemp2->Tag0=LIST_DEL : pTemp2->Tag1=0 : 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->Tag1=0 Or pNode->Tag1=255 Then : this.NodeFlat : this.NodeRecycle2 : End If ' RECURSIF
            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
        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->Tag0<>LIST_RES Then : pTemp2->pPrev->pNext=pTemp2->pNext : End If
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pTemp2->ListData : this.FlatTagSet(Str_tmp) ' *pTemp2->ListData->str_flat_tag = Str_tmp ' : pTemp2->pPrev= this.pLastNode :
            pTemp1->pNext = pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode=pTemp2 : 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
            If pTemp2->ListData=0 Then : pTemp2->ListData=this.AllowPanCake : End If : pCurrentPanCakeTMP=pTemp2->ListData : this.FlatTagSet(Str_tmp) ' *pTemp2->ListData->str_flat_tag = Str_tmp
            pTemp1->pNext=pTemp2 : this.pLastNode=pTemp2 : this.pFirstNode->pBranchLastNode = pTemp2 : pTemp2->pPrev=pTemp1 : pTemp2->pNext=0
            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->Tag1=0 Or pNode->Tag1=255 Then : this.NodeFlat : this.NodeRecycle2  : End If  ' RECURSIF
            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
        End If
    End If
    If bTracking=1 And pTemp6<>0 Then
        If pFirstNode->Tag0<>LIST_RES Then :  bAlrdyTracked=0 : this.TrackCompute : End If     ' this.TrackSecure this.NodeRecycle :  pNode=pTemp6 :
        this.NodeRecycle : pNode=AllowCake : pNode->pBranchLastNode=pTemp6 : pLocalMove=pNode : pLocalMove->Tag0=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 : Dim bTagExists As Byte : Dim As Byte uTagTmp=uTag, IsLastOne=0
    If this.pNode->ListData=0 Then : Return 0 : End If ' If pNode=pLocalMove Then : Return 0 : Else  Print "LZLE : RestoreHash : failure or non-value" :
    pTemp=this.pnode
    # IF TagMode=0
        If uTag=0 Then : str_tmp=*this.pNode->ListData->str_flat_tag : Else : str_tmp=*this.pNode->ListData->str_tag_C(uTag) : End If
    # ELSE
        If uTag=0 Then : str_tmp=*this.pNode->ListData->str_flat_tag : Else : str_tmp=this.pNode->ListData->str_tag_C(uTag) : End If
    # ENDIF
    If str_tmp="" Then : Return 0 : End If : pTmpPrev=this.pnode->pPrev : pTmpNext=this.pnode->pNext
    'Vérification du contexte
    If pNode->pNext=pEndFlat And pNode->pPrev=pFirstNode Then : IsLastOne=1 : End If
    this.NodeRecycle
    If this.pNode=this.pEndFlat Or pFirstNode->pBranch<>pFlatRoot  Then : this.Up : 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
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0  : Else : pTemp->Tag0= Str(this.pnode->Tag1)  : End If
        pMove=this.pnode : pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) ' *pMove->ListData->str_flat_tag=str_tmp :
        bTagExists=3 ' swap
    ElseIf bTagExists<>0 And pNode->Tag1<>0  Then ' tag deja existant et "vraie" clef
        'Gestion des modes (RHmethod)
        If uTag=0 Then
            If bRHmethod=-1 Then : pTemp->Tag0= this.pnode->Tag0 : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= this.pnode->Tag0  : pMove=this.pnode :  pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) : bTagExists=2 ' swap *pMove->ListData->str_flat_tag=str_tmp
            Else : If pNode->Tag1=255 Then : pNode->Tag1=1 : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        Else
            If bRHmethod=-1 Then : pTemp->Tag0= Str(this.pnode->Tag1)  : pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :'envoi garbage
            ElseIf bRHmethod=1 Then : pTemp->Tag0= Str(this.pnode->Tag1)  : pMove=this.pnode : pCurrentPanCakeTMP=pMove->ListData : this.FlatTagSet(str_tmp) : bTagExists=2 ' swap *pMove->ListData->str_flat_tag=str_tmp :
            Else : If pNode->Tag1=255 Then : pNode->Tag1=1 : End If : this.RootPrivate : this.pNode=this.pFlatRoot : this.Branch : pNode=pTemp : Return 0  ' bypass
            End If   
        End If
    Else
        If uTag=0 Then : pTemp->Tag0= this.pnode->Tag0 : Else : pTemp->Tag0=Str(this.pnode->Tag1) : End If
        pLocalMove=this.pnode : pLocalMove->Tag0=LIST_DEL : this.pFlatRoot->pBranch->BranchCount-=1 ':  pLocalMove->pBranch=0  :
    End If
    uTag=uTagTmp
    'Swapping mémoire
    pNode->Tag1=pTemp->Tag1
    pTemp->pPrev->pNext=pTemp->pNext : pTemp->pNext->pPrev=pTemp->pPrev
    pTemp->pPrev=this.pnode->pPrev : pTemp->pNext=this.pnode->pNext  : *pTemp->ListData->str_flat_tag=""
  '  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->Tag1=""  '  pnode->pBranch->Tag1=""
        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<>3 Then : this.pnode=pLocalMove : this.pnode->pPrev=pTmpPrev : this.pnode->pNext=pTmpNext :  pLocalMove->pBranch=0  : pLocalMove->Tag1=0 : pLocalMove->Tag0=LIST_DEL :
    Else : pNode=pMove : pTmpPrev->pNext=pNode : pTmpNext->pPrev=pNode : pNode->pPrev=pTmpPrev : pNode->pNext=pTmpNext :
    End If : If IsLastOne=1 Then : this.Up : bfStepZero=1 : pNode=pLastNode : End If '
    Return 1
End Property

Property List.Check(ub As uByte) As Byte : this.pNode->Tag1=ub : Return 1 : End Property
Property List.Check As Byte : Return this.pNode->Tag1 : 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>MAX_HASHLEN Then : Print "LZLE warning : HashLen Property ignored (deprecated), or must be =< MAX_HASHLEN (constant)" : End If : this.bHashLen=1 : Return 1 : End Property
Property List.KeysRegister(ub As uByte) As Byte : Print "LZLE warning : KeysRegister Property ignored (deprecated)" :  Return 0 : 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+1 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->Tag0=LIST_RES  Or pNode->Tag0=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->Tag1=0 : End If : pNode->BranchCount=0 : Wend
    Else : While this.HashStepTrace And pNode<>pTemp2 :  If bHStepTrace=-1 Then : pFirstNode->Tag1=0 : 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->Tag0=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->Tag0=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->pPrev->Tag0=LIST_RES Then ' :  ? "++0" ' : bAlrdyTracked=0 ': pNode=pNode->pPrev->pNext  :  :  ? "++0"       
    ElseIf pNode->pNext=pTrackTmp Then : If pNode->Tag0<>LIST_DEL And pTrackTmp->Tag0<>LIST_DEL  Then : bAlrdyTracked=1 : End If ' : ? "++1"  And pTrackTmp->Tag0<>LIST_DEL And pNode->pPrev->Tag0<>LIST_ROOT
    ElseIf pNode->pPrev=pTrackTmp Then : bAlrdyTracked=1 ' : ? "++2"   ':  If pNode->Tag0="" Then : bAlrdyTracked=0 : End If
    ElseIf pTrackTmp=pNode Then :
        If pNode->pBranchLastNode=0 Then : this.Root : bTracking=0 : Return 0  : End If
        pFirstNode=pFirstNodeTMP : pLastNode=pLastNodeTMP : this.uCount=pFirstNode->BranchCount  ': ? "++2"  ' ->pBranchLastNode : bAlrdyTracked=0 : this.TrackCompute : '
      '  ? pNode->pPrev->Tag0 & " - " & pFirstNode->Tag0 & " count=" & this.uCount & " - " & pLastNode->Tag0
       ' If pNode->Tag0<>LIST_RES Then : bAlrdyTracked=1 : End If
        If uCount>0 Then : bAlrdyTracked=1  : End If
    End If '
    If pNode->pBranchLastNode->Tag0=LIST_DEL Or bColTrackLocked=1 Then : this.Root : bTracking=0 :  Return 0 : End If
    If pNode->pBranchLastNode<>0  And pNode->pBranchLastNode->Tag0<>LIST_RES Then
        pTrackTmp=pNode : pNode=pNode->pBranchLastNode : bTracking=1 : pFirstNodeTMP=pFirstNode : pLastNodeTMP=pLastNode
        If bTrackingMethod=1 Or pFirstNode->Tag0<>LIST_RES Then : bAlrdyTracked=0 : this.TrackCompute : End If
        If pNode=pEndFlat Then : this.Root : bTracking=0 :  Return 0 : End If :  this.TrackSecure :       
        Return 1
    End If : bAlrdyTracked=0 : 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->Tag0<>LIST_DEL And pNode->Tag0<>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->Tag0=LIST_DEL
        If this.Tracks(by).pNode->Tag0=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->Tag0="" : bAlrdyTracked=0
        Return 1
    End If
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.996c

Post by Lost Zergling »

Archive 0.996c 4/4

Code: Select all

Property List.TrackSet As Byte : Return this.TrackSet(0) : End Property
Property List.TrackSet(by As Byte) As Byte
    this.NodeRecycle :  this.Tracks(by).pNode=pNode ' : If pNode->pBranchLastNode<>0 Then : this.Tracks(by).pNode=pNode->pBranchLastNode  : Else : this.Tracks(by).pNode=pNode : End If
    pTrackTmp=0 : bAlrdyTracked=0 : this.TrackCompute : bTracking=1
    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->Tag0<>LIST_RES Then : Return 1 : Else : For i=0 To MAX_COLS : 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_ASIDE 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->Tag0 : 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_ASIDE 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
    pTrackTmp=pNode : pFirstNodeTMP=pFirstNode : pLastNodeTMP=pLastNode
    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
    this.TrackSecure
    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.TagLenRedim(ub as uByte) as Byte
    If ub=1 Then : uB_RedimTagLen=ub : Return 1 : End If
    # IF TagMode=0 Or  TagMode=1
        uB_RedimTagLen=ub : Return 1
    # ELSE
        Print "Lzle warning : ListTagLenRedim(0) - No Redim - is only valid on # Define TagMode 0 and  # Define TagMode 1" : Return 0
    # ENDIF
End Property

Property List.TagLenDefault(ub as uByte) As Byte
    # IF TagMode=0
        uB_TagC_Len(uTag)=ub : Return 1
    # ELSE
        Print "Lzle warning : TagLenDefault (dynamic) is only valid on # Define TagMode=0" : Return 0
    # ENDIF
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->Tag1=0 : pLocalMove->Tag0=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->Tag0=LIST_DEL : pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0
        pTemp3=pNode : pNode=pTemp1 : this.Val("") :
        If pTemp1->ListData<>0 Then           
            For i=MIN_COLS To MAX_COLS
                # IF TagMode=0
                    *pTemp1->ListData->str_tag_C(i)=""
                # ELSE
                    pTemp1->ListData->str_tag_C(i)=""
                # ENDIF
            Next i
            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->Tag0=LIST_DEL
    If pTemp1->ListData<>0 Then         
        For i=MIN_COLS to MAX_COLS
            # IF TagMode=0
                *pTemp1->ListData->str_tag_C(i)=""
            # ELSE
                pTemp1->ListData->str_tag_C(i)=""
            # ENDIF
        Next i
    End If
    pTemp1->pBranchLastNode=0 : pTemp1->BranchCount=0
    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     
    Dim As ListContainer Ptr P_tmp : Dim As uInteger i
    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
            If pFlatRoot->pNext->ListData->str_flat_tag<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_flat_tag) : End If
            If pFlatRoot->pNext->ListData->str_item<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_item) : End If
            # IF TagMode=0
                For i=MIN_COLS To MAX_COLS :  If pFlatRoot->pNext->ListData->str_tag_C(i)<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_tag_C(i)) : End If  : Next i
        '    # ELSE
        '        If pFlatRoot->pNext->ListData->str_tag_C<>0 Then : _Deallocate(pFlatRoot->pNext->ListData->str_tag_C) : End If
            # ENDIF
            _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
        P_tmp=AllowPanCake : If P_tmp->str_flat_tag<>0 Then : _Deallocate(P_tmp->str_flat_tag) : End If : If P_tmp->str_item<>0 Then : _Deallocate(P_tmp->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If P_tmp->str_tag_C(i)<>0 Then : _Deallocate(P_tmp->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate(P_tmp) : pPanTemp=pPanCakeGarbage->pNextContainer
    Wend
    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
    Dim As uByte i
    If this.IsDestroyed=1 Then : Return 0 : End If
    this.Root : this.DropAll : IsDestroyed=1
    If pPanCakeGarbage<>0 Then
        If pPanCakeGarbage->str_flat_tag<>0 Then : _Deallocate(pPanCakeGarbage->str_flat_tag) : End If
        If pPanCakeGarbage->str_item<>0 Then : _Deallocate(pPanCakeGarbage->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pPanCakeGarbage->str_tag_C(i)<>0 Then : _Deallocate(pPanCakeGarbage->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _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
        If pEndFlat->ListData->str_flat_tag<>0 Then : _Deallocate(pEndFlat->ListData->str_flat_tag) : End If
        If pEndFlat->ListData->str_item<>0 Then : _Deallocate(pEndFlat->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pEndFlat->ListData->str_tag_C(i)<>0 Then : _Deallocate(pEndFlat->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pEndFlat->ListData : this.pEndFlat->ListData=0     
    End If
    If this.pLastLASTNode->ListData<>0 Then
        If pLastLASTNode->ListData->str_flat_tag<>0 Then : _Deallocate(pLastLASTNode->ListData->str_flat_tag) : End If
        If pLastLASTNode->ListData->str_item<>0 Then : _Deallocate(pLastLASTNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pLastLASTNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pLastLASTNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pLastLASTNode->ListData : this.pLastLASTNode->ListData=0
    End If
    If this.pGarbage->ListData<>0 Then
        If pGarbage->ListData->str_flat_tag<>0 Then : _Deallocate(pGarbage->ListData->str_flat_tag) : End If
        If pGarbage->ListData->str_item<>0 Then : _Deallocate(pGarbage->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pGarbage->ListData->str_tag_C(i)<>0 Then : _Deallocate(pGarbage->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pGarbage->ListData : this.pGarbage->ListData=0
    End If
    If this.pWhyteMove->ListData<>0 Then
        If pWhyteMove->ListData->str_flat_tag<>0 Then : _Deallocate(pWhyteMove->ListData->str_flat_tag) : End If
        If pWhyteMove->ListData->str_item<>0 Then : _Deallocate(pWhyteMove->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pWhyteMove->ListData->str_tag_C(i)<>0 Then : _Deallocate(pWhyteMove->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pWhyteMove->ListData : this.pWhyteMove->ListData=0
    End If
    If this.pFirstFIRSTNode->ListData<>0 Then
        If pFirstFIRSTNode->ListData->str_flat_tag<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_flat_tag) : End If :
        If pFirstFIRSTNode->ListData->str_item<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pFirstFIRSTNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pFirstFIRSTNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _Deallocate this.pFirstFIRSTNode->ListData : this.pFirstFIRSTNode->ListData=0
    End If
    If this.pNode->ListData<>0 Then
        If pNode->ListData->str_flat_tag<>0 Then : _Deallocate(pNode->ListData->str_flat_tag) : End If :
        If pNode->ListData->str_item<>0 Then : _Deallocate(pNode->ListData->str_item) : End If
        # IF TagMode=0
            For i=MIN_COLS To MAX_COLS :  If pNode->ListData->str_tag_C(i)<>0 Then : _Deallocate(pNode->ListData->str_tag_C(i)) : End If  : Next i
        # ENDIF
        _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
    Return 0
End Property

'==========================================================================================DATA EXCHANGE
Property List.SnatchBelow(pList As List) As Byte
  Dim As ListNode Ptr pTemp1, pTemp2
    If pNode->Tag0=LIST_RES Or pNode->Tag0=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->Tag1=0 : pLocalMove->Tag0=LIST_DEL
            If this.Snatch(pList) <> 1 Then : this.NodeRecycle : pLocalMove=pFirstNode : pFirstNode->pBranch->pBranch=0 : pFirstNode->pBranch=0 :  pLocalMove->Tag1=0 : pLocalMove->Tag0=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->Tag1=0 : pLocalMove->Tag0=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->Tag0=LIST_DEL Then : If pFirstNode->pBranch=0 Then : pNode=pGarbage->pNext : Else : Return -1 : End If
    ElseIf pNode->Tag0=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 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
Post Reply