// 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" "errors" "io" ) var errCorruptManifest = errors.New("leveldb: corrupt manifest") type byteReader interface { io.Reader io.ByteReader } // These numbers are written to disk and should not be changed. const ( recComparer = 1 recJournalNum = 2 recNextNum = 3 recSeq = 4 recCompactionPointer = 5 recDeletedTable = 6 recNewTable = 7 // 8 was used for large value refs recPrevJournalNum = 9 ) type cpRecord struct { level int key iKey } type ntRecord struct { level int num uint64 size uint64 min iKey max iKey } func (r ntRecord) makeFile(s *session) *tFile { return newTFile(s.getTableFile(r.num), r.size, r.min, r.max) } type dtRecord struct { level int num uint64 } type sessionRecord struct { hasRec int comparer string journalNum uint64 prevJournalNum uint64 nextNum uint64 seq uint64 compactionPointers []cpRecord addedTables []ntRecord deletedTables []dtRecord scratch [binary.MaxVarintLen64]byte err error } func (p *sessionRecord) has(rec int) bool { return p.hasRec&(1<= kNumLevels { p.err = errCorruptManifest return 0 } return int(x) } func (p *sessionRecord) decode(r io.Reader) error { br, ok := r.(byteReader) if !ok { br = bufio.NewReader(r) } p.err = nil for p.err == nil { rec, err := binary.ReadUvarint(br) if err != nil { if err == io.EOF { err = nil } return err } switch rec { case recComparer: x := p.readBytes(br) if p.err == nil { p.setComparer(string(x)) } case recJournalNum: x := p.readUvarint(br) if p.err == nil { p.setJournalNum(x) } case recPrevJournalNum: x := p.readUvarint(br) if p.err == nil { p.setPrevJournalNum(x) } case recNextNum: x := p.readUvarint(br) if p.err == nil { p.setNextNum(x) } case recSeq: x := p.readUvarint(br) if p.err == nil { p.setSeq(x) } case recCompactionPointer: level := p.readLevel(br) key := p.readBytes(br) if p.err == nil { p.addCompactionPointer(level, iKey(key)) } case recNewTable: level := p.readLevel(br) num := p.readUvarint(br) size := p.readUvarint(br) min := p.readBytes(br) max := p.readBytes(br) if p.err == nil { p.addTable(level, num, size, min, max) } case recDeletedTable: level := p.readLevel(br) num := p.readUvarint(br) if p.err == nil { p.deleteTable(level, num) } } } return p.err }