func (t *Table) Optimize() (e error) {
	if e = t.Pk.Optimize(); e != nil {
		return
	}
	e = t.Chunk.Optimize()
	return
}
optimize table data.
chunk and pk are all optimized.
package jx
import (
	"errors"
	"github.com/Unknwon/com"
	"github.com/fuxiaohei/jx/col"
	"os"
	"path"
	"reflect"
)
var (
	Nil      = errors.New("nil")
	Conflict = errors.New("conflict")
	Wrong    = errors.New("wrong")
)
type Table struct {
	directory string
	Object    *Object
	Chunk *col.Chunk
	Pk    *col.PK
}
func (t *Table) Insert(v interface{}) (e error) {
	var pk interface{}
	pk, e = t.Pk.SetPk(v, t.Object.Pk)
	if e != nil {
		if e == col.PKConflict {
			e = Conflict
		}
		if e == col.PkEmpty {
			e = Wrong
		}
		return
	}
	uid, cursor, e := t.Chunk.Write(v)
	if e != nil {
		return
	}
	e = t.Pk.Write(pk, cursor, uid, 0)
	return
}
func (t *Table) Delete(v interface{}) (e error) {
	pk := reflect.ValueOf(v).Elem().FieldByName(t.Object.Pk).Interface()
	pkValue, e := t.Pk.Get(pk)
	if e != nil || pkValue == nil {
		return
	}
	if e = t.Pk.Delete(pk); e != nil {
		return
	}
	value, e := t.Chunk.Get(pkValue)
	if e != nil || value == nil {
		return
	}
	e = t.Chunk.Delete(pkValue)
	return
}
func (t *Table) Update(v interface{}) (e error) {
	pk := reflect.ValueOf(v).Elem().FieldByName(t.Object.Pk).Interface()
	pkValue, e := t.Pk.Get(pk)
	if e != nil || pkValue == nil {
		return
	}
	e = t.Chunk.Update(v, pkValue)
	if e != nil {
		return
	}
	e = t.Pk.Update(pk, pkValue)
	return
}
func (t *Table) Get(v interface{}) (e error) {
	pk := reflect.ValueOf(v).Elem().FieldByName(t.Object.Pk).Interface()
	pkValue, e := t.Pk.Get(pk)
	if e != nil {
		return
	}
	if pkValue == nil {
		e = Nil
		return
	}
	value, e := t.Chunk.Get(pkValue)
	if e != nil {
		return
	}
	if value == nil {
		e = Nil
		return
	}
	reflect.ValueOf(v).Elem().Set(reflect.ValueOf(value).Elem())
	return
}
func (t *Table) init() (e error) {
	if !com.IsDir(t.directory) {
		e = t.firstInit()
		return
	}
	dir := path.Join(t.directory, "_pk")
	if t.Pk, e = col.NewPk(dir, t.Object.PkAuto); e != nil {
		return
	}
	dir = path.Join(t.directory, "_data")
	if t.Chunk, e = col.NewChunk(dir, "data", ".dat", 1000, t.Object.DataType); e != nil {
		return
	}
	e = t.Chunk.ReadCursorFile(t.Pk.GetLastCursor(), true)
	return
}
func (t *Table) firstInit() (e error) {
	e = os.MkdirAll(t.directory, os.ModePerm)
	if e != nil {
		return
	}
	dir := path.Join(t.directory, "_data")
	if t.Chunk, e = col.NewChunk(dir, "data", ".dat", 1000, t.Object.DataType); e != nil {
		return
	}
	dir = path.Join(t.directory, "_pk")
	if t.Pk, e = col.NewPk(dir, t.Object.PkAuto); e != nil {
		return
	}
	return
}