1. 2. 3. 4. 5. 6. 7. BuilderVisitor XMLMetadataVisitor ProcessMetadataVisitor FolderRenameVisitor ComparerVisitor SyncerVisitor XMLWriterVisitor 1. BuilderVisitor 2. ComparerVisitor 3. Builds the merged tree. Compares and updates the state of each node. SyncerVisitor Takes the updated state of each node and performs an action to keep them synchronized. BuilderVisitor Nothing else to build, so we Since traverse Now, “A” is thethe firstcontents folder toofbe Build FolderCompareObject return all the way back to Traverse build, “School Finally, allwe Work” the and build build and “Results.txt” or build populate new with name “School Work”, RootCompareObject. Now, we tree populate FileCompareObjects objects. and for In thisthe case, information build or at and populate build “CueSheet.docx” information and at “C:\Users\Wysie\Desktop\A” FolderCompareObjects “Final.pdf” index 0. and “Proposal.docx” will be index 0. information at index populate created. and populate index 0. 0. RootCompareObject string[] paths paths[0] = “C:\Users\Wysie\Desktop\A” paths[1] = “C:\Users\Wysie\Desktop\B” paths[2] = “C:\Users\Wysie\Desktop\C” Index 0: C:\Users\Wysie\Desktop\A Index 1: C:\Users\Wysie\Desktop\B Index 2: C:\Users\Wysie\Desktop\C FolderCompareObject FileCompareObject FileCompareObject name = “School Work” name = “CueSheet.docx” name = “Results.txt” numOfPaths = 3 numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] exists; exists[0] = true exists[1] = false exists[2] = false string[] hash; hash[0] = “QWERTY”; hash[1] = null; hash[2] = null; string[] hash; hash[0] = “AAAAA”; hash[1] = null; hash[2] = null; long[] lastModified; long[0] = 99999; long[1] = 0; long[2] = 0; long[] lastModified; long[0] = 70000; long[1] = 0; long[2] = 0; FileCompareObject FileCompareObject name = “Final.pdf” name = “Proposal.docx” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] exists; exists[0] = true exists[1] = false exists[2] = false string[] hash; hash[0] = “ZXCVB”; hash[1] = null; hash[2] = null; string[] hash; hash[0] = “ASDFG”; hash[1] = null; hash[2] = null; long[] lastModified; long[0] = 30000; long[1] = 0; long[2] = 0; long[] lastModified; long[0] = 10000; long[1] = 0; long[2] = 0; “CueSheet.docx” is found in Traverse Since “Results.txt” “School andisbuild Work” alsoor found does populate not in “B”. We now populate index 1 of treeWe exist “B”. for in “B”, nowthe populate entire index portion 1 of “CueSheet.docx” with “C:\Users\Wysie\Desktop\B” remains “Results.txt” unchanged. with information. information. RootCompareObject string[] paths paths[0] = “C:\Users\Wysie\Desktop\A” paths[1] = “C:\Users\Wysie\Desktop\B” paths[2] = “C:\Users\Wysie\Desktop\C” Index 0: C:\Users\Wysie\Desktop\A Index 1: C:\Users\Wysie\Desktop\B Index 2: C:\Users\Wysie\Desktop\C FolderCompareObject FileCompareObject FileCompareObject FileCompareObject name = “School Work” name name==“CueSheet.docx” “CueSheet.docx” name = “Results.txt” numOfPaths = 3 numOfPaths numOfPaths==33 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] bool[]exists; exists; exists[0] exists[0]==true true exists[1] exists[1]==false true exists[2] exists[2]==false false bool[] exists; exists[0] = true exists[1] = true false exists[2] = false string[] string[]hash; hash; hash[0] hash[0]==“QWERTY”; “QWERTY”; hash[1] hash[1]==null; “MNBVC”; hash[2] hash[2]==null; null; string[] hash; hash[0] = “AAAAA”; hash[1] = “VVBBB”; null; hash[2] = null; long[] long[]lastModified; lastModified; long[0] long[0]==99999; 99999; long[1] long[1]==0; 88888; long[2] long[2]==0; 0; long[] lastModified; long[0] = 70000; long[1] = 90000; 0; long[2] = 0; FileCompareObject FileCompareObject name = “Final.pdf” name = “Proposal.docx” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] exists; exists[0] = true exists[1] = false exists[2] = false string[] hash; hash[0] = “ZXCVB”; hash[1] = null; hash[2] = null; string[] hash; hash[0] = “ASDFG”; hash[1] = null; hash[2] = null; long[] lastModified; long[0] = 30000; long[1] = 0; long[2] = 0; long[] lastModified; long[0] = 10000; long[1] = 0; long[2] = 0; RootCompareObject “Final.pdf” Traverse and does build notor exist. populate “School Work” exists in “C”. tree for “Proposal.docx” However, Populate index 2 in “C”. “C:\Users\Wysie\Desktop\C” exists. Populate at index 2. string[] paths paths[0] = “C:\Users\Wysie\Desktop\A” paths[1] = “C:\Users\Wysie\Desktop\B” paths[2] = “C:\Users\Wysie\Desktop\C” Index 0: C:\Users\Wysie\Desktop\A Index 1: C:\Users\Wysie\Desktop\B Index 2: C:\Users\Wysie\Desktop\C FolderCompareObject FileCompareObject FileCompareObject name = “School Work” name = “CueSheet.docx” name = “Results.txt” numOfPaths = 3 numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = true false bool[] exists; exists[0] = true exists[1] = true exists[2] = false bool[] exists; exists[0] = true exists[1] = true exists[2] = false string[] hash; hash[0] = “QWERTY”; hash[1] = “MNBVC”; hash[2] = null; string[] hash; hash[0] = “AAAAA”; hash[1] = “VVBBB”; hash[2] = null; long[] lastModified; long[0] = 99999; long[1] = 88888; long[2] = 0; long[] lastModified; long[0] = 70000; long[1] = 90000; long[2] = 0; FileCompareObject FileCompareObject name = “Final.pdf” name = “Proposal.docx” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = false exists[2] = false bool[] exists; exists[0] = true exists[1] = false false exists[2] = true string[] hash; hash[0] = “ZXCVB”; hash[1] = null; hash[2] = null; string[] hash; hash[0] = “ASDFG”; hash[1] = null; null; hash[2] = “DFGHJK”; long[] lastModified; long[0] = 30000; long[1] = 0; long[2] = 0; long[] lastModified; long[0] = 10000; long[1] = 0; long[2] = 10000; 0; There are many other attributes that are left out, such as priority, new name, creation time, among many others. For a more detailed explanation, please take a look at the source code comments. ComparerVisitor Finally, Now, For It Based will “Proposal.docx”, it first now on “Results.txt” will the visit visit traverse last “School modified the isitvisited. Work”. exists in Since contents 0 “CueSheet.docx”. date, Again, and the it 2,itexists but exists of one “School not at ininin index index Since 1.Work”. Comparing 00is and itand exists more For 1. ComparerVisitor will now visit index “Final.pdf”, the in updated This index hash time 2, 0but then of round, and index since not the 1 but inthe it 0one index and only not one at2 inexists 1, index at shows 2, the the tree. algorithm in that comparison 1. index Thus, index they 1 issource 0,found are will source will identical. set position to beposition source be done more Thus, willwill be position again source between set updated. to be 0.position to set 0Source and 0.to 0. 1. will position be setisto1.0. RootCompareObject string[] paths paths[0] = “C:\Users\Wysie\Desktop\A” paths[1] = “C:\Users\Wysie\Desktop\B” paths[2] = “C:\Users\Wysie\Desktop\C” Index 0: C:\Users\Wysie\Desktop\A Index 1: C:\Users\Wysie\Desktop\B Index 2: C:\Users\Wysie\Desktop\C FolderCompareObject FolderCompareObject FileCompareObject FileCompareObject name Work” name==“School “School Work” name = “CueSheet.docx” name = “Results.txt” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = true exists[2] = false bool[] exists; exists[0] = true exists[1] = true exists[2] = false string[] hash; hash[0] = “QWERTY”; hash[1] = “MNBVC”; hash[2] = null; string[] hash; hash[0] = “AAAAA”; hash[1] = “VVBBB”; hash[2] = null; long[] lastModified; long[0] = 99999; long[1] = 88888; long[2] = 0; long[] lastModified; long[0] = 70000; long[1] = 90000; long[2] = 0; srcPosition = 0 srcPosition = 1 numOfPaths = 3 numOfPaths = 3 bool[] exists; bool[] exists[0]exists; = true exists[0] = true exists[1] = false exists[2] = = true exists[1] false exists[2] srcPosition==true 0 FileCompareObject FileCompareObject FileCompareObject FileCompareObject name name==“Final.pdf” “Final.pdf” name name==“Proposal.docx” “Proposal.docx” numOfPaths numOfPaths==3 3 numOfPaths numOfPaths==3 3 bool[] bool[]exists; exists; exists[0] exists[0]==true true exists[1] = false exists[1] = false exists[2] = false bool[] bool[]exists; exists; exists[0] = true exists[0] = true exists[1] = false exists[1] = false exists[2] = true string[] hash; string[] hash[0] =hash; “ZXCVB”; hash[0] “ZXCVB”; hash[1] ==null; hash[1] null; hash[2] ==null; string[] hash; string[] hash[0] =hash; “ASDFG”; hash[0] “ASDFG”; hash[1] ==null; hash[1] null; hash[2] ==“ASDFG”; hash[2] = null; hash[2] = “DFGHJK”; long[2] = 0;= 0 srcPosition long[2] = 10000; srcPosition =0 exists[2] = false long[] lastModified; long[0]lastModified; = 30000; long[] long[1] ==0;30000; long[0] long[2] long[1]==0;0; exists[2] = true long[] lastModified; long[0]lastModified; = 10000; long[] long[1] ==0;10000; long[0] long[2] long[1]==10000; 0; The purpose of source position is for SyncerVisitor to find out which file to propagate. In actual fact, there is another array called priority. All files which are determined to be equal (same hash if create/update, same new name if rename, or file does not exist if delete) are given equal priority. During actual synchronization, only lower priority indexes than that of the source position will be affected. This is to prevent redundant file or folder changes. SyncerVisitor Finally, It Next Then, The willnext itfirst itwill “Results.txt” will node visit visit visit to “School “Final.pdf”. be visited willWork”, be is determine Since “Proposal.docx”. “CueSheet.docx”. visited. source Since the position the source Since source Since is position, source 0, the it will SyncerVisitor With that, all the willfiles now and visit the andcopied be source position then position iscreate over 0, and 1, but to isaindex it0, the folder isand more other 2 when it is is the tree. are now synchronized. folders necessary. positions, determined most updated updated, then and The tothe the be state it will rest, equal, state of propagate itthe of only will the1 node will to propagate the bewill other updated. then to2the locations. be other updated. nodes. RootCompareObject string[] paths paths[0] = “C:\Users\Wysie\Desktop\A” paths[1] = “C:\Users\Wysie\Desktop\B” paths[2] = “C:\Users\Wysie\Desktop\C” Index 0: C:\Users\Wysie\Desktop\A Index 1: C:\Users\Wysie\Desktop\B Index 2: C:\Users\Wysie\Desktop\C FolderCompareObject FileCompareObject FileCompareObject name = “School Work” name = “CueSheet.docx” name = “Results.txt” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = true exists[2] = true false bool[] exists; exists[0] = true exists[1] = true exists[2] = true false string[] hash; hash[0] = “QWERTY”; hash[1] = “QWERTY”; “MNBVC”; hash[2] = “QWERTY”; null; string[] hash; hash[0] = “VVBBB”; “AAAAA”; hash[1] = “VVBBB”; hash[2] = “VVBBB”; null; long[] lastModified; long[0] = 99999; long[1] = 99999; 88888; long[2] = 99999; 0; long[] lastModified; long[0] = 90000; 70000; long[1] = 90000; long[2] = 90000; 0; srcPosition = 0 srcPosition = 1 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = true false exists[2] = true srcPosition = 0 FileCompareObject FileCompareObject name = “Final.pdf” name = “Proposal.docx” numOfPaths = 3 numOfPaths = 3 bool[] exists; exists[0] = true exists[1] = true false exists[2] = true false bool[] exists; exists[0] = true exists[1] = true false exists[2] = true string[] hash; hash[0] = “ZXCVB”; hash[1] = “ZXCVB”;; null; hash[2] = “ZXCVB”;; null; string[] hash; hash[0] = “ASDFG”; hash[1] = “ASDFG”; null; hash[2] = “ASDFG”; long[] lastModified; long[0] = 30000; long[1] = 30000; 0; long[2] = 30000; 0; long[] lastModified; long[0] = 10000; long[1] = 10000; 0; long[2] = 10000; srcPosition = 0 srcPosition = 0 As stated earlier, a priority array in each node is used to determine if a file is actually copied over. We hope this simple presentation will give you a good overview of how the visitor pattern, and in particular, how our merged tree, works. Many other functions and visitors were not explained, please look at the detailed comments in the source code, as well as the developer guide, if you are interested. Traversing the tree can be pre, post, or levelorder traversal, depending on what is needed.
© Copyright 2026 Paperzz