Skip to content

Commit

Permalink
Implement Transactions: Part 2
Browse files Browse the repository at this point in the history
- Move all errors into a new file: errors.go.
- Remove all public APIs from kv.go. All the public APIs now flow through transactions.
- Remove SetIfAbsent, CompareAndSet, etc. They should all be done via transactions now.
- Remove CAS counter from everywhere.
- Simplify serialization/deserialization of various structs.
- Move them into new structs.go file (currently only contains value.go structs).
- Logic to handle transaction boundaries when replaying value log.
  • Loading branch information
manishrjain committed Sep 28, 2017
1 parent 816af49 commit ffd14f0
Show file tree
Hide file tree
Showing 15 changed files with 505 additions and 737 deletions.
82 changes: 82 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2017 Dgraph Labs, Inc. and Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package badger

import (
"encoding/hex"

"github.com/pkg/errors"
)

// ErrInvalidDir is returned when Badger cannot find the directory
// from where it is supposed to load the key-value store.
var ErrInvalidDir = errors.New("Invalid Dir, directory does not exist")

// ErrValueLogSize is returned when opt.ValueLogFileSize option is not within the valid
// range.
var ErrValueLogSize = errors.New("Invalid ValueLogFileSize, must be between 1MB and 2GB")

// ErrKeyNotFound is returned when key isn't found on a txn.Get.
var ErrKeyNotFound = errors.New("Key not found")

// ErrTxnTooBig is returned if too many writes are fit into a single transaction.
var ErrTxnTooBig = errors.New("Txn is too big to fit into one request.")

// ErrConflict is returned when a transaction conflicts with another transaction. This can happen if
// the read rows had been updated concurrently by another transaction.
var ErrConflict = errors.New("Transaction Conflict. Please retry.")

// ErrReadOnlyTxn is returned if an update function is called on a read-only transaction.
var ErrReadOnlyTxn = errors.New("No sets or deletes are allowed in a read-only transaction.")

// ErrEmptyKey is returned if an empty key is passed on an update function.
var ErrEmptyKey = errors.New("Key cannot be empty.")

const maxKeySize = 1 << 20

func exceedsMaxKeySizeError(key []byte) error {
return errors.Errorf("Key with size %d exceeded %dMB limit. Key:\n%s",
len(key), maxKeySize<<20, hex.Dump(key[:1<<10]))
}

func exceedsMaxValueSizeError(value []byte, maxValueSize int64) error {
return errors.Errorf("Value with size %d exceeded ValueLogFileSize (%dMB). Key:\n%s",
len(value), maxValueSize<<20, hex.Dump(value[:1<<10]))
}

var (
// ErrRetry is returned when a log file containing the value is not found.
// This usually indicates that it may have been garbage collected, and the
// operation needs to be retried.
ErrRetry = errors.New("Unable to find log file. Please retry")

// ErrThresholdZero is returned if threshold is set to zero, and value log GC is called.
// In such a case, GC can't be run.
ErrThresholdZero = errors.New(
"Value log GC can't run because threshold is set to zero")

// ErrNoRewrite is returned if a call for value log GC doesn't result in a log file rewrite.
ErrNoRewrite = errors.New(
"Value log GC attempt didn't result in any cleanup")

// ErrRejected is returned if a value log GC is called either while another GC is running, or
// after KV::Close has been called.
ErrRejected = errors.New("Value log GC request rejected")

// ErrInvalidRequest is returned if the user request is invalid.
ErrInvalidRequest = errors.New("Invalid request")
)
31 changes: 14 additions & 17 deletions iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,17 @@ const (
// KVItem is returned during iteration. Both the Key() and Value() output is only valid until
// iterator.Next() is called.
type KVItem struct {
status prefetchStatus
err error
wg sync.WaitGroup
kv *KV
key []byte
vptr []byte
meta byte
userMeta byte
val []byte
casCounter uint64 // TODO: Rename to version ts.
slice *y.Slice // Used only during prefetching.
next *KVItem
status prefetchStatus
err error
wg sync.WaitGroup
kv *KV
key []byte
vptr []byte
meta byte
userMeta byte
val []byte
slice *y.Slice // Used only during prefetching.
next *KVItem
}

// Key returns the key. Remember to copy if you need to access it outside the iteration loop.
Expand Down Expand Up @@ -116,10 +115,9 @@ func (item *KVItem) EstimatedSize() int64 {
return int64(vp.Len) // includes key length.
}

// Counter returns the CAS counter associated with the value.
// TODO: Make this version.
func (item *KVItem) Counter() uint64 {
return item.casCounter
// Version returns the commit timestamp of the item.
func (item *KVItem) Version() uint64 {
return y.ParseTs(item.key)
}

// UserMeta returns the userMeta set by the user. Typically, this byte, optionally set by the user
Expand Down Expand Up @@ -322,7 +320,6 @@ func (it *Iterator) fill(item *KVItem) {
vs := it.iitr.Value()
item.meta = vs.Meta
item.userMeta = vs.UserMeta
item.casCounter = vs.CASCounter
item.key = y.Safecopy(item.key, it.iitr.Key())
item.vptr = y.Safecopy(item.vptr, vs.Value)
item.val = nil
Expand Down
Loading

0 comments on commit ffd14f0

Please sign in to comment.