// Copyright (c) 2012, Suryandaru Triandana // All rights reserved. // // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package leveldb import ( "bufio" "encoding/binary" "io" "strings" "github.com/syndtr/goleveldb/leveldb/errors" ) type byteReader interface { io.Reader io.ByteReader } // These numbers are written to disk and should not be changed. const ( recComparer = 1 recJournalNum = 2 recNextFileNum = 3 recSeqNum = 4 recCompPtr = 5 recDelTable = 6 recAddTable = 7 // 8 was used for large value refs recPrevJournalNum = 9 ) type cpRecord struct { level int ikey iKey } type atRecord struct { level int num uint64 size uint64 imin iKey imax iKey } type dtRecord struct { level int num uint64 } type sessionRecord struct { hasRec int comparer string journalNum uint64 prevJournalNum uint64 nextFileNum uint64 seqNum uint64 compPtrs []cpRecord addedTables []atRecord deletedTables []dtRecord scratch [binary.MaxVarintLen64]byte err error } func (p *sessionRecord) has(rec int) bool { return p.hasRec&(1<= uint64(numLevel) { p.err = errors.NewErrCorrupted(nil, &ErrManifestCorrupted{field, "invalid level number"}) return 0 } return int(x) } func (p *sessionRecord) decode(r io.Reader, numLevel int) error { br, ok := r.(byteReader) if !ok { br = bufio.NewReader(r) } p.err = nil for p.err == nil { rec := p.readUvarintMayEOF("field-header", br, true) if p.err != nil { if p.err == io.EOF { return nil } return p.err } switch rec { case recComparer: x := p.readBytes("comparer", br) if p.err == nil { p.setComparer(string(x)) } case recJournalNum: x := p.readUvarint("journal-num", br) if p.err == nil { p.setJournalNum(x) } case recPrevJournalNum: x := p.readUvarint("prev-journal-num", br) if p.err == nil { p.setPrevJournalNum(x) } case recNextFileNum: x := p.readUvarint("next-file-num", br) if p.err == nil { p.setNextFileNum(x) } case recSeqNum: x := p.readUvarint("seq-num", br) if p.err == nil { p.setSeqNum(x) } case recCompPtr: level := p.readLevel("comp-ptr.level", br, numLevel) ikey := p.readBytes("comp-ptr.ikey", br) if p.err == nil { p.addCompPtr(level, iKey(ikey)) } case recAddTable: level := p.readLevel("add-table.level", br, numLevel) num := p.readUvarint("add-table.num", br) size := p.readUvarint("add-table.size", br) imin := p.readBytes("add-table.imin", br) imax := p.readBytes("add-table.imax", br) if p.err == nil { p.addTable(level, num, size, imin, imax) } case recDelTable: level := p.readLevel("del-table.level", br, numLevel) num := p.readUvarint("del-table.num", br) if p.err == nil { p.delTable(level, num) } } } return p.err }