func (part *Partition) ApproxDocCount() int {
	totalPart := 24  
	for {
		keys, _ := part.lookup.GetPartition(0, totalPart)
		if len(keys) == 0 {
			if totalPart < 8 {
				return 0  
			}
			totalPart = totalPart / 2
		} else {
			return int(float64(len(keys)) * float64(totalPart))
		}
	}
}
Return approximate number of documents in the partition.
package data
import (
	"sync"
	"github.com/HouzuoGuo/tiedot/dberr"
	"github.com/HouzuoGuo/tiedot/tdlog"
)
type Partition struct {
	*Config
	col      *Collection
	lookup   *HashTable
	DataLock *sync.RWMutex  
	exclUpdate     map[int]chan struct{}
	exclUpdateLock *sync.Mutex  
}
func (conf *Config) newPartition() *Partition {
	conf.CalculateConfigConstants()
	return &Partition{
		Config:         conf,
		exclUpdateLock: new(sync.Mutex),
		exclUpdate:     make(map[int]chan struct{}),
		DataLock:       new(sync.RWMutex),
	}
}
func (conf *Config) OpenPartition(colPath, lookupPath string) (part *Partition, err error) {
	part = conf.newPartition()
	part.CalculateConfigConstants()
	if part.col, err = conf.OpenCollection(colPath); err != nil {
		return
	} else if part.lookup, err = conf.OpenHashTable(lookupPath); err != nil {
		return
	}
	return
}
func (part *Partition) Insert(id int, data []byte) (physID int, err error) {
	physID, err = part.col.Insert(data)
	if err != nil {
		return
	}
	part.lookup.Put(id, physID)
	return
}
func (part *Partition) Read(id int) ([]byte, error) {
	physID := part.lookup.Get(id, 1)
	if len(physID) == 0 {
		return nil, dberr.New(dberr.ErrorNoDoc, id)
	}
	data := part.col.Read(physID[0])
	if data == nil {
		return nil, dberr.New(dberr.ErrorNoDoc, id)
	}
	return data, nil
}
func (part *Partition) Update(id int, data []byte) (err error) {
	physID := part.lookup.Get(id, 1)
	if len(physID) == 0 {
		return dberr.New(dberr.ErrorNoDoc, id)
	}
	newID, err := part.col.Update(physID[0], data)
	if err != nil {
		return
	}
	if newID != physID[0] {
		part.lookup.Remove(id, physID[0])
		part.lookup.Put(id, newID)
	}
	return
}
func (part *Partition) LockUpdate(id int) {
	for {
		part.exclUpdateLock.Lock()
		ch, ok := part.exclUpdate[id]
		if !ok {
			part.exclUpdate[id] = make(chan struct{})
		}
		part.exclUpdateLock.Unlock()
		if ok {
			<-ch
		} else {
			break
		}
	}
}
func (part *Partition) UnlockUpdate(id int) {
	part.exclUpdateLock.Lock()
	ch := part.exclUpdate[id]
	delete(part.exclUpdate, id)
	part.exclUpdateLock.Unlock()
	close(ch)
}
func (part *Partition) Delete(id int) (err error) {
	physID := part.lookup.Get(id, 1)
	if len(physID) == 0 {
		return dberr.New(dberr.ErrorNoDoc, id)
	}
	part.col.Delete(physID[0])
	part.lookup.Remove(id, physID[0])
	return
}
func (part *Partition) ForEachDoc(partNum, totalPart int, fun func(id int, doc []byte) bool) (moveOn bool) {
	ids, physIDs := part.lookup.GetPartition(partNum, totalPart)
	for i, id := range ids {
		data := part.col.Read(physIDs[i])
		if data != nil {
			if !fun(id, data) {
				return false
			}
		}
	}
	return true
}