コード例 #1
0
ファイル: graph.go プロジェクト: AaronO/lightwave
func (self *permaNode) applyMutation(newnode *mutationNode, transformer Transformer) (err os.Error) {
	if transformer == nil {
		return
	}
	// 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())
	prune := map[string]bool{}
	rollback := int64(0)
	// 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
			}
			rollback++
			if h.Test() {
				break
			}
		}
	}

	concurrent := []string{}
	for c, _ := range prune {
		concurrent = append(concurrent, c)
	}
	ch, err := self.grapher.getMutationsAscending(self.blobref, newnode.EntityBlobRef(), newnode.Field(), self.SequenceNumber()-rollback, self.SequenceNumber())
	if err != nil {
		return err
	}
	err = transformer.TransformMutation(newnode, ch, concurrent)
	if err != nil {
		return err
	}
	return
}
コード例 #2
0
ファイル: grapher.go プロジェクト: AaronO/lightwave
func (self *Grapher) handleKeep(perma *permaNode, keep *keepNode) bool {
	var perm *permissionNode
	// The signer of the keep is not the signer of the permanode?
	// In this case he must present a valid invitation
	if keep.Signer() != perma.Signer() {
		var err os.Error
		perm, err = self.permission(perma.BlobRef(), keep.permissionBlobRef)
		if err != nil || perm == nil { // Problem already catched at checkKeep
			panic("Keep references a permision that is something else or malformed")
		}
	}

	// This keep is new. The permaNode has a new user.
	perma.addKeep(keep.Signer())
	log.Printf("Processing keep of %v\n", keep.Signer())
	// Signal the keep to the application
	if self.api != nil {
		if perm != nil {
			self.api.Blob_Keep(perma, perm, keep)
		} else {
			self.api.Blob_Keep(perma, nil, keep)
		}
	}

	// This implies that the local user is accepting an invitation?
	if perm != nil && perm.User == self.userID {
		// Send the keep (which accepts the invitation) to the signer of the invitation
		if self.fed != nil && keep.Signer() != self.userID {
			self.fed.Forward(keep.BlobRef(), []string{keep.Signer()})
		}
		//    self.openInvitations[perma.BlobRef()] = "", false
		log.Printf("The local user accepted the invitation\nREF=%v\n", keep.BlobRef())
	} else if perm != nil {
		// Some other user is accepting his invitation?
		log.Printf("The user %v accepted the invitation\n", keep.Signer())
		// Send this user all blobs of the local user that are not in the other user's frontier yet.
		if self.fed != nil {
			h := ot.NewHistoryGraph(perma.frontier, keep.Dependencies())
			h.SubstituteBlob(keep.BlobRef(), keep.Dependencies())
			forwards := []string{}
			if !h.Test() {
				ch, _ := self.getOTNodesDescending(perma.BlobRef())
				for history_node := range ch {
					if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) {
						// Send nodes created by the local user
						if history_node.Signer() == self.userID {
							forwards = append(forwards, history_node.BlobRef())
							// Send keeps that rely on a permission given by the local user
						} else if k, ok := history_node.(*keepNode); ok && k.permissionBlobRef != "" {
							if p, e := self.permission(perma.BlobRef(), k.permissionBlobRef); e == nil && p != nil && p.Signer() == self.userID {
								forwards = append(forwards, history_node.BlobRef())
							}
						}
					}
					if h.Test() {
						break
					}
				}
			}
			for _, f := range forwards {
				self.fed.Forward(f, []string{keep.Signer()})
			}
		}
	}
	return true
}
コード例 #3
0
ファイル: indexer.go プロジェクト: AaronO/lightwave
func (self *Indexer) handleKeep(perma *PermaNode, keep *keepNode) bool {
	log.Printf("Handling Keep from %v at %v\n", keep.Signer(), self.userID)
	var perm *permissionNode
	// The signer of the keep is not the signer of the permanode?
	// In this case he must present a valid invitation
	if keep.Signer() != perma.Signer() {
		var err os.Error
		perm, err = self.Permission(keep.permission)
		if err != nil || perm == nil { // Problem already catched at checkKeep
			panic("Keep references a permision that is something else or malformed")
		}
	}

	// Does this implicitly accept a pending invitation? Clean it up.
	if _, ok := perma.pendingInvitations[keep.Signer()]; ok {
		perma.pendingInvitations[keep.Signer()] = "", false
	}
	// This keep is new. The permaNode has a new user.
	perma.keeps[keep.Signer()] = keep.BlobRef()

	// This implies accepting an invitation?
	if perm != nil && perm.permission.User == self.userID {
		// Send the keep (which accepts the invitation) to the signer of the invitation
		if self.fed != nil && keep.Signer() != self.userID {
			self.fed.Forward(keep.BlobRef(), []string{keep.Signer()})
		}
		self.openInvitations[perma.BlobRef()] = "", false
		log.Printf("The local user accepted the invitation\n")
		// Signal this to the application
		for _, app := range self.appIndexers {
			app.PermaNode(perma.BlobRef(), perm.BlobRef(), keep.BlobRef())
		}
	} else {
		if perm != nil {
			log.Printf("The user %v accepted the invitation\n", keep.Signer())
			// Signal this to the application
			for _, app := range self.appIndexers {
				app.NewFollower(perma.BlobRef(), perm.BlobRef(), keep.BlobRef(), perm.permission.User)
			}
			// Send this user all blobs of the local user that are not in the other user's frontier yet.
			if perma.ot != nil && self.fed != nil {
				frontier := perma.ot.Frontier()
				h := ot.NewHistoryGraph(frontier, keep.Dependencies())
				forwards := []string{}
				if !h.Test() {
					for x := range perma.ot.History(true) {
						history_node := x.(otNode)
						if !h.SubstituteBlob(history_node.BlobRef(), history_node.Dependencies()) {
							// Send nodes created by the local user
							if history_node.Signer() == self.userID {
								forwards = append(forwards, history_node.BlobRef())
								// Send keeps that rely on a permission given by the local user
							} else if k, ok := x.(*keepNode); ok && k.permission != "" {
								if p, e := self.Permission(k.permission); e == nil && p != nil && p.Signer() == self.userID {
									forwards = append(forwards, history_node.BlobRef())
								}
							}
						}
						if h.Test() {
							break
						}
					}
				}
				for _, f := range forwards {
					self.fed.Forward(f, []string{keep.Signer()})
				}
			}
		} else {
			log.Printf("The user %v keeps his own perma node\n", keep.Signer())
			// Signal this to the application
			for _, app := range self.appIndexers {
				app.PermaNode(perma.BlobRef(), "", keep.BlobRef())
			}
		}
	}
	return true
}
コード例 #4
0
ファイル: graph.go プロジェクト: AaronO/lightwave
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
}
コード例 #5
0
ファイル: history.go プロジェクト: AaronO/lightwave
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
}