github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/manifest/manifest_save.go (about) 1 package manifest 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "sort" 8 9 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 12 ) 13 14 // SaveManifest writes the manifest to a file in JSON format. It first removes any 15 // duplicate chunks and sorts them. It then marshals the manifest into JSON and 16 // writes it to the file. The function takes the chain name and file name as arguments. 17 func (m *Manifest) SaveManifest(chain, fileName string) error { 18 m.Config = config.GetScrape(chain) 19 m.Config.ChannelCount = 0 // Exclude ChannelCount from the JSON 20 21 w, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) 22 if err != nil { 23 return fmt.Errorf("creating file: %s", err) 24 } 25 defer func() { 26 w.Close() 27 config.SetExpectedVersion(m.Version) 28 }() 29 30 err = file.Lock(w) 31 if err != nil { 32 return fmt.Errorf("locking file: %s", err) 33 } 34 defer func() { 35 _ = file.Unlock(w) 36 }() 37 38 m.removeDuplicatesAndSort() 39 40 outputBytes, err := json.MarshalIndent(m, "", " ") 41 if err != nil { 42 return err 43 } 44 45 _, err = w.Write(outputBytes) 46 return err 47 } 48 49 // removeDuplicatesAndSort is a helper function that removes duplicate chunks from the manifest 50 // and sorts the remaining chunks by their range. It uses a map to track seen ranges and a slice 51 // to store unique chunks. It then sorts the slice and updates the manifest's chunks. 52 func (m *Manifest) removeDuplicatesAndSort() { 53 seen := make(map[string]bool) 54 chunks := make([]types.ChunkRecord, 0, len(m.Chunks)) 55 56 for i := len(m.Chunks) - 1; i >= 0; i-- { 57 if !seen[m.Chunks[i].Range] { 58 seen[m.Chunks[i].Range] = true 59 chunks = append(chunks, m.Chunks[i]) 60 } 61 } 62 63 sort.Slice(chunks, func(i, j int) bool { 64 return chunks[i].Range < chunks[j].Range 65 }) 66 67 m.Chunks = chunks 68 }