Skip to content

Commit

Permalink
Merge pull request #2519 from cockroachdb/bram/sim2
Browse files Browse the repository at this point in the history
Sim: Add range splitting
  • Loading branch information
BramGruneir committed Sep 16, 2015
2 parents fd8159e + 7ee59f1 commit 9910822
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
23 changes: 23 additions & 0 deletions storage/simulation/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package main

import (
"bytes"
"math/rand"
"sort"

"github.com/cockroachdb/cockroach/base"
Expand All @@ -28,6 +29,7 @@ import (
"github.com/cockroachdb/cockroach/storage"
"github.com/cockroachdb/cockroach/testutils/gossiputil"
"github.com/cockroachdb/cockroach/util/hlc"
"github.com/cockroachdb/cockroach/util/randutil"
"github.com/cockroachdb/cockroach/util/stop"
)

Expand All @@ -44,11 +46,14 @@ type Cluster struct {
nodes map[proto.NodeID]*Node
stores map[proto.StoreID]*Store
ranges map[proto.RangeID]*Range
rand *rand.Rand
seed int64
}

// createCluster generates a new cluster using the provided stopper and the
// number of nodes supplied. Each node will have one store to start.
func createCluster(stopper *stop.Stopper, nodeCount int) *Cluster {
rand, seed := randutil.NewPseudoRand()
clock := hlc.NewClock(hlc.UnixNano)
rpcContext := rpc.NewContext(&base.Context{}, clock, stopper)
g := gossip.New(rpcContext, gossip.TestInterval, gossip.TestBootstrap)
Expand All @@ -64,6 +69,8 @@ func createCluster(stopper *stop.Stopper, nodeCount int) *Cluster {
nodes: make(map[proto.NodeID]*Node),
stores: make(map[proto.StoreID]*Store),
ranges: make(map[proto.RangeID]*Range),
rand: rand,
seed: seed,
}

// Add the nodes.
Expand Down Expand Up @@ -102,6 +109,22 @@ func (c *Cluster) addRange() *Range {
return newRng
}

func (c *Cluster) splitRangeRandom() {
rangeID := proto.RangeID(c.rand.Int63n(int64(len(c.ranges))))
c.splitRange(rangeID)
}

func (c *Cluster) splitRangeLast() {
rangeID := proto.RangeID(len(c.ranges) - 1)
c.splitRange(rangeID)
}

func (c *Cluster) splitRange(rangeID proto.RangeID) {
newRange := c.addRange()
originalRange := c.ranges[rangeID]
newRange.splitRange(originalRange)
}

// String prints out the current status of the cluster.
func (c *Cluster) String() string {
storesRangeCounts := make(map[proto.StoreID]int)
Expand Down
7 changes: 7 additions & 0 deletions storage/simulation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ func main() {

fmt.Printf("A simulation of the cluster's rebalancing.\n\n")
fmt.Printf("Cluster Info:\n%s\n", c)

// Split a random range 100 times.
for i := 0; i < 100; i++ {
c.splitRangeRandom()
}

fmt.Printf("Cluster Info:\n%s\n", c)
}
23 changes: 23 additions & 0 deletions storage/simulation/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ func (r *Range) getStoreIDs() []proto.StoreID {
return storeIDs
}

// getStores returns a shallow copy of the internal stores map.
func (r *Range) getStores() map[proto.StoreID]*Store {
r.RLock()
defer r.RUnlock()
stores := make(map[proto.StoreID]*Store)
for storeID, store := range r.stores {
stores[storeID] = store
}
return stores
}

// split range adds a replica to all the stores from the passed in range. This
// function should only be called on new ranges as it will overwrite all of the
// replicas in the range.
func (r *Range) splitRange(originalRange *Range) {
desc := originalRange.getDesc()
stores := originalRange.getStores()
r.Lock()
defer r.Unlock()
r.desc.Replicas = desc.Replicas
r.stores = stores
}

// String returns a human readable string with details about the range.
func (r *Range) String() string {
r.RLock()
Expand Down

0 comments on commit 9910822

Please sign in to comment.