Example #1
0
// CreateRange allocates a new range ID and stores range metadata.
// On success, returns the new range.
func (s *Store) CreateRange(startKey, endKey engine.Key, replicas []proto.Replica) (*Range, error) {
	rangeID, err := engine.Increment(s.engine, engine.KeyLocalRangeIDGenerator, 1)
	if err != nil {
		return nil, err
	}
	if ok, _ := engine.GetProto(s.engine, makeRangeKey(rangeID), nil); ok {
		return nil, util.Error("newly allocated range ID already in use")
	}
	// RangeMetadata is stored local to this store only. It is neither
	// replicated via raft nor available via the global kv store.
	meta := &proto.RangeMetadata{
		ClusterID: s.Ident.ClusterID,
		RangeID:   rangeID,
		RangeDescriptor: proto.RangeDescriptor{
			StartKey: startKey,
			EndKey:   endKey,
			Replicas: replicas,
		},
	}
	err = engine.PutProto(s.engine, makeRangeKey(rangeID), meta)
	if err != nil {
		return nil, err
	}
	rng := NewRange(meta, s.clock, s.engine, s.allocator, s.gossip, s)
	rng.Start()
	s.mu.Lock()
	defer s.mu.Unlock()
	s.ranges[rangeID] = rng
	return rng, nil
}
Example #2
0
// InternalSnapshotCopy scans the key range specified by start key through
// end key up to some maximum number of results from the given snapshot_id.
// It will create a snapshot if snapshot_id is empty.
func (r *Range) InternalSnapshotCopy(args *proto.InternalSnapshotCopyRequest, reply *proto.InternalSnapshotCopyResponse) {
	if len(args.SnapshotId) == 0 {
		candidateID, err := engine.Increment(r.engine, engine.KeyLocalSnapshotIDGenerator, 1)
		if err != nil {
			reply.SetGoError(err)
			return
		}
		snapshotID := strconv.FormatInt(candidateID, 10)
		err = r.engine.CreateSnapshot(snapshotID)
		if err != nil {
			reply.SetGoError(err)
			return
		}
		args.SnapshotId = snapshotID
	}

	kvs, err := r.engine.ScanSnapshot(args.Key, args.EndKey, args.MaxResults, args.SnapshotId)
	if err != nil {
		reply.SetGoError(err)
		return
	}
	if len(kvs) == 0 {
		err = r.engine.ReleaseSnapshot(args.SnapshotId)
	}

	reply.Rows = kvs
	reply.SnapshotId = args.SnapshotId
	reply.SetGoError(err)
}
Example #3
0
// createSnapshot creates a new snapshot, named using an internal counter.
func (r *Range) createSnapshot() (string, error) {
	candidateID, err := engine.Increment(r.engine, engine.KeyLocalSnapshotIDGenerator, 1)
	if err != nil {
		return "", err
	}
	snapshotID := strconv.FormatInt(candidateID, 10)
	err = r.engine.CreateSnapshot(snapshotID)
	return snapshotID, err
}
Example #4
0
// TestIDAllocatorNegativeValue creates an ID allocator against an
// increment key which is preset to a negative value. We verify that
// the id allocator makes a double-alloc to make up the difference
// and push the id allocation into positive integers.
func TestIDAllocatorNegativeValue(t *testing.T) {
	store, _ := createTestStore(false, t)
	// Increment our key to a negative value.
	newValue, err := engine.Increment(store.engine, engine.KeyRaftIDGenerator, -1024)
	if err != nil {
		t.Fatal(err)
	}
	if newValue != -1024 {
		t.Errorf("expected new value to be -1024; got %d", newValue)
	}
	idAlloc := NewIDAllocator(engine.KeyRaftIDGenerator, store.db, 2, 10)
	value := idAlloc.Allocate()
	if value != 2 {
		t.Errorf("expected id allocation to have value 2; got %d", value)
	}
}
Example #5
0
// Increment increments the value (interpreted as varint64 encoded) and
// returns the newly incremented value (encoded as varint64). If no value
// exists for the key, zero is incremented.
func (r *Range) Increment(args *proto.IncrementRequest, reply *proto.IncrementResponse) {
	value, err := engine.Increment(r.engine, args.Key, args.Increment)
	reply.NewValue = value
	reply.SetGoError(err)
}
Example #6
0
// Increment increments the value (interpreted as varint64 encoded) and
// returns the newly incremented value (encoded as varint64). If no value
// exists for the key, zero is incremented.
func (r *Range) Increment(args *IncrementRequest, reply *IncrementResponse) {
	reply.NewValue, reply.Error = engine.Increment(r.engine, args.Key, args.Increment)
}