Skip to content

Commit

Permalink
add rpc commands for make-master and hide-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
DocSavage committed May 14, 2021
1 parent cfa0db5 commit fe6b7f2
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
22 changes: 22 additions & 0 deletions datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,28 @@ func NewVersion(parent dvid.UUID, note string, branchname string, assign *dvid.U
return manager.newVersion(parent, note, branchname, assign)
}

// MakeMaster makes the branch at given UUID (that node and all its children)
// the new master branch and renames the old master branch to the given
// branch name. NOTE: This command will fail if the given UUID is not
// a node that is directly branched off master.
func MakeMaster(newMasterNode dvid.UUID, oldMasterBranchName string) error {
if manager == nil {
return ErrManagerNotInitialized
}
return manager.makeMaster(newMasterNode, oldMasterBranchName)
}

// HideBranch makes the branch at given UUID (that node and all its children)
// the new master branch and renames the old master branch to the given
// branch name. NOTE: This command will fail if the given UUID is not
// a node that is directly branched off master.
func HideBranch(uuid dvid.UUID, branchName string) error {
if manager == nil {
return ErrManagerNotInitialized
}
return manager.hideBranch(uuid, branchName)
}

// GetParents returns the parent nodes of the given version id.
func GetParentsByVersion(v dvid.VersionID) ([]dvid.VersionID, error) {
if manager == nil {
Expand Down
122 changes: 122 additions & 0 deletions datastore/repo_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,109 @@ func (m *repoManager) commit(uuid dvid.UUID, note string, log []string) error {
return r.save()
}

func (m *repoManager) hideBranch(uuid dvid.UUID, branch string) error {
if branch == "" {
return fmt.Errorf("cannot hide master branch")
}
r, err := m.repoFromUUID(uuid)
if err != nil {
return err
}
m.repoMutex.Lock()
r.Lock()
del_set := make(map[dvid.VersionID]struct{})
for v, node := range r.dag.nodes {
if node.branch == branch {
del_set[v] = struct{}{}
del_uuid := m.versionToUUID[v]
delete(m.versionToUUID, v)
delete(m.uuidToVersion, del_uuid)
delete(r.dag.nodes, v)
delete(m.repos, del_uuid)
}
}
for _, node := range r.dag.nodes {
var children []dvid.VersionID
for _, cv := range node.children {
if _, found := del_set[cv]; !found {
children = append(children, cv)
}
}
if len(children) < len(node.children) {
node.children = children
}
}
r.Unlock()
m.repoMutex.Unlock()
return r.save()
}

func (m *repoManager) makeMaster(newMasterUUID dvid.UUID, oldMasterBranchName string) error {
if oldMasterBranchName == "" {
return fmt.Errorf("renamed master branch cannot be empty string")
}
r, err := m.repoFromUUID(newMasterUUID)
if err != nil {
return err
}
newMasterV, err := m.versionFromUUID(newMasterUUID)
if err != nil {
return err
}

r.RLock()
defer r.RUnlock()
newMasterNode, found := r.dag.nodes[newMasterV]
if !found {
return fmt.Errorf("unable to find node with version %d, UUID %s", newMasterV, newMasterUUID)
}
if newMasterNode.branch == "" {
return fmt.Errorf("designated node is already on the master branch")
}

// Get master branch that must be sibling.
if len(newMasterNode.parents) == 0 {
return fmt.Errorf("given UUID must be the first node of the branch to make master")
}
parentV := newMasterNode.parents[0]
oldMasterNode, err := r.getChildBranchNode(parentV, "")
if err != nil {
return err
}
if oldMasterNode == nil {
return fmt.Errorf("no sibling master branch found for UUID %s", newMasterUUID)
}

// Change the master nodes to the appropriate rename
for {
oldMasterNode.branch = oldMasterBranchName
childNode, err := r.getChildBranchNode(oldMasterNode.version, "")
if err != nil {
return err
}
if childNode == nil {
break
}
oldMasterNode = childNode
}

// Change the new master nodes to the master branch.
oldBranchName := newMasterNode.branch
for {
newMasterNode.branch = ""
childNode, err := r.getChildBranchNode(newMasterNode.version, oldBranchName)
if err != nil {
return err
}
if childNode == nil {
break
}
newMasterNode = childNode
}

return r.save()
}

// newVersion creates a new version as a child of the given parent. If the
// assign parameter is not nil, the new node is given the UUID.
func (m *repoManager) newVersion(parent dvid.UUID, note string, branchname string, assign *dvid.UUID) (dvid.UUID, error) {
Expand Down Expand Up @@ -2735,6 +2838,25 @@ func (r *repoT) versionSet() map[dvid.VersionID]struct{} {
return vset
}

// get the given branch child from this node.
func (r *repoT) getChildBranchNode(parentV dvid.VersionID, branch string) (branchNode *nodeT, err error) {
parent, found := r.dag.nodes[parentV]
if !found {
return nil, ErrInvalidVersion
}
for _, v := range parent.children {
node, found := r.dag.nodes[v]
if !found {
continue
}
if node.branch == branch {
branchNode = node
break
}
}
return
}

// --------------------------------------

// DataAvail gives the availability of data within a node or whether parent nodes
Expand Down
30 changes: 30 additions & 0 deletions server/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ DANGEROUS COMMANDS (only available via command line)
Delete the given data instance.
repo <UUID> make-master <old-master-branch-name>
Makes the branch at given UUID (that node and all its children) the
new master branch and renames the old master branch to the given
branch name. NOTE: This command will fail if the given UUID is not
a node that is directly branched off master.
repo <UUID> hide-branch <branch-name>
Removes metadata for the given branch so that it is not visible.
This does not remove the key-value pairs associated wiith the given
nodes, since doing so would be very expensive. Instead, the old
key values aren't accessible.
EXPERIMENTAL COMMANDS
Expand Down Expand Up @@ -621,6 +635,22 @@ func handleCommand(cmd *datastore.Request) (reply *datastore.Response, err error
}
reply.Text = fmt.Sprintf("Limited metadata versions for repo %s\n", uuid)

case "make-master":
var newMasterBranchName string
cmd.CommandArgs(3, &newMasterBranchName)
if err = datastore.MakeMaster(uuid, newMasterBranchName); err != nil {
dvid.Errorf("make-master error: %v\n", err)
}
reply.Text = fmt.Sprintf("Made branch from %s the new master\n", uuid)

case "hide-branch":
var branchName string
cmd.CommandArgs(3, &branchName)
if err = datastore.HideBranch(uuid, branchName); err != nil {
dvid.Errorf("make-master error: %v\n", err)
}
reply.Text = fmt.Sprintf("Hid branch %s in repo with UUID %s\n", branchName, uuid)

case "push":
var target string
cmd.CommandArgs(3, &target)
Expand Down

0 comments on commit fe6b7f2

Please sign in to comment.