Example #1
0
func (self *permaNode) applyPermission(newnode *permissionNode) (err os.Error) {
	// Find out how far back we have to go in history to find a common anchor point for transformation
	h := ot.NewHistoryGraph(self.frontier, newnode.Dependencies())
	reverse_permissions := []*permissionNode{}
	prune := map[string]bool{}
	// Need to rollback?
	if !h.Test() {
		// Go back in history until our history is equal to (or earlier than) that of 'mut'.
		// On the way remember which mutations of our history do not belong to the
		// history of 'mut' because these must be pruned.
		ch, err := self.grapher.getOTNodesDescending(self.BlobRef())
		if err != nil {
			return err
		}
		for history_node := range ch {
			if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) {
				prune[history_node.BlobRef()] = true
			}
			if x, ok := history_node.(*permissionNode); ok {
				reverse_permissions = append(reverse_permissions, x)
			}
			if h.Test() {
				break
			}
		}
	}

	// Reverse the mutation history, such that oldest are first in the list.
	// This is ugly but prepending in the above loops is too slow.
	permissions := make([]*permissionNode, len(reverse_permissions))
	for i := 0; i < len(permissions); i++ {
		permissions[i] = reverse_permissions[len(reverse_permissions)-1-i]
	}

	// Prune all mutations that have been applied locally but do not belong to the history of the new mutation
	pnodes, e := prunePermissionSeq(permissions, prune)
	if e != nil {
		log.Printf("Prune Error: %v\n", e)
		err = e
		return
	}

	// Transform 'newnode' to apply it locally
	pnodes = append(pnodes, newnode)
	for _, n := range permissions {
		if n.BlobRef() != pnodes[0].BlobRef() {
			pnodes, _, err = transformPermissionSeq(pnodes, n)
			if err != nil {
				log.Printf("TRANSFORM ERR: %v", err)
				return
			}
		} else {
			pnodes = pnodes[1:]
		}
	}
	*newnode = *pnodes[0]

	bits, ok := self.permissions[newnode.User]
	if !ok {
		bits = 0
	}
	bits, err = ot.ExecutePermission(bits, newnode.Permission)
	if err == nil {
		self.permissions[newnode.User] = bits
	}
	return
}
Example #2
0
func (self *otHistory) Apply(newnode otNode) (deps []string, err os.Error) {
	// The mutation has already been applied?
	if self.HasApplied(newnode.BlobRef()) {
		return
	}
	// Are all dependencies satisfied, i.e. are all mutations
	// on which mut depends already processed by the builder?
	unsatisfied := false
	for _, dep := range newnode.Dependencies() {
		if !self.HasApplied(dep) {
			unsatisfied = true
			deps = append(deps, dep)
		}
	}
	if unsatisfied {
		return deps, nil
	}

	// Find out how far back we have to go in history to find a common anchor point for transformation
	frontier := self.Frontier()
	h := ot.NewHistoryGraph(frontier, newnode.Dependencies())
	reverse_nodes := []otNode{}
	prune := map[string]bool{}
	// Need to rollback?
	if !h.Test() {
		// Go back in history until our history is equal to (or earlier than) that of 'mut'.
		// On the way remember which mutations of our history do not belong to the
		// history of 'mut' because these must be pruned.
		for x := range self.History(true) {
			history_node := x.(otNode)
			if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) {
				prune[history_node.BlobRef()] = true
			}
			reverse_nodes = append(reverse_nodes, history_node)
			if h.Test() {
				break
			}
		}
	}

	// Reverse the mutation history, such that oldest are first in the list.
	// This is ugly but prepending in the above loops is too slow.
	nodes := make([]otNode, len(reverse_nodes))
	for i := 0; i < len(nodes); i++ {
		nodes[i] = reverse_nodes[len(reverse_nodes)-1-i]
	}

	// Prune all mutations that have been applied locally but do not belong to the history of the new mutation
	pnodes, e := pruneSeq(nodes, prune)
	if e != nil {
		log.Printf("Prune Error: %v\n", e)
		err = e
		return
	}

	// Transform 'mut' to apply it locally
	pnodes = append(pnodes, newnode)
	for _, n := range nodes {
		if n.BlobRef() != pnodes[0].BlobRef() {
			pnodes, _, err = transformSeq(pnodes, n)
			if err != nil {
				log.Printf("TRANSFORM ERR: %v", err)
				return
			}
		} else {
			pnodes = pnodes[1:]
		}
	}
	newnode = pnodes[0]

	// Apply the mutation
	if mut, ok := newnode.(*mutationNode); ok {
		mut.mutation.AppliedAt = len(self.appliedBlobs)
	}
	self.appliedBlobs = append(self.appliedBlobs, newnode.BlobRef())
	self.members[newnode.BlobRef()] = newnode
	self.frontier.AddBlob(newnode.BlobRef(), newnode.Dependencies())

	if mut, ok := newnode.(*mutationNode); ok {
		self.content, err = ot.Execute(self.content, mut.mutation)
	} else if perm, ok := newnode.(*permissionNode); ok {
		bits, ok := self.permissions[perm.permission.User]
		if !ok {
			bits = 0
		}
		bits, err = ot.ExecutePermission(bits, perm.permission)
		if err == nil {
			self.permissions[perm.permission.User] = bits
		}
	}
	return
}