Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,45 @@ func (c *Cdb) Data(key []byte) (data []byte, err error) {
return
}

// DumpN returns n records, starting at record number o, from the cdb as an
// array of [2][]byte values: key, data.
// If n is 0, then all of the records are returned.
func (c *Cdb) DumpN(n uint64, o uint64) (recs [][2][]byte) {
intBuf := make([]byte, 4)
pos := uint32(0)
readNum := func () uint32 {
c.r.ReadAt(intBuf, int64(pos))
pos += 4
return binary.LittleEndian.Uint32(intBuf)
}

eod := readNum()
pos = headerSize // skip header
recNum := uint64(0)
for pos < eod && (n == 0 || recNum < n) {
// CDB records are laid out as: [klen (uint32)] [dlen (uint32)] [key (klen bytes)] [data (dlen bytes)]
klen := readNum()
dlen := readNum()
if recNum >= o {
// read key and data:
k := make([]byte, klen)
d := make([]byte, dlen)
c.r.ReadAt(k, int64(pos))
pos += klen
c.r.ReadAt(d, int64(pos))
pos += dlen
recs = append(recs, [2][]byte{k, d})
} else {
// skip:
pos += klen + dlen
}

recNum++
}

return
}

// FindStart resets the cdb to search for the first record under a new key.
func (c *Cdb) FindStart() { c.loop = 0 }

Expand Down
32 changes: 23 additions & 9 deletions dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@ import (
"io"
)

// Dump reads the cdb-formatted data in r and dumps it as a series of formatted
// records (+klen,dlen:key->data\n) and a final newline to w.
// Dump reads records from the cdb-formatted data in r and dumps it as a
// series of formatted records (+klen,dlen:key->data\n) and a final newline to w.
// The output of Dump is suitable as input to Make.
// See http://cr.yp.to/cdb/cdbmake.html for details on the record format.
func Dump(w io.Writer, r io.Reader) (err error) {
func Dump(w io.Writer, r io.Reader) error {
return DumpN(0, 0, w, r)
}

// DumpN reads n records, starting at record number o, from the cdb-formatted
// data in r and dumps it as a series of formatted records
// (+klen,dlen:key->data\n) and a final newline to w.
// If n is 0, then all of the records are dumped.
// The output of DumpN is suitable as input to Make.
// See http://cr.yp.to/cdb/cdbmake.html for details on the record format.
func DumpN(n uint64, o uint64, w io.Writer, r io.Reader) (err error) {
defer func() { // Centralize exception handling.
if e := recover(); e != nil {
err = e.(error)
Expand All @@ -29,14 +39,18 @@ func Dump(w io.Writer, r io.Reader) (err error) {
}

pos := headerSize
for pos < eod {
recNum := uint64(0)
for pos < eod && (n == 0 || recNum < n) {
klen, dlen := readNum(), readNum()
rw.writeString(fmt.Sprintf("+%d,%d:", klen, dlen))
rw.copyn(rb, klen)
rw.writeString("->")
rw.copyn(rb, dlen)
rw.writeString("\n")
if recNum >= o {
rw.writeString(fmt.Sprintf("+%d,%d:", klen, dlen))
rw.copyn(rb, klen)
rw.writeString("->")
rw.copyn(rb, dlen)
rw.writeString("\n")
}
pos += 8 + klen + dlen
recNum++
}
rw.writeString("\n")

Expand Down