// Load the next ids to be used for RepoID, VersionID, and InstanceID. func (m *repoManager) loadNewIDs() error { var ctx storage.MetadataContext value, err := m.store.Get(ctx, storage.NewTKey(newIDsKey, nil)) if err != nil { return err } if len(value) != dvid.RepoIDSize+dvid.VersionIDSize+dvid.InstanceIDSize { return fmt.Errorf("Bad value returned for new ids. Length %d bytes!", len(value)) } pos := 0 m.repoID = dvid.RepoIDFromBytes(value[pos : pos+dvid.RepoIDSize]) pos += dvid.RepoIDSize m.versionID = dvid.VersionIDFromBytes(value[pos : pos+dvid.VersionIDSize]) pos += dvid.VersionIDSize m.instanceID = dvid.InstanceIDFromBytes(value[pos : pos+dvid.InstanceIDSize]) return nil }
func (m *repoManager) loadVersion0() error { // Load the maps if _, err := m.loadData(repoToUUIDKey, &(m.repoToUUID)); err != nil { return fmt.Errorf("Error loading repo to UUID map: %s", err) } if _, err := m.loadData(versionToUUIDKey, &(m.versionToUUID)); err != nil { return fmt.Errorf("Error loading version to UUID map: %s", err) } if err := m.loadNewIDs(); err != nil { return fmt.Errorf("Error loading new local ids: %s", err) } // Generate the inverse UUID to VersionID mapping. for v, uuid := range m.versionToUUID { m.uuidToVersion[uuid] = v } // Load all the repo data var ctx storage.MetadataContext minRepo := dvid.RepoID(0) maxRepo := dvid.RepoID(dvid.MaxRepoID) minTKey := storage.NewTKey(repoKey, minRepo.Bytes()) maxTKey := storage.NewTKey(repoKey, maxRepo.Bytes()) kvList, err := m.store.GetRange(ctx, minTKey, maxTKey) if err != nil { return err } var saveCache bool for _, kv := range kvList { var saveRepo bool ibytes, err := kv.K.ClassBytes(repoKey) if err != nil { return err } repoID := dvid.RepoIDFromBytes(ibytes) // Load each repo _, found := m.repoToUUID[repoID] if !found { return fmt.Errorf("Retrieved repo with id %d that is not in map. Corrupt DB?", repoID) } r := &repoT{ log: []string{}, properties: make(map[string]interface{}), data: make(map[dvid.InstanceName]DataService), } if err = dvid.Deserialize(kv.V, r); err != nil { return fmt.Errorf("Error gob decoding repo %d: %v", repoID, err) } // Cache all UUID from nodes into our high-level cache for v, node := range r.dag.nodes { uuid, found := m.versionToUUID[v] if !found { dvid.Errorf("Version id %d found in repo %s (id %d) not in cache map. Adding it...", v, r.uuid, r.id) m.versionToUUID[v] = node.uuid m.uuidToVersion[node.uuid] = v uuid = node.uuid saveCache = true } m.repos[uuid] = r } // Populate the instance id -> dataservice map. for _, dataservice := range r.data { m.iids[dataservice.InstanceID()] = dataservice } // Update the sync graph with all syncable data instances in this repo for _, dataservice := range r.data { syncedData, syncable := dataservice.(Syncer) if syncable { for _, name := range syncedData.SyncedNames() { r.addSyncGraph(syncedData.InitSync(name)) } } } // Load any mutable properties for the data instances. for _, dataservice := range r.data { mutator, mutable := dataservice.(InstanceMutator) if mutable { saveRepo, err = mutator.LoadMutable(r.version, m.formatVersion, RepoFormatVersion) if err != nil { return err } } } // If updates had to be made, save the migrated repo metadata. if saveRepo { dvid.Infof("Re-saved repo with root %s due to migrations.\n", r.uuid) if err := r.save(); err != nil { return err } } } if err := m.verifyCompiledTypes(); err != nil { return err } // If we noticed missing cache entries, save current metadata. if saveCache { if err := m.putCaches(); err != nil { return err } } if m.formatVersion != RepoFormatVersion { dvid.Infof("Updated metadata from version %d to version %d\n", m.formatVersion, RepoFormatVersion) m.formatVersion = RepoFormatVersion if err := m.putData(formatKey, &(m.formatVersion)); err != nil { return err } } dvid.Infof("Loaded %d repositories from metadata store.", len(m.repos)) return nil }