コード例 #1
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
}
コード例 #2
0
ファイル: reader.go プロジェクト: yufeng108/goleveldb
// 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
}