get returns the value in memtable or disk for given key. Note that value will include meta byte. IMPORTANT: We should never write an entry with an older timestamp for the same key, We need to maintain this invariant to search for the latest value of a key, or else we need to search in all tables an
(key []byte)
| 640 | // been moved, then for the corresponding movekey, we'll look through all the levels of the tree |
| 641 | // to ensure that we pick the highest version of the movekey present. |
| 642 | func (db *DB) get(key []byte) (y.ValueStruct, error) { |
| 643 | tables, decr := db.getMemTables() // Lock should be released. |
| 644 | defer decr() |
| 645 | |
| 646 | var maxVs *y.ValueStruct |
| 647 | var version uint64 |
| 648 | if bytes.HasPrefix(key, badgerMove) { |
| 649 | // If we are checking badgerMove key, we should look into all the |
| 650 | // levels, so we can pick up the newer versions, which might have been |
| 651 | // compacted down the tree. |
| 652 | maxVs = &y.ValueStruct{} |
| 653 | version = y.ParseTs(key) |
| 654 | } |
| 655 | |
| 656 | y.NumGets.Add(1) |
| 657 | for i := 0; i < len(tables); i++ { |
| 658 | vs := tables[i].Get(key) |
| 659 | y.NumMemtableGets.Add(1) |
| 660 | if vs.Meta == 0 && vs.Value == nil { |
| 661 | continue |
| 662 | } |
| 663 | // Found a version of the key. For user keyspace, return immediately. For move keyspace, |
| 664 | // continue iterating, unless we found a version == given key version. |
| 665 | if maxVs == nil || vs.Version == version { |
| 666 | return vs, nil |
| 667 | } |
| 668 | if maxVs.Version < vs.Version { |
| 669 | *maxVs = vs |
| 670 | } |
| 671 | } |
| 672 | return db.lc.get(key, maxVs, 0) |
| 673 | } |
| 674 | |
| 675 | // updateHead should not be called without the db.Lock() since db.vhead is used |
| 676 | // by the writer go routines and memtable flushing goroutine. |