// AutoEdges produces an object which generates a minimal pkg file optimization // sequence of edges. func (obj *PkgRes) AutoEdges() AutoEdge { // in contrast with the FileRes AutoEdges() function which contains // more of the mechanics, most of the AutoEdge mechanics for the PkgRes // is contained in the Test() method! This design is completely okay! // add matches for any svc resources found in pkg definition! var svcUIDs []ResUID for _, x := range ReturnSvcInFileList(obj.fileList) { var reversed = false svcUIDs = append(svcUIDs, &SvcUID{ BaseUID: BaseUID{ name: obj.GetName(), kind: obj.Kind(), reversed: &reversed, }, name: x, // the svc name itself in the SvcUID object! }) // build list } return &PkgResAutoEdges{ fileList: util.RemoveCommonFilePrefixes(obj.fileList), // clean start! svcUIDs: svcUIDs, testIsNext: false, // start with Next() call name: obj.GetName(), // save data for PkgResAutoEdges obj kind: obj.Kind(), } }
// Test gets results of the earlier Next() call, & returns if we should continue! func (obj *PkgResAutoEdges) Test(input []bool) bool { if !obj.testIsNext { log.Fatal("Expecting a call to Next()") } // ack the svcUID's... if x := obj.svcUIDs; len(x) > 0 { if y := len(x); y != len(input) { log.Fatalf("Expecting %d value(s)!", y) } obj.svcUIDs = []ResUID{} // empty obj.testIsNext = false return true } count := len(obj.fileList) if count != len(input) { log.Fatalf("Expecting %d value(s)!", count) } obj.testIsNext = false // set after all the errors paths are past // while i do believe this algorithm generates the *correct* result, i // don't know if it does so in the optimal way. improvements welcome! // the basic logic is: // 0) Next() returns whatever is in fileList // 1) Test() computes the dirname of each file, and removes duplicates // and dirname's that have been in the path of an ack from input results // 2) It then simplifies the list by removing the common path prefixes // 3) Lastly, the remaining set of files (dirs) is used as new fileList // 4) We then iterate in (0) until the fileList is empty! var dirs = make([]string, count) done := []string{} for i := 0; i < count; i++ { dir := util.Dirname(obj.fileList[i]) // dirname of /foo/ should be / dirs[i] = dir if input[i] { done = append(done, dir) } } nodupes := util.StrRemoveDuplicatesInList(dirs) // remove duplicates nodones := util.StrFilterElementsInList(done, nodupes) // filter out done noempty := util.StrFilterElementsInList([]string{""}, nodones) // remove the "" from / obj.fileList = util.RemoveCommonFilePrefixes(noempty) // magic if len(obj.fileList) == 0 { // nothing more, don't continue return false } return true // continue, there are more files! }