func makeSomeUniqueKeys(N, K uint) (rawKeys [][]byte, bKeys []gh.BytesKey) {

	rng := xr.MakeSimpleRNG()
	rawKeys = make([][]byte, N)
	bKeys = make([]gh.BytesKey, N)
	keyMap := make(map[uint64]bool)

	for i := uint(0); i < N; i++ {
		var bKey gh.BytesKey
		key := make([]byte, K)
		for {
			rng.NextBytes(key)
			bKey, _ = gh.NewBytesKey(key)
			hc := bKey.Hashcode()
			_, ok := keyMap[hc]
			if !ok { // value is not in the map
				keyMap[hc] = true
				break
			}
		}
		rawKeys[i] = key
		bKeys[i] = bKey
	}
	return
}
Exemple #2
0
func (rc *RegCluster) AddMember(member *ClientInfo) (err error) {

	// verify no existing member has the same name
	name := member.GetName()

	rc.mu.RLock() // <------------------------------------
	_, ok := rc.MembersByName[name]
	rc.mu.RUnlock() // <------------------------------------

	if ok {
		// DEBUG
		fmt.Printf("AddMember: ATTEMPT TO ADD EXISTING MEMBER %s\n", name)
		// END
		err = ClusterMemberNameInUse
	}
	if err == nil {
		var (
			entry interface{}
			bKey  ha.BytesKey
		)
		// check for entry in HAMT
		rc.mu.RLock() // <---------------------------------
		bKey, err = ha.NewBytesKey(rc.ID)
		entry, err = rc.MembersByID.Find(bKey)
		rc.mu.RUnlock() // <-------------------------------
		if err == nil {
			if entry != nil {
				err = ClusterMemberIDInUse
			}
		}
		if err == nil {
			rc.mu.Lock()             // <------------------
			index := len(rc.Members) // DEBUG
			_ = index                // we might want to use this
			rc.Members = append(rc.Members, member)
			rc.MembersByName[name] = member
			bKey, err = ha.NewBytesKey(member.GetNodeID().Value())
			if err == nil {
				err = rc.MembersByID.Insert(bKey, member)
			}
			rc.mu.Unlock() // <----------------------------
		}
	}
	return
}
Exemple #3
0
// Add an item to the map.  This should be idempotent: adding a key
// that is already in the map should have no effect at all.
//
func (m *IDMapHAMT) Insert(key []byte, value interface{}) (err error) {
	bKey, err := gh.NewBytesKey(key)
	if err == nil {
		// XXX A very coarse lock
		m.mu.Lock()
		defer m.mu.Unlock()
		err = m.h.Insert(bKey, value)
	}
	return
}
Exemple #4
0
func (m *IDMapHAMT) Delete(key []byte) (err error) {

	bKey, err := gh.NewBytesKey(key)
	if err == nil {
		// XXX A very coarse lock
		m.mu.Lock()
		defer m.mu.Unlock()
		err = m.h.Delete(bKey)
	}
	return
}
Exemple #5
0
func (reg *Registry) AddCluster(cluster *RegCluster) (index int, err error) {

	var bKey, cKey ha.BytesKey
	if cluster == nil {
		err = NilCluster
	} else {
		name := cluster.Name
		id := cluster.ID // []byte

		// convert ID into a HAMT BytesKey
		bKey, err = ha.NewBytesKey(id)
		if err == nil {
			reg.mu.Lock()
			defer reg.mu.Unlock()

			if _, ok := reg.ClustersByName[name]; ok {
				err = NameAlreadyInUse
			} else {
				var whatever interface{}
				whatever, err = reg.ClustersByID.Find(bKey)
				if err == nil && whatever != nil {
					err = IDAlreadyInUse
				}
			}
			if err == nil {
				index = len(reg.Clusters)
				reg.Clusters = append(reg.Clusters, cluster)
				reg.ClustersByName[name] = cluster
				cKey, err = ha.NewBytesKey(cluster.GetNodeID().Value())
				if err == nil {
					err = reg.ClustersByID.Insert(cKey, cluster)
				}
			}
		}
	}
	if err != nil {
		index = -1
	}
	return
}
Exemple #6
0
// Return the value associated with the key or nil if there is no
// such value.
func (m *IDMapHAMT) Find(key []byte) (value interface{}, err error) {

	bKey, err := gh.NewBytesKey(key)
	if err == nil {
		// XXX A very coarse lock
		m.mu.RLock()
		defer m.mu.RUnlock()
		value, err = m.h.Find(bKey)
		if err == gh.NotFound {
			err = nil
			value = nil
		}
	}
	return
}
Exemple #7
0
func doGetMsg(h *InHandler) {
	var (
		cluster *RegCluster
		err     error
	)
	defer func() {
		h.errOut = err
	}()
	// Examine incoming message -------------------------------------
	getMsg := h.msgIn
	clusterID := getMsg.GetClusterID()
	whichRequested := xu.NewBitMap64(getMsg.GetWhich())

	// Take appropriate action --------------------------------------
	var tokens []*XLRegMsg_Token
	whichReturned := xu.NewBitMap64(0)

	// Put the type assertion within the critical section because on
	// 2013-12-04 I observed a panic with the error message saying
	// that the assertion failed because kluster was nil, which should
	// be impossible.

	// convert clusterID into a BytesKey
	bKey, err := ha.NewBytesKey(clusterID)
	if err == nil {
		var kluster interface{}
		h.reg.mu.RLock() // <-- LOCK --------------------------
		kluster, err = h.reg.ClustersByID.Find(bKey)
		if kluster == nil {
			msg := fmt.Sprintf("doGetMsg: can't find cluster with ID %s",
				hex.EncodeToString(clusterID))
			// DEBUG
			h.reg.Logger.Printf("%s\n", msg)
			// END
			err = e.New(msg)
		} else {
			cluster = kluster.(*RegCluster)
		}
		h.reg.mu.RUnlock() // <-- UNLOCK ----------------------
	}

	if err == nil {
		size := cluster.Size()       // actual size, not MaxSize
		if size > MAX_CLUSTER_SIZE { // yes, should be impossible
			size = MAX_CLUSTER_SIZE
		}
		// XXX UNDESIRABLE CAST
		weHave := xu.LowNMap(uint(size))
		whichToSend := whichRequested.Intersection(weHave)
		for i := uint32(0); i < size; i++ {
			// XXX UNDESIRABLE CAST
			if whichToSend.Test(uint(i)) { // they want this one
				member := cluster.Members[i]
				token, err := member.Token()
				if err == nil {
					tokens = append(tokens, token)
					// XXX UNDESIRABLE CAST
					whichReturned = whichReturned.Set(uint(i))
				} else {
					break
				}
			}
		}
	}
	if err == nil {
		// Prepare reply to client --------------------------------------
		op := XLRegMsg_ClusterMembers
		h.msgOut = &XLRegMsg{
			Op:        &op,
			ClusterID: clusterID,
			Which:     &whichReturned.Bits,
			Tokens:    tokens,
		}
		// Set exit state -----------------------------------------------
		h.exitState = JOIN_RCVD // the JOIN is intentional !
	}
}
Exemple #8
0
func doJoinMsg(h *InHandler) {

	var err error
	defer func() {
		h.errOut = err
	}()
	// Examine incoming message -------------------------------------
	var (
		cluster        *RegCluster
		clusterName    string
		clusterID      []byte
		clusterMaxSize uint32
		endPointCount  uint32
	)
	joinMsg := h.msgIn

	// Take appropriate action --------------------------------------

	// Accept either cluster name or id.  If it's just the name,
	// attempt to retrieve the ID; it's an error if it does not exist
	// in the registry.  . In either case use the ID to retrieve the size.

	clusterName = joinMsg.GetClusterName() // will be "" if absent
	clusterID = joinMsg.GetClusterID()     // will be nil if absent

	if clusterID != nil {
		h.reg.Logger.Printf("JOIN: cluster %x, new member %s\n",
			clusterID, h.thisClient.GetName())
	} else {
		h.reg.Logger.Printf("JOIN: cluster %s, new member %s\n",
			clusterName, h.thisClient.GetName())
	}

	if clusterID == nil && clusterName == "" {
		// if neither is present, we will use any cluster already
		// associated with this connection
		if h.cluster != nil {
			cluster = h.cluster
		} else {
			err = MissingClusterNameOrID
		}
	} else if clusterID != nil {
		var kluster interface{}

		// convert the clusterID into a HAMT BytesKey
		bKey, err := ha.NewBytesKey(clusterID)
		if err == nil {
			// if an ID has Leen defined, we will try to use that
			h.reg.mu.RLock()
			kluster, err = h.reg.ClustersByID.Find(bKey)
			h.reg.mu.RUnlock()
			if kluster == nil {
				msg := fmt.Sprintf("can't find cluster with ID %s",
					hex.EncodeToString(clusterID))
				// DEBUG
				h.reg.Logger.Printf("%s\n", msg)
				// END
				err = e.New(msg)
			} else {
				cluster = kluster.(*RegCluster)
			}
		}
	} else {
		// we have no ID and clusterName is not nil, so we will try to use that
		var ok bool
		h.reg.mu.RLock()
		if cluster, ok = h.reg.ClustersByName[clusterName]; !ok {
			err = CantFindClusterByName
		}
		h.reg.mu.RUnlock()
	}
	if err == nil {
		// if we get here, cluster is not nil
		err = cluster.AddMember(h.thisClient)
	}
	if err == nil {
		h.reg.Logger.Printf("cluster %x, new member %s\n",
			cluster.ID, h.thisClient.GetName())

		// Prepare reply to client ----------------------------------
		h.cluster = cluster
		clusterID = cluster.ID
		clusterAttrs := cluster.Attrs
		clusterMaxSize = h.cluster.maxSize
		endPointCount = h.cluster.epCount

		op := XLRegMsg_JoinReply
		h.msgOut = &XLRegMsg{
			Op:             &op,
			ClusterID:      clusterID,
			ClusterAttrs:   &clusterAttrs,
			ClusterMaxSize: &clusterMaxSize,
			EndPointCount:  &endPointCount,
		}
		// Set exit state -------------------------------------------
		h.exitState = JOIN_RCVD
	}
	if err != nil {
		h.reg.Logger.Printf("cluster %x, new member %s, ERROR %s\n",
			cluster.ID, h.thisClient.GetName(), err.Error())
	}
}
Exemple #9
0
func (s *XLSuite) TestRegClusterMaker(c *C) {
	if VERBOSITY > 0 {
		fmt.Println("\nTEST_REG_CLUSTER_MAKER")
	}
	var err error
	rng := xr.MakeSimpleRNG()

	// Generate a random cluster
	epCount := uint32(1 + rng.Intn(3)) // so from 1 to 3
	maxSize := uint32(2 + rng.Intn(6)) // so from 2 to 7
	cl := s.makeARegCluster(c, rng, epCount, maxSize)

	c.Assert(cl.MaxSize(), Equals, maxSize)
	c.Assert(cl.Size(), Equals, maxSize) //

	// Verify that member names are unique within the cluster
	ids := make([][]byte, maxSize)
	names := make([]string, maxSize)
	nameMap := make(map[string]uint32)
	for i := uint32(0); i < maxSize; i++ {
		member := cl.Members[i]
		names[i] = member.GetName()
		// fmt.Printf("member[%d]: %s\n", i, names[i])		// DEBUG
		nameMap[names[i]] = i

		// collect IDs while we are at it
		id := member.GetNodeID().Value() // returns a clone of the nodeID
		ids[i] = id
	}
	// if the names are not unique, map will be smaller
	c.Assert(maxSize, Equals, uint32(len(nameMap)))

	// verify that the RegCluster.MembersByName index is correct
	for i := uint32(0); i < maxSize; i++ {
		name := names[i]
		member := cl.MembersByName[name]
		c.Assert(name, Equals, member.GetName())
	}

	// verify that the RegCluster.MembersByID index is correct
	count := uint32(0) // number of successful type assertions
	for i := uint32(0); i < maxSize; i++ {
		id := ids[i]
		var bKey ha.BytesKey
		bKey, err = ha.NewBytesKey(id)
		c.Assert(err, IsNil)
		mbr, err := cl.MembersByID.Find(bKey)
		c.Assert(err, IsNil)
		var member *ClientInfo
		// verify that the type assertion succeeds
		if m, ok := mbr.(*ClientInfo); ok {
			member = m
			mID := member.GetNodeID().Value()
			c.Assert(len(id), Equals, len(mID))
			for j := uint(0); j < uint(len(id)); j++ {
				c.Assert(id[j], Equals, mID[j])
			}
			count++
		}
	}
	c.Assert(maxSize, Equals, count)
}