Read reads the value log at a given location. TODO: Make this read private.
(vp valuePointer, s *y.Slice)
| 1535 | // Read reads the value log at a given location. |
| 1536 | // TODO: Make this read private. |
| 1537 | func (vlog *valueLog) Read(vp valuePointer, s *y.Slice) ([]byte, func(), error) { |
| 1538 | buf, lf, err := vlog.readValueBytes(vp, s) |
| 1539 | // log file is locked so, decide whether to lock immediately or let the caller to |
| 1540 | // unlock it, after caller uses it. |
| 1541 | cb := vlog.getUnlockCallback(lf) |
| 1542 | if err != nil { |
| 1543 | return nil, cb, err |
| 1544 | } |
| 1545 | |
| 1546 | if vlog.opt.VerifyValueChecksum { |
| 1547 | hash := crc32.New(y.CastagnoliCrcTable) |
| 1548 | if _, err := hash.Write(buf[:len(buf)-crc32.Size]); err != nil { |
| 1549 | runCallback(cb) |
| 1550 | return nil, nil, errors.Wrapf(err, "failed to write hash for vp %+v", vp) |
| 1551 | } |
| 1552 | // Fetch checksum from the end of the buffer. |
| 1553 | checksum := buf[len(buf)-crc32.Size:] |
| 1554 | if hash.Sum32() != y.BytesToU32(checksum) { |
| 1555 | runCallback(cb) |
| 1556 | return nil, nil, errors.Wrapf(y.ErrChecksumMismatch, "value corrupted for vp: %+v", vp) |
| 1557 | } |
| 1558 | } |
| 1559 | var h header |
| 1560 | headerLen := h.Decode(buf) |
| 1561 | kv := buf[headerLen:] |
| 1562 | if lf.encryptionEnabled() { |
| 1563 | kv, err = lf.decryptKV(kv, vp.Offset) |
| 1564 | if err != nil { |
| 1565 | return nil, cb, err |
| 1566 | } |
| 1567 | } |
| 1568 | if uint32(len(kv)) < h.klen+h.vlen { |
| 1569 | vlog.db.opt.Logger.Errorf("Invalid read: vp: %+v", vp) |
| 1570 | return nil, nil, errors.Errorf("Invalid read: Len: %d read at:[%d:%d]", |
| 1571 | len(kv), h.klen, h.klen+h.vlen) |
| 1572 | } |
| 1573 | return kv[h.klen : h.klen+h.vlen], cb, nil |
| 1574 | } |
| 1575 | |
| 1576 | // getUnlockCallback will returns a function which unlock the logfile if the logfile is mmaped. |
| 1577 | // otherwise, it unlock the logfile and return nil. |