package build import ( "sync" "git.novox.be/novox/mesh-sdk/go/delivery" ) // LanguageOf is the language each build module's toolchains state holds (the indexer's ToolchainModules, reversed). var LanguageOf = map[string]string{GoBuildModule: "go", NodeBuildModule: "typescript"} // ToolchainSet holds what the build modules' toolchains buckets hold: each node's entry of a language, as the watches // put them in. Safe for use from the watches and from a build at once. type ToolchainSet struct { mu sync.Mutex by map[string]map[string]delivery.Toolchain // language -> node -> entry } // Put takes a change of a build module's toolchains bucket in: a put of a node's entry (key .) or its // delete. It answers whether the language's entries changed (a node's version or recipe, or a node appearing or going). // A key or a value that is not an entry of the module's language is left out. func (s *ToolchainSet) Put(module, key string, value []byte, deleted bool) bool { language, ok := LanguageOf[module] if !ok { return false } node, keyLanguage, err := delivery.ParseToolchainKey(key) if err != nil || keyLanguage != language { return false } s.mu.Lock() defer s.mu.Unlock() if deleted { if _, had := s.by[language][node]; !had { return false } delete(s.by[language], node) return true } tc, err := delivery.DecodeToolchain(value) if err != nil || tc.Language != language { return false } if s.by == nil { s.by = map[string]map[string]delivery.Toolchain{} } if s.by[language] == nil { s.by[language] = map[string]delivery.Toolchain{} } cur, had := s.by[language][node] s.by[language][node] = tc return !had || cur.Version != tc.Version || cur.Recipe != tc.Recipe } // Entries are the nodes' entries of a language, in no particular order. func (s *ToolchainSet) Entries(language string) []delivery.NodeToolchain { s.mu.Lock() defer s.mu.Unlock() var out []delivery.NodeToolchain for node, tc := range s.by[language] { out = append(out, delivery.NodeToolchain{Node: node, Toolchain: tc}) } return out }