// intersect returns true if the provided shard intersect with any shard // in the destination array func intersect(si *topo.ShardInfo, allShards []*topo.ShardInfo) bool { for _, shard := range allShards { if key.KeyRangesIntersect3(si.KeyRange, shard.KeyRange) { return true } } return false }
// findIntersectingShard will go through the map and take the first // entry in there that intersect with the source array, remove it from // the map, and return it func findIntersectingShard(shardMap map[string]*topo.ShardInfo, sourceArray []*topo.ShardInfo) *topo.ShardInfo { for name, si := range shardMap { for _, sourceShardInfo := range sourceArray { if si.KeyRange == nil || sourceShardInfo.KeyRange == nil || key.KeyRangesIntersect3(si.KeyRange, sourceShardInfo.KeyRange) { delete(shardMap, name) return si } } } return nil }
// CreateShard creates a new shard and tries to fill in the right information. // This should be called while holding the keyspace lock for the shard. // (call topotools.CreateShard to do that for you). // In unit tests (that are not parallel), this function can be called directly. func (ts Server) CreateShard(ctx context.Context, keyspace, shard string) error { name, keyRange, err := ValidateShardName(shard) if err != nil { return err } // start the shard with all serving types. If it overlaps with // other shards for some serving types, remove them. servedTypes := map[pb.TabletType]bool{ pb.TabletType_MASTER: true, pb.TabletType_REPLICA: true, pb.TabletType_RDONLY: true, } value := &pb.Shard{ KeyRange: keyRange, } if IsShardUsingRangeBasedSharding(name) { // if we are using range-based sharding, we don't want // overlapping shards to all serve and confuse the clients. sis, err := ts.FindAllShardsInKeyspace(ctx, keyspace) if err != nil && err != ErrNoNode { return err } for _, si := range sis { if si.KeyRange == nil || key.KeyRangesIntersect3(si.KeyRange, keyRange) { for _, st := range si.ServedTypes { delete(servedTypes, st.TabletType) } } } } for st := range servedTypes { value.ServedTypes = append(value.ServedTypes, &pb.Shard_ServedType{ TabletType: st, }) } if err := ts.Impl.CreateShard(ctx, keyspace, name, value); err != nil { return err } event.Dispatch(&events.ShardChange{ KeyspaceName: keyspace, ShardName: shard, Shard: value, Status: "created", }) return nil }