//NodesForGet returns nodes which has datfile cache , and that extends nodes to #searchDepth .
func NodesForGet(datfile string, searchDepth int) node.Slice {
	var ns, ns2 node.Slice
	ns = ns.Extend(Get(datfile, nil))
	ns = ns.Extend(Get(list, nil))
	ns = ns.Extend(Random(ns, 0))

	for _, n := range ns {
		if !n.Equals(node.Me(true)) && n.IsAllowed() {
			ns2 = append(ns2, n)
		}
	}
	if ns2.Len() > searchDepth {
		ns2 = ns2[:searchDepth]
	}
	return ns2
}
//TellUpdate makes mynode info from node or dnsname or ip addr,
//and broadcast the updates of record id=id in cache c.datfile with stamp.
func TellUpdate(datfile string, stamp int64, id string, n *node.Node) {
	const updateNodes = 10

	tellstr := node.Me(true).Toxstring()
	if n != nil {
		tellstr = n.Toxstring()
	}
	msg := strings.Join([]string{"/update", datfile, strconv.FormatInt(stamp, 10), id, tellstr}, "/")

	ns := Get(datfile, nil)
	ns = ns.Extend(Get(list, nil))
	ns = ns.Extend(Random(ns, updateNodes))
	log.Println("telling #", len(ns))
	for _, n := range ns {
		_, err := n.Talk(msg, nil)
		if err != nil {
			log.Println(err)
		}
	}
}
//Join tells n to join and adds n to nodelist if welcomed.
//if n returns another nodes, repeats it and return true..
//removes fron nodelist if not welcomed and return false.
func Join(n *node.Node) bool {
	const retryJoin = 2 // Times; Join network
	if n == nil {
		return false
	}
	if hasNodeInTable(list, n) || node.Me(false).Nodestr == n.Nodestr {
		return false
	}
	flag := false
	for count := 0; count < retryJoin && ListLen() < defaultNodes; count++ {
		extnode, err := n.Join()
		if err != nil {
			RemoveFromTable(list, n)
			return false
		}
		AppendToList(n)
		flag = true
		if extnode == nil {
			return true
		}
		n = extnode
	}
	return flag
}