@@ -11,12 +11,15 @@ import (
1111 "sort"
1212 "strconv"
1313
14+ "github.com/juruen/rmapi/archive"
1415 "github.com/juruen/rmapi/log"
1516 "github.com/juruen/rmapi/transport"
1617 "golang.org/x/sync/errgroup"
1718)
1819
19- const SchemaVersion = "3"
20+ const SchemaVersionV3 = "3"
21+ const SchemaVersionV4 = "4"
22+
2023const DocType = "80000000"
2124const FileType = "0"
2225const Delimiter = ':'
@@ -76,37 +79,79 @@ func parseEntry(line string) (*Entry, error) {
7679 return & entry , nil
7780}
7881
82+ func parseSchemaV4 (line string ) (entriesCount int , totalSize int64 , err error ) {
83+ r := NewFieldReader (line )
84+ _ , _ = r .Next () //0
85+ _ , _ = r .Next () //.
86+ entriesCountStr , _ := r .Next () //count?
87+ totalSizeStr , _ := r .Next () //size?
88+
89+ entriesCount , err = strconv .Atoi (entriesCountStr )
90+ if err != nil {
91+ return
92+ }
93+ totalSize , err = strconv .ParseInt (totalSizeStr , 10 , 64 )
94+ if err != nil {
95+ return
96+ }
97+
98+ return
99+ }
100+
79101func parseIndex (f io.Reader ) ([]* Entry , error ) {
80102 var entries []* Entry
81103 scanner := bufio .NewScanner (f )
82104 eof := scanner .Scan ()
83105 if ! eof {
84- return nil , fmt .Errorf ("empty file" )
106+ return nil , fmt .Errorf ("empty index file" )
85107 }
86108 schema := scanner .Text ()
109+ expectedCount := 0
110+ count := 0
111+ var err error
112+ switch schema {
87113
88- if schema != SchemaVersion {
89- return nil , fmt .Errorf ("wrong schema got %s, expected: %s" , schema , SchemaVersion )
90- }
91- for scanner .Scan () {
92- line := scanner .Text ()
93- if line == "" {
94- log .Warning .Printf ("TODO: empty line in index file, ignored" )
95- continue
114+ case SchemaVersionV4 :
115+ eof := scanner .Scan ()
116+ if ! eof {
117+ return nil , fmt .Errorf ("expecting a schema v4 line" )
96118 }
97- entry , err := parseEntry (line )
119+ line := scanner .Text ()
120+ expectedCount , _ , err = parseSchemaV4 (line )
98121 if err != nil {
99- return nil , fmt .Errorf ("cant parse line '%s', %w" , line , err )
122+ return nil , fmt .Errorf ("can't parse v4 line %v" , err )
100123 }
124+ fallthrough
125+ case SchemaVersionV3 :
126+ for scanner .Scan () {
127+ line := scanner .Text ()
128+ if line == "" {
129+ log .Warning .Printf ("TODO: empty line in index file, ignored" )
130+ continue
131+ }
132+ count ++
133+ entry , err := parseEntry (line )
134+ if err != nil {
135+ return nil , fmt .Errorf ("cant parse line '%s', %w" , line , err )
136+ }
101137
102- entries = append (entries , entry )
138+ entries = append (entries , entry )
139+ }
140+ default :
141+ return nil , fmt .Errorf ("unsupported schema %s" , schema )
103142 }
143+ if schema == SchemaVersionV4 {
144+ if count != expectedCount {
145+ log .Warning .Printf ("entries mismatch, expected %d, but was %d" , expectedCount , count )
146+ }
147+ }
148+
104149 return entries , nil
105150}
106151
107152func (t * HashTree ) IndexReader () (io.Reader , error ) {
108153 var w bytes.Buffer
109- w .WriteString (SchemaVersion )
154+ w .WriteString (SchemaVersionV3 )
110155 w .WriteString ("\n " )
111156 for _ , d := range t .Docs {
112157 w .WriteString (d .Line ())
@@ -167,8 +212,9 @@ func (t *HashTree) Rehash() error {
167212 return nil
168213}
169214
170- func addSchema (name string ) string {
171- return name + ".docSchema"
215+ // adds the extensions to filename (for the rm-file header later)
216+ func addExt (name string , ext archive.RmExt ) string {
217+ return name + "." + string (ext )
172218}
173219
174220// / Mirror makes the tree look like the storage
@@ -189,7 +235,7 @@ func (t *HashTree) Mirror(r RemoteStorage, maxconcurrent int) error {
189235 }
190236 log .Info .Printf ("remote root hash different" )
191237
192- rootIndexReader , err := r .GetReader (rootHash , addSchema ("root" ))
238+ rootIndexReader , err := r .GetReader (rootHash , addExt ("root" , archive . DocSchemaExt ))
193239 if err != nil {
194240 return fmt .Errorf ("cannot get root hash %v" , err )
195241 }
0 commit comments