github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/chunks/handle_check_sequential.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package chunksPkg 6 7 import ( 8 "fmt" 9 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/utils" 13 ) 14 15 // CheckSequential checks that the range of blocks in each of three arrays (onDisc, 16 // LocalManifest, RemoteManifest) "cover" the range without gaps. (There may be a bug 17 // for allow_missing chains where gaps are allowed.) It also makes sure than snap-to-grids 18 // happen where they should and that non-snaps have at least appsPerChunks records and 19 // snaps have exactly appsPerChunks records or less. 20 func (opts *ChunksOptions) CheckSequential(fnArray, cacheArray, remoteArray []string, allowMissing bool, report *types.ReportCheck) error { 21 if err := opts.checkSequential("disc", fnArray, allowMissing, report); err != nil { 22 return err 23 } 24 25 if err := opts.checkSequential("cache", cacheArray, allowMissing, report); err != nil { 26 return err 27 } 28 29 if err := opts.checkSequential("contract", remoteArray, allowMissing, report); err != nil { 30 return err 31 } 32 33 return nil 34 } 35 36 // TODO: Can this be made concurrent? 37 func (opts *ChunksOptions) checkSequential(which string, array []string, allowMissing bool, report *types.ReportCheck) error { 38 prev := base.NotARange 39 for _, item := range array { 40 var fR base.FileRange 41 var err error 42 if fR, err = base.RangeFromFilenameE(item); err != nil { 43 return err 44 } 45 46 w := utils.MakeFirstUpperCase(which) 47 if prev != base.NotARange { 48 report.VisitedCnt++ 49 report.CheckedCnt++ 50 if prev != fR { 51 if !prev.Preceeds(fR, !allowMissing) { 52 // try to figure out why 53 if prev.Intersects(fR) { 54 report.MsgStrings = append(report.MsgStrings, fmt.Sprintf("%s: file ranges intersect %s:%s", w, prev, fR)) 55 } else if prev.Follows(fR, !allowMissing) { 56 report.MsgStrings = append(report.MsgStrings, fmt.Sprintf("%s: previous range is after current %s:%s", w, prev, fR)) 57 } else if prev.Preceeds(fR, false) { 58 report.MsgStrings = append(report.MsgStrings, fmt.Sprintf("%s: gap in sequence %d to %d skips %d", w, prev.Last, fR.First, (fR.First-prev.Last-1))) 59 } else { 60 report.MsgStrings = append(report.MsgStrings, fmt.Sprintf("%s: files not sequental %s:%s", w, prev, fR)) 61 } 62 } else { 63 report.PassedCnt++ 64 } 65 } else { 66 report.MsgStrings = append(report.MsgStrings, fmt.Sprintf("%s: duplicate at %s", w, fR)) 67 } 68 } 69 prev = fR 70 } 71 return nil 72 }