예제 #1
0
파일: reader.go 프로젝트: 29n/goleveldb
func (t *Reader) getBlock(bi *bInfo, ro opt.ReadOptionsGetter) (b *block.Reader, err error) {
	buf, err := bi.readAll(t.r, ro.HasFlag(opt.RFVerifyChecksums))
	if err != nil {
		return
	}
	b, err = block.NewReader(buf, t.o.GetComparer())
	return
}
예제 #2
0
func (t *Reader) getDataIter(bi *bInfo, ro opt.ReadOptionsGetter) (it *block.Iterator, cache cache.Object, err error) {
	var b *block.Reader

	if t.cache != nil {
		cache, _ = t.cache.Get(bi.offset, func() (ok bool, value interface{}, charge int, fin func()) {
			var buf []byte
			buf, err = bi.readAll(t.r, ro.HasFlag(opt.RFVerifyChecksums))
			if err != nil {
				return
			}
			b, err = block.NewReader(buf, t.o.GetComparer())
			if err != nil {
				return
			}
			ok = true
			value = b
			charge = int(bi.size)
			return
		})

		if err != nil {
			return
		}

		if b == nil {
			b = cache.Value().(*block.Reader)
		}
	} else {
		var buf []byte
		buf, err = bi.readAll(t.r, ro.HasFlag(opt.RFVerifyChecksums))
		if err != nil {
			return
		}
		b, err = block.NewReader(buf, t.o.GetComparer())
		if err != nil {
			return
		}
	}

	it = b.NewIterator()
	return
}
예제 #3
0
func (p *stConstructor_Block) finish() (size int, err error) {
	csize := p.bw.Size()
	buf := p.bw.Finish()

	p.t.Logf("block: contains %d entries and %d restarts", p.bw.Len(), p.bw.CountRestart())

	size = len(buf)
	if csize != size {
		p.t.Errorf("block: calculated size doesn't equal with actual size, %d != %d", csize, size)
	}

	p.br, err = block.NewReader(buf, comparer.BytesComparer{})
	return
}
예제 #4
0
파일: reader.go 프로젝트: 29n/goleveldb
// NewReader create new initialized table reader.
func NewReader(r storage.Reader, size uint64, o opt.OptionsGetter, cache cache.Namespace) (p *Reader, err error) {
	mb, ib, err := readFooter(r, size)
	if err != nil {
		return
	}

	t := &Reader{r: r, o: o, dataEnd: mb.offset, cache: cache}

	// index block
	buf, err := ib.readAll(r, true)
	if err != nil {
		return
	}
	t.indexBlock, err = block.NewReader(buf, o.GetComparer())
	if err != nil {
		return
	}

	// we will ignore any errors at meta/filter block
	// since it is not essential for operation

	// meta block
	buf, err1 := mb.readAll(r, true)
	if err1 != nil {
		return
	}
	meta, err1 := block.NewReader(buf, comparer.BytesComparer{})
	if err1 != nil {
		return
	}

	// filter block
	iter := meta.NewIterator()
	for iter.Next() {
		key := string(iter.Key())
		if !strings.HasPrefix(key, "filter.") {
			continue
		}
		if filter := o.GetAltFilter(key[7:]); filter != nil {
			fb := new(bInfo)
			_, err1 = fb.decodeFrom(iter.Value())
			if err1 != nil {
				continue
			}

			// now the data block end before filter block start offset
			// instead of meta block start offset
			t.dataEnd = fb.offset

			buf, err1 = fb.readAll(r, true)
			if err1 != nil {
				continue
			}
			t.filterBlock, err1 = block.NewFilterReader(buf, filter)
			if err1 != nil {
				continue
			}
			break
		}
	}

	return t, nil
}
예제 #5
0
// NewReader create new initialized table reader.
func NewReader(r desc.Reader, size uint64, o opt.OptionsGetter, cache cache.Namespace) (p *Reader, err error) {
	mb, ib, err := readFooter(r, size)
	if err != nil {
		return
	}

	t := &Reader{r: r, o: o, dataEnd: mb.offset, cache: cache}

	// index block
	buf, err := ib.readAll(r, true)
	if err != nil {
		return
	}
	t.index, err = block.NewReader(buf, o.GetComparer())
	if err != nil {
		return
	}

	// filter block
	filter := o.GetFilter()
	if filter != nil {
		// we will ignore any errors at meta/filter block
		// since it is not essential for operation

		// meta block
		buf, err = mb.readAll(r, true)
		if err != nil {
			goto out
		}
		var meta *block.Reader
		meta, err = block.NewReader(buf, comparer.BytesComparer{})
		if err != nil {

			goto out
		}

		// check for filter name
		iter := meta.NewIterator()
		key := "filter." + filter.Name()
		if iter.Seek([]byte(key)) && string(iter.Key()) == key {
			fb := new(bInfo)
			_, err = fb.decodeFrom(iter.Value())
			if err != nil {
				return
			}

			// now the data end before filter block start offset
			t.dataEnd = fb.offset

			// filter block
			buf, err = fb.readAll(r, true)
			if err != nil {
				goto out
			}
			t.filter, err = block.NewFilterReader(buf, filter)
			if err != nil {
				goto out
			}
		}
	}

out:
	return t, nil
}