Get looks for key and returns corresponding Item. If key is not found, ErrKeyNotFound is returned.
(key []byte)
| 439 | // Get looks for key and returns corresponding Item. |
| 440 | // If key is not found, ErrKeyNotFound is returned. |
| 441 | func (txn *Txn) Get(key []byte) (item *Item, rerr error) { |
| 442 | if len(key) == 0 { |
| 443 | return nil, ErrEmptyKey |
| 444 | } else if txn.discarded { |
| 445 | return nil, ErrDiscardedTxn |
| 446 | } |
| 447 | |
| 448 | item = new(Item) |
| 449 | if txn.update { |
| 450 | if e, has := txn.pendingWrites[string(key)]; has && bytes.Equal(key, e.Key) { |
| 451 | if isDeletedOrExpired(e.meta, e.ExpiresAt) { |
| 452 | return nil, ErrKeyNotFound |
| 453 | } |
| 454 | // Fulfill from cache. |
| 455 | item.meta = e.meta |
| 456 | item.val = e.Value |
| 457 | item.userMeta = e.UserMeta |
| 458 | item.key = key |
| 459 | item.status = prefetched |
| 460 | item.version = txn.readTs |
| 461 | item.expiresAt = e.ExpiresAt |
| 462 | // We probably don't need to set db on item here. |
| 463 | return item, nil |
| 464 | } |
| 465 | // Only track reads if this is update txn. No need to track read if txn serviced it |
| 466 | // internally. |
| 467 | txn.addReadKey(key) |
| 468 | } |
| 469 | |
| 470 | seek := y.KeyWithTs(key, txn.readTs) |
| 471 | vs, err := txn.db.get(seek) |
| 472 | if err != nil { |
| 473 | return nil, errors.Wrapf(err, "DB::Get key: %q", key) |
| 474 | } |
| 475 | if vs.Value == nil && vs.Meta == 0 { |
| 476 | return nil, ErrKeyNotFound |
| 477 | } |
| 478 | if isDeletedOrExpired(vs.Meta, vs.ExpiresAt) { |
| 479 | return nil, ErrKeyNotFound |
| 480 | } |
| 481 | |
| 482 | item.key = key |
| 483 | item.version = vs.Version |
| 484 | item.meta = vs.Meta |
| 485 | item.userMeta = vs.UserMeta |
| 486 | item.db = txn.db |
| 487 | item.vptr = y.SafeCopy(item.vptr, vs.Value) |
| 488 | item.txn = txn |
| 489 | item.expiresAt = vs.ExpiresAt |
| 490 | return item, nil |
| 491 | } |
| 492 | |
| 493 | func (txn *Txn) addReadKey(key []byte) { |
| 494 | if txn.update { |