func (s *dbs) Size() uint16 {
	s.mtx.RLock()
	defer s.mtx.RUnlock()
	return s.size
}
Size returns the number of header & validator set pairs.

Safe for concurrent use by multiple goroutines.
package db
import (
	"encoding/binary"
	"fmt"
	"github.com/google/orderedcode"
	dbm "github.com/tendermint/tm-db"
	tmsync "github.com/tendermint/tendermint/internal/libs/sync"
	"github.com/tendermint/tendermint/light/store"
	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
	"github.com/tendermint/tendermint/types"
)
const (
	prefixLightBlock = int64(11)
	prefixSize       = int64(12)
)
type dbs struct {
	db dbm.DB
	mtx  tmsync.RWMutex
	size uint16
}
func New(db dbm.DB) store.Store {
	lightStore := &dbs{db: db}
	size := uint16(0)
	bz, err := lightStore.db.Get(lightStore.sizeKey())
	if err == nil && len(bz) > 0 {
		size = unmarshalSize(bz)
	}
	lightStore.size = size
	return lightStore
}
func (s *dbs) SaveLightBlock(lb *types.LightBlock) error {
	if lb.Height <= 0 {
		panic("negative or zero height")
	}
	lbpb, err := lb.ToProto()
	if err != nil {
		return fmt.Errorf("unable to convert light block to protobuf: %w", err)
	}
	lbBz, err := lbpb.Marshal()
	if err != nil {
		return fmt.Errorf("marshaling LightBlock: %w", err)
	}
	s.mtx.Lock()
	defer s.mtx.Unlock()
	b := s.db.NewBatch()
	defer b.Close()
	if err = b.Set(s.lbKey(lb.Height), lbBz); err != nil {
		return err
	}
	if err = b.Set(s.sizeKey(), marshalSize(s.size+1)); err != nil {
		return err
	}
	if err = b.WriteSync(); err != nil {
		return err
	}
	s.size++
	return nil
}
func (s *dbs) DeleteLightBlock(height int64) error {
	if height <= 0 {
		panic("negative or zero height")
	}
	s.mtx.Lock()
	defer s.mtx.Unlock()
	b := s.db.NewBatch()
	defer b.Close()
	if err := b.Delete(s.lbKey(height)); err != nil {
		return err
	}
	if err := b.Set(s.sizeKey(), marshalSize(s.size-1)); err != nil {
		return err
	}
	if err := b.WriteSync(); err != nil {
		return err
	}
	s.size--
	return nil
}
func (s *dbs) LightBlock(height int64) (*types.LightBlock, error) {
	if height <= 0 {
		panic("negative or zero height")
	}
	bz, err := s.db.Get(s.lbKey(height))
	if err != nil {
		panic(err)
	}
	if len(bz) == 0 {
		return nil, store.ErrLightBlockNotFound
	}
	var lbpb tmproto.LightBlock
	err = lbpb.Unmarshal(bz)
	if err != nil {
		return nil, fmt.Errorf("unmarshal error: %w", err)
	}
	lightBlock, err := types.LightBlockFromProto(&lbpb)
	if err != nil {
		return nil, fmt.Errorf("proto conversion error: %w", err)
	}
	return lightBlock, err
}
func (s *dbs) LastLightBlockHeight() (int64, error) {
	itr, err := s.db.ReverseIterator(
		s.lbKey(1),
		append(s.lbKey(1<<63-1), byte(0x00)),
	)
	if err != nil {
		panic(err)
	}
	defer itr.Close()
	if itr.Valid() {
		return s.decodeLbKey(itr.Key())
	}
	return -1, itr.Error()
}
func (s *dbs) FirstLightBlockHeight() (int64, error) {
	itr, err := s.db.Iterator(
		s.lbKey(1),
		append(s.lbKey(1<<63-1), byte(0x00)),
	)
	if err != nil {
		panic(err)
	}
	defer itr.Close()
	if itr.Valid() {
		return s.decodeLbKey(itr.Key())
	}
	return -1, itr.Error()
}
func (s *dbs) LightBlockBefore(height int64) (*types.LightBlock, error) {
	if height <= 0 {
		panic("negative or zero height")
	}
	itr, err := s.db.ReverseIterator(
		s.lbKey(1),
		s.lbKey(height),
	)
	if err != nil {
		panic(err)
	}
	defer itr.Close()
	if itr.Valid() {
		var lbpb tmproto.LightBlock
		err = lbpb.Unmarshal(itr.Value())
		if err != nil {
			return nil, fmt.Errorf("unmarshal error: %w", err)
		}
		lightBlock, err := types.LightBlockFromProto(&lbpb)
		if err != nil {
			return nil, fmt.Errorf("proto conversion error: %w", err)
		}
		return lightBlock, nil
	}
	if err = itr.Error(); err != nil {
		return nil, err
	}
	return nil, store.ErrLightBlockNotFound
}
func (s *dbs) Prune(size uint16) error {
	s.mtx.Lock()
	defer s.mtx.Unlock()
	sSize := s.size
	if sSize <= size {  
		return nil
	}
	numToPrune := sSize - size
	b := s.db.NewBatch()
	defer b.Close()
	if err := s.batchDelete(b, numToPrune); err != nil {
		return err
	}
	s.size = size
	if err := b.Set(s.sizeKey(), marshalSize(size)); err != nil {
		return fmt.Errorf("failed to persist size: %w", err)
	}
	return b.WriteSync()
}