██████╗ ███████╗███████╗ ██████╗ ██████╗
██╔══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗
██████╔╝█████╗ ███████╗██║ ██║██████╔╝
██╔══██╗██╔══╝ ╚════██║██║ ██║██╔══██╗
██║ ██║███████╗███████║╚██████╔╝██████╔╝
╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝
resob是remote service of BsTr tree的缩写。包resob定义了一个名为BsTr的结构,并基于该结构实现了一个可以指针混写的类B+树,借鉴脉动工作流模式,支持表级并行度。纯go标准库实现,没有额外的依赖。
resob_jsondb是基于BsTr树的json数据库,支持特定的json格式作为包含数据的操作命令,通过解析json实现插入、删除、更新和查找。
一个退役中校教你如何用go语言写一个基于B+树的json数据库
{"showdbs":""}
{"use":{"db":"info-energizer","remotelog":"127.0.0.1:9527","readonly":false,"usr":"resob","pwd":"jsonany"}}
{"updpwd":{"usr":"resob","pwd":"anyjson"}}
{"showdts":"info-energizer"}
{"get":{"personal_info":"{*}","fields":"[*]"}}
{"page":"next"}/{"page":"prev"}/{"page":200}
{"get":{"family_name:personal_info":"{~
李}","fields":"[
personal_info.family_name,
personal_info.name]"}}
dt.field
) for results.{"get":{"time_performance":"{>=0}","fields":"[*]"}}
{"put":{"key":1234560,"personal_info":{"personid":"0880124199802032569","family_name":"李","name":"三","native_place":"某地","personnel_category":"某种**人员","mt_rank":"某校","mt_appointment":"某长","mt_technical_level":"无","civil_service_level":"无","civil_management_position":"无","political_party":"XXXXX","race":"汉","party_membership_time":"2005-10-05","working_time":"2004-12-01","enlistment_time":"2004-12-01","health_condition":"健康","education":"大学","academic_degree":"本科","graduated":"某院","speciality":"某专业","in-service_education":"无","in-service_academic_degree":"无","in-service_graduated":"无","in-service_speciality":"无","honors_awards":"awards 2次","mt_skills":"某技能","mt_drill":"某大型XXX","resume":"2004.12-2006.09 某XXX soldier;2006.09-2023.06 某XXX commander。"}}}
{"upd":{"key":1234560,"personal_info":{"family_name":"liu"}}}
{"del":[{"key":123456,"personal_info":{}},{"key":1234560,"personal_info":{}}]}
{"close":{"db":"info-energizer"}}
import (
"gitee.com/lineofsight/resob"
)
func main(){
dbsp, dbspf := InitDbsp(new(DefaultJsonDbAuth))
log.Println(dbsp)
defer CloseDbsp(dbsp, dbspf)
log.Println(dbsp)
s := "{\"use\":{\"db\":\"test00\",\"remotelog\":\"127.0.0.1:9527\",\"readonly\":false,\"usr\":\"resob000\",\"pwd\":\"jsonany\"}}"
ur := UseDb(&DbspUseDbParams{s, dbsp, dbspf})
if ur.E != nil {
log.Println(ur.E)
}
log.Println(ur.Jdb)
log.Println(dbsp)
tml := "{\"set\":{\"key\":123456,\"personal_info\":{\"aaa\":\"!\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":1,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
Jdb, _, rs, e := LocalCenterJsonEngine(dbsp, dbspf, ur.Jdb, tml, nil)
if e != nil {
log.Println(rs, e)
}
s = "{\"put\":{\"key\":123456,\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, ur.Jdb, s, nil)
if e != nil {
log.Println(e)
}
s6 := "{\"put\":{\"personal_info\":{\"anyany\":\"anysdf\tsdfs\\dfe29asdf\",\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s6, nil)
if e != nil {
log.Println(e)
}
s5 := "{\"put\":{\"key\":0123456,\"personal_info\":{\"anyany\":\"anysdf\tsdfs\\dfe29asdf\",\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s5, nil)
if e != nil {
log.Println(e)
}
s0 := "{\"put\":[{\"key\":12345678,\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}},{\"key\":1234560,\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}]}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s0, nil)
if e != nil {
log.Println(e)
}
s1 := "{\"put\":{\"key\":123456,\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s1, nil)
if e != nil {
log.Println(e)
}
s2 := "{\"put\":[{\"key\":1234567823324,\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}},{\"key\":\"1234560\",\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}]}"
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s2, nil)
if e != nil {
log.Println(e)
}
wg := new(sync.WaitGroup)
wg.Add(900)
for i := 0; i < 300; i++ {
s3 := "{\"put\":{\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
go func(s string) {
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s, nil)
if e != nil {
log.Println(e)
}
wg.Done()
}(s3)
s4 := "{\"put\":[{\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}},{\"personal_info\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}]}"
go func(s string) {
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s, nil)
if e != nil {
log.Println(e)
}
wg.Done()
}(s4)
s7 := "{\"put\":{\"personal_info\":{\"anyany\":\"anysdf\tsdfs\\dfe29asdf\",\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
go func(s string) {
Jdb, _, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, s, nil)
if e != nil {
log.Println(e)
}
wg.Done()
}(s7)
}
wg.Wait()
ss := []string{
"{\"Get\":{\"personal_info\":\"{>=-6357736063366594537,<=2865645942165471232}\",\"personal_info\":\"{>=-123456,<=123456782332455}\",\"personal_info\":\"{!=123456}\",\"aaa:personal_info\":\"{~`sdf`}\",\"fields\":\"[`personal_info.aaa`,`personal_info.aaab`,`personal_info.arrarrstrct.ccc`,`personal_info.comboolarr`]\"}}",
"{\"Get\":{\"personal_info\":\"{>=-6357736063366594537,<=6865645942165471232}\",\"fields\":\"[*]\"}}",
}
var jr *JsonResults
for i := 0; i < len(ss); i++ {
Jdb, jr, rs, e = LocalCenterJsonEngine(dbsp, dbspf, Jdb, ss[i], jr)
if e != nil {
log.Println(e)
}
log.Println(rs)
if jr == nil {
continue
}
for {
jr.SetOrientation(true)
if jr.IsEnd(true) {
break
}
jr, rs = jr.SomeJsons()
log.Println(rs)
jr.SetOrientation(true)
log.Print("curpageNO--WantedpageNO:")
log.Println(jr.GetCurWanPageNO())
}
}
s = "{\"close\":{\"db\":\"test00\"}}"
log.Println(CloseDb(&DbspCloseDbParams{s, ur.Jdb}))
}
(1) put
import (
"gitee.com/lineofsight/resob"
)
func main(){
cs := new(BsTr)
//must init pool firstly
cs.InitPool(nil)
//init a Bstr struct with no nids, and open file "log"
cs.InitWithLogNonids("", "", true)
f, err := os.OpenFile("data/putjson.atd", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("打开数据文件失败:", err)
} else {
defer f.Close()
}
binlogf, err := os.OpenFile("binlog/putjson.binlog", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("打开数据文件失败:", err)
} else {
defer binlogf.Close()
}
logc, err := net.Dial("tcp", "127.0.0.1:9528")
if err != nil {
log.Println("failed:", err)
} else {
defer logc.Close()
}
var ckpcs *BsTr
cs, ckpcs, err = cs.Start(f, binlogf)
log.Println(ckpcs)
log.Println("######################################")
jdt := new(JsonDt)
jdt.Init(f, binlogf, logc, nil)
tml := "{\"set\":{\"key\":123456,\"putjsontest0\":{\"aaa\":\"!\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":1,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
jdt = jdt.SetSpire(cs).SetJsonTemplate(tml, false)
wg := new(sync.WaitGroup)
wg.Add(300)
for i := 0; i < 100; i++ {
s := "{\"put\":{\"key\":123456,\"putjsontest0\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
go func(s string) {
log.Println(jdt.Put(s))
wg.Done()
}(s)
s = "{\"put\":{\"key\":123456,\"putjsontest0\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
go func(s string) {
log.Println(jdt.Put(s))
wg.Done()
}(s)
s = "{\"put\":{\"key\":123456,\"putjsontest0\":{\"aaa\":\"sdf\tsdfs\\dfe29asdf\",\"aaab\":true,\"arrarrstrct\":{\"nnn\":-1234567890,\"ccc\":[[\"sdf\tsdfs\\dfe29asdf\",\"nmbndfvdfgfdg\"],[\"sdf\tsdfs\\dfe29asdf\",\"poiuiyyttt\"]]},\"ddd\":\"sdf\tsdfs\\dfe29asdf\",\"fff\":false,\"comboolarr\":[{\"boolarr0\":[true,false]},{\"boolarr1\":[true,false]}]}}}"
go func(s string) {
log.Println(jdt.Put(s))
wg.Done()
}(s)
}
wg.Wait()
cs.Plb(0, f, true)
cs.End(true, f)
}
(2) get
func main(){
cs := new(BsTr)
cs.InitPool(nil)
cs.InitWithLogNonids("", "", true)
f, err := os.OpenFile("data/putjson.atd", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("打开数据文件失败:", err)
} else {
defer f.Close()
}
binlogf, err := os.OpenFile("binlog/putjson.binlog", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("打开数据文件失败:", err)
} else {
defer binlogf.Close()
}
logc, err := net.Dial("tcp", "127.0.0.1:9528")
if err != nil {
log.Println("failed:", err)
} else {
defer logc.Close()
}
cs, _, _ = cs.Start(f, binlogf)
log.Println("######################################")
jdt := new(JsonDt)
jdt.Init(f, binlogf, logc, nil)
jdt = jdt.SetSpire(cs)
jdt = jdt.GetEmbedSpire("putjsontest0")
log.Println("-----------------------------------")
ss := []string{
"{\"Get\":{\"putjsontest0\":{[\"{>=-6357736063366594537,<=2865645942165471232}\",\"{>=-123456,<=1234567823324}\",\"{!=123456}\"],\"aaa\":\"{~`sdf`}\"},\"fields\":\"[`putjsontest0.aaa`,`putjsontest0.aaab`,`putjsontest0.arrarrstrct.ccc`,`putjsontest0.comboolarr`]\"}}",
"{\"Get\":{\"putjsontest0\":\"{>=-6357736063366594537,<=2865645942165471232}\",\"putjsontest0\":\"{>=-123456,<=2865645942165471232}\",\"putjsontest0\":\"{!=123456}\",\"aaa:putjsontest0\":\"{~`sdf`}\",\"fields\":\"[`putjsontest0.aaa`,`putjsontest0.aaab`,`putjsontest0.arrarrstrct.ccc`,`putjsontest0.comboolarr`]\"}}",
"{\"Get\":{\"putjsontest0\":\"{>=-6357736063366594537,<=6865645942165471232}\",\"fields\":\"[*]\"}}",
}
var jsondata string
for i := 0; i < len(ss); i++ {
log.Println("======================================")
jr := jdt.SetFindJson(ss[i])
if jr != nil {
log.Println(jr)
jr = jr.SomeStart()
log.Print("curpageNO--WantedpageNO:")
log.Println(jr.GetCurWanPageNO())
for {
jr, jsondata = jr.SomeJsons()
log.Println(jsondata)
if jr.IsEnd(true) {
break
}
jr.SetOrientation(true)
log.Print("curpageNO--WantedpageNO:")
log.Println(jr.GetCurWanPageNO())
}
}
}
}
import (
"gitee.com/lineofsight/resob"
)
func main(){
dataf, err := os.OpenFile("data/test.atd", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("failed:", err)
} else {
defer dataf.Close()
}
binlogf, err := os.OpenFile("binlog/test.binlog", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("failed:", err)
} else {
defer binlogf.Close()
}
logc, err := net.Dial("tcp", "127.0.0.1:9528")
if err != nil {
log.Println("failed:", err)
} else {
defer logc.Close()
}
cs := new(BsTr)
//must init pool firstly
cs.InitPool(dataf)
//init a Bstr struct with no nids, and open file "log"
cs.InitWithLogNonids("", "", true)
rs := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
var cif DefaultCIf
var ckpcs *BsTr
cs, ckpcs, _ = cs.Start(dataf, binlogf)
//if not InitWithLog or InitWithLogNonids,will print to stdout
log.Println(cs)
var e error
var pi, q, p0 int
rsl := len(rs) - 10
cs.CT(MEM|UNIQUE|F64KEY|NOSERIAL, 8192, 3, "I love China", dataf)
cs.CT(MEM|UNIQUE|F64KEY|NOSERIAL, 8192, 3, "Mem | Unique | F64Key | NoSerial", dataf)
cs.CT(MEM|UNIQUE|I64KEY|NOSERIAL, 8192, 3, "Mem | Unique | I64Key | NoSerial", dataf)
cs.CT(MEM|UNIQUE|C128KEY|NOSERIAL, 8192, 3, "Mem | Unique | C128Key | NoSerial", dataf)
cs.CT(MEM|UNIQUE|STRKEY|NOSERIAL, 16384, 3, "Mem | Unique | StrKey | NoSerial", dataf)
cs.CT(MEM|UNIQUE|F64KEY|NOSERIAL|BIG, 8192, 3, "Mem | Unique | F64Key | NoSerial | Big", dataf)
cs.CT(Null|BSKEY|NOSERIAL, 16384, 3, "Null | BsKey | NoSerial", dataf)
cs.CT(MEM|UNIQUE|I64KEY|NOSERIAL|BIG, 8192, 3, "Mem | Unique | I64Key | NoSerial | Big", dataf)
cs.CT(MEM|UNIQUE|C128KEY|NOSERIAL|BIG, 8192, 3, "Mem | Unique | C128Key | NoSerial | Big", dataf)
cs.CT(MEM|UNIQUE|STRKEY|NOSERIAL|BIG, 8192, 3, "Mem | Unique | StrKey | NoSerial | Big", dataf)
cs.CT(MEM|UNIQUE|BSKEY|NOSERIAL|BIG, 8192, 3, "Mem | Unique | 0BsKey | NoSerial | Big", dataf)
cs.CT(MEM|UNIQUE|STRKEY|NOSERIAL|BIG|FILEBIG, 8192, 3, "Mem | Unique | StrKey | NoSerial | Big | FileBig", dataf)
cs.CT(MEM|UNIQUE|STRKEY|NOSERIAL|FILEBIG, 8192, 3, "Mem | Unique | StrKey | NoSerial | FileBig", dataf)
cs.CT(UNIQUE|STRKEY|NOSERIAL|FILEBIG, 8192, 3, "Unique | StrKey | NoSerial | FileBig", dataf)
cs.CT(UNIQUE|STRKEY|NOSERIAL|BIG, 8192, 3, "Unique | StrKey | NoSerial | Big", dataf)
cs.CT(Null|STRKEY|NOSERIAL, 8192, 3, "Null | StrKey | NoSerial", dataf)
cs.CT(UNIQUE|STRKEY|NOSERIAL|COMPRESS, 8192, 3, "Unique | StrKey | NoSerial | Compress", dataf)
wg := new(sync.WaitGroup)
count := 800
wg.Add(5 * count)
for j := 0; j < 5; j++ {
for i := 0; i < count; i++ {
pi = mrand.Intn(rsl)
q = mrand.Intn(rsl)
if pi > q {
pi, q = q, pi
} else if pi == q {
q = pi + 5
}
p0 = pi
if q-pi > 1000 {
pi = q - 1000
}
if q-p0 > 128 {
p0 = q - 128
}
if i < 50 {
p := &putParams{cs, INS, "Mem | Unique | F64Key | NoSerial", mrand.Float64(), []byte(nil), "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 100 {
rspqcopy := make([]byte, len(rs[p0:q]))
copy(rspqcopy, rs[p0:q])
p := &putParams{cs, INS, "Mem | Unique | I64Key | NoSerial", mrand.Int63(), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 150 {
rspqcopy := make([]byte, len(rs[p0:q]))
copy(rspqcopy, rs[p0:q])
p := &putParams{cs, INS, "Mem | Unique | C128Key | NoSerial", complex(mrand.Float64(), mrand.Float64()), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 200 {
rspqcopy := make([]byte, len(rs[p0:q]))
copy(rspqcopy, rs[p0:q])
p := &putParams{cs, INS, "Mem | Unique | StrKey | NoSerial", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 250 {
rspqcopy := make([]byte, len(rs[p0:q]))
copy(rspqcopy, rs[p0:q])
var a []byte
// pass nil directly will be no effect
// but pass a will be effctive
p := &putParams{cs, INS, "Null | BsKey | NoSerial", a, rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 300 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | F64Key | NoSerial | Big", mrand.Float64(), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 350 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | I64Key | NoSerial | Big", mrand.Int63(), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 400 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | C128Key | NoSerial | Big", complex(mrand.Float64(), mrand.Float64()), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 450 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | StrKey | NoSerial | Big", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 500 {
rspqcopy := make([]byte, len(rs[pi:q]))
rsp0qcopy := make([]byte, len(rs[p0:q]))
copy(rspqcopy, rs[pi:q])
copy(rsp0qcopy, rs[p0:q])
p := &putParams{cs, INS, "Mem | Unique | 0BsKey | NoSerial | Big", rsp0qcopy, rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 550 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | StrKey | NoSerial | Big | FileBig", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 600 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Mem | Unique | StrKey | NoSerial | FileBig", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 650 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Unique | StrKey | NoSerial | FileBig", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 700 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Unique | StrKey | NoSerial | Big", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 750 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Null | StrKey | NoSerial", "", rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
} else if i < 800 {
rspqcopy := make([]byte, len(rs[pi:q]))
copy(rspqcopy, rs[pi:q])
p := &putParams{cs, INS, "Unique | StrKey | NoSerial | Compress", string(rs[p0:q]), rspqcopy, "json", dataf, binlogf, logc, cif}
go func(p *putParams) {
_, e = p.cs.Put(p.ops, p.tn, p.key, p.Dts, p.tag, p.f, p.binlogf, p.logc, p.cif, -1)
log.Println(e)
wg.Done()
}(p)
}
}
}
wg.Wait()
cs.End(true, dataf)
cs.Plb(0, dataf, false)
//checkpoint must use EndOnlyPersis
ckpcs.EndOnlyPersis(true, binlogf)
FreeSpire(&cs)
FreeSpire(&ckpcs)
runtime.GC()
// seeing GC recycle memory or not
time.Sleep(10 * time.Second)
}
import (
"gitee.com/lineofsight/resob"
)
type AUU struct {
Ass [3]string `json:"auuuss"`
Afff [3][2][1]float32 `json:"auuufff"`
}
type UUU struct {
Ass [3]string `json:"uuuss"`
Afff [3][2][1]float32 `json:"uuufff"`
Aam map[string]int `json:"uuuam"`
Am map[string]map[int]int `json:"uuum"`
Ac complex128 `json:"uuuc"`
Puu *UU `json:"uu"`
AUU
}
type UU struct {
Abool bool
Ai8 int8
Ai16 int16
Ai32 int32
Ai64 int64
Ai int
Aui8 uint8
Aui16 uint16
Aui32 uint32
Aui64 uint64
Aui uint
As string
Ab [][]byte `json:"b"`
Ass [3]string `json:"ss"`
Afff [3][2][1]float32
Aam map[string]int `json:"am"`
Am map[string]map[int]int `json:"m"`
Ac complex128 `json:"c"`
Auuu UUU `json:"uuu"`
}
func main() {
f, err := os.OpenFile("TestBstrPutGet", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
log.Println("open data file failed:", err)
}
defer f.Close()
m := make(map[string]map[int]int)
mi := make(map[int]int)
mo := make(map[int]int)
m["roytoyi"] = mi
m["poouyyy"] = mo
mi[9] = 100
mo[10] = 1000
ms := make(map[string]int)
ms["dfgdg"] = 100000
uu := UU{
true,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
"sdklfsdk",
[][]byte{{0}, {1}, {1, 2, 3}, {4, 5, 6, 7, 8}},
[3]string{"55566", "3454", "234324"},
[3][2][1]float32{{{11}, {12}}, {{13}, {14}}, {{15}, {16}}},
ms,
m,
23334343 + 45645456i,
UUU{[3]string{"uuu55566", "uuu3454", "uuu234324"},
[3][2][1]float32{{{111}, {112}}, {{113}, {114}}, {{115}, {116}}},
ms,
m,
111123334343 + 45645456i,
nil,
AUU{[3]string{"auuu55566", "auuu3454", "auuu234324"}, [3][2][1]float32{{{111}, {112}}, {{113}, {114}}, {{115}, {116}}}}},
}
var key string
var cs BsTr
cs.InitPool(f)
cs.InitWithLog("世界", "你好")
log.Println("--------------------------------------------Put/Get structure/map etc.")
//k是ID,由IDxy()生成。IDxy()采用类snowflake算法
//param 4 is nil, return a new key by auto
for i := 0; i < 100; i++ {
k, e := cs.PutAnyByKey(uu, "", "json", nil, 1577808000000)
log.Println(k)
log.Println(e)
log.Println(cs)
}
log.Println("-----------------------------------------读取结构体等")
ppcs := new(BsTr)
ppcs.InitWithoutBT()
var e error
k := ""
//if &k==nil,key将自动生成
//此时为空key Put
ppcs.PutAnyByKey(m, "", "json", &k, 1577808000000)
log.Println(ppcs)
mm := make(map[string]map[int]int)
log.Println(ppcs.GetAnyByKey(k, &mm))
log.Println(mm)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(uu.Afff, "", "json", &k, 1577808000000)
log.Println(ppcs)
var ffff [3][2][1]float32
log.Println(ppcs.GetAnyByKey("", &ffff))
log.Println(ffff)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(uu.Ab, "", "json", &k, 1577808000000)
log.Println(ppcs)
var bb [][]byte
log.Println(ppcs.GetAnyByKey("", &bb))
log.Println(bb)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
ppcs.PutAnyByKey(uu, "", "json", &k, 1577808000000)
log.Println(ppcs)
log.Println(ppcs.Save(0, f))
tppcs, _, e := GetFromFileOff(ppcs.Offset(), f)
log.Println(tppcs)
log.Println(e)
log.Println(reflect.DeepEqual(tppcs, ppcs))
var gcsuu, gcsuu4 UU
log.Println(ppcs.GetAnyByKey("", &gcsuu))
log.Println(tppcs.GetAnyByKey("", &gcsuu4))
log.Println(reflect.DeepEqual(gcsuu, gcsuu4))
//struct field name
//key is ""
b, _ := ppcs.GetBool("Abool")
log.Println(*b)
log.Println("uu", uu)
log.Println("gcsuu", gcsuu)
log.Println(reflect.DeepEqual(gcsuu, uu))
//use sort carefully
sort.Sort(ppcs)
log.Println(ppcs)
log.Println(ppcs.GetAnyByKey(key, &gcsuu4))
log.Println("uu", uu)
log.Println("gcsuu4", gcsuu4)
log.Println(reflect.DeepEqual(gcsuu4, uu))
log.Println("--------------------key非空------------------")
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(m, "", "json", nil, 1577808000000)
log.Println(ppcs)
mm = make(map[string]map[int]int)
log.Println(ppcs.GetAnyByKey(key, &mm))
log.Println(mm)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(uu.Afff, "", "json", nil, 1577808000000)
log.Println(ppcs)
log.Println(ppcs.GetAnyByKey(key, &ffff))
log.Println(ffff)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(uu.Ab, "", "json", nil, 1577808000000)
log.Println(ppcs)
log.Println(ppcs.GetAnyByKey(key, &bb))
log.Println(bb)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
key, _ = ppcs.PutAnyByKey(uu, "", "json", nil, 1577808000000)
log.Println(ppcs)
var gcsuu3, gcsuu1, gcsuu2 UU
log.Println(ppcs.GetAnyByKey(key, &gcsuu3))
b, _ = ppcs.GetBool("Abool:" + key)
log.Println(*b)
log.Println("uu", uu)
log.Println("gcsuu", gcsuu3)
log.Println(reflect.DeepEqual(gcsuu3, uu))
key1, _ := ppcs.PutAnyByKey(uu, "", "json", nil, 1577808000000)
log.Println(ppcs)
log.Println(ppcs.GetAnyByKey(key1, &gcsuu2))
log.Println(ppcs.GetAnyByKey(key, &gcsuu1))
log.Println("gcsuu21", gcsuu1)
log.Println("gcsuu2", gcsuu2)
log.Println(reflect.DeepEqual(gcsuu2, gcsuu1))
log.Println(reflect.DeepEqual(uu, gcsuu1))
log.Println("-----------------------------------------加入指针Put/Get")
gcsuu.Auuu.Puu = &uu
log.Println("gcsuu.Auuu.Puu", gcsuu.Auuu.Puu)
ppcs = new(BsTr)
ppcs.InitWithoutBT()
k, e = ppcs.PutAnyByKey(gcsuu, "", "json", &key, 1577808000000)
log.Println(key, ":", k)
log.Println(e)
log.Println(ppcs)
var pgcsuu UU
e = ppcs.GetAnyByKey(k, &pgcsuu)
log.Println(e)
log.Println(pgcsuu)
b, _ = ppcs.GetBool("Abool:" + k)
log.Println(*b)
log.Println(gcsuu)
log.Println(gcsuu.Auuu.Puu)
//not support ptr
log.Println(reflect.DeepEqual(pgcsuu, gcsuu))
log.Println(pgcsuu.Auuu.Puu)
log.Println("-----------------------------------------Delete/Rollback")
ppcs = new(BsTr)
ppcs.InitWithoutBT()
var r [MAXSNADD1 + 1]int
ppcs.PutBool(true, "0", "1", "2")
r[BOOLSN] += 1
ppcs.PutInt8(1, "3", "4", "5")
ppcs.PutInt16(2, "6", "7", "8")
ppcs.PutInt32(1, "63", "4", "5")
ppcs.PutInt64(2, "66", "7", "8")
ppcs.PutUint8(1, "73", "4", "5")
ppcs.PutUint16(2, "76", "7", "8")
ppcs.PutUint32(1, "83", "4", "5")
ppcs.PutUint64(2, "86", "7", "8")
ppcs.PutFloat32(1, "93", "4", "5")
ppcs.PutFloat64(2, "96", "7", "8")
ppcs.PutComplex64(1, "103", "4", "5")
r[COMPLEX64SN] += 1
ppcs.PutComplex128(2, "106", "7", "8")
ppcs.PutString("1", "3", "104", "5")
ppcs.PutBytes([]byte("1"), "116", "7", "8")
ppcs.PutBsk([]byte("1"), "", "", "")
r[BYTEKEYSN] += 1
ppcs.PutChunk(ppcs)
r[MAXSNADD1] += 1
ppcs.PutOff(1)
ppcs.PutTm(2)
log.Println(ppcs)
log.Println(ppcs.Rollback(r, 0))
log.Println(ppcs)
ppcs.PutBool(true, "000", "1", "2")
ppcs.PutInt8(1, "003", "4", "5")
ppcs.PutInt16(2, "006", "7", "8")
r[INT16SN] += 1
ppcs.PutInt32(1, "003", "4", "5")
ppcs.PutInt64(2, "600", "7", "8")
ppcs.PutUint8(1, "300", "4", "5")
ppcs.PutUint16(2, "116", "7", "8")
ppcs.PutUint32(1, "113", "4", "5")
ppcs.PutUint64(2, "611", "7", "8")
ppcs.PutFloat32(1, "311", "4", "5")
ppcs.PutFloat64(2, "622", "7", "8")
ppcs.PutComplex64(1, "302", "4", "5")
ppcs.PutComplex128(2, "633", "7", "8")
ppcs.PutString("1", "333", "4", "5")
r[STRINGSN] += 1
ppcs.PutBytes([]byte("144"), "6", "7", "8")
r[BYTESN] += 1
ppcs.PutBsk([]byte("104"), "", "", "")
ppcs.PutChunk(ppcs)
r[MAXSNADD1] += 1
ppcs.PutOff(1)
r[OFFSSN] += 1
ppcs.PutTm(2)
log.Println(ppcs)
log.Println(ppcs.Rollback(r, 2))
log.Println(ppcs)
ppcs.PutString("11", "3331", "4", "5")
ppcs.PutString("12", "3332", "4", "5")
ppcs.PutString("13", "3333", "4", "5")
ppcs.PutString("14", "3334", "4", "5")
ppcs.PutString("15", "3335", "4", "5")
ppcs.PutString("16", "3336", "4", "5")
ppcs.PutString("17", "3337", "4", "5")
ppcs.PutString("18", "3338", "4", "5")
ppcs.PutString("19", "3339", "4", "5")
log.Println(ppcs)
log.Println(ppcs.Delete(STRINGSN, 3, 3))
log.Println(ppcs)
ppcs.PutBool(true, "00000", "1", "2")
ppcs.PutInt8(1, "00003", "4", "5")
ppcs.PutInt16(2, "00006", "7", "8")
ppcs.PutInt32(1, "00003", "4", "5")
ppcs.PutInt64(2, "60000", "7", "8")
ppcs.PutUint8(1, "30000", "4", "5")
ppcs.PutUint16(2, "10016", "7", "8")
ppcs.PutUint32(1, "10013", "4", "5")
ppcs.PutUint64(2, "60011", "7", "8")
ppcs.PutFloat32(1, "30011", "4", "5")
ppcs.PutFloat64(2, "60022", "7", "8")
ppcs.PutComplex64(1, "30002", "4", "5")
ppcs.PutComplex128(2, "60033", "7", "8")
ppcs.PutString("1", "30033", "4", "5")
ppcs.PutBytes([]byte("10044"), "6", "7", "8")
ppcs.PutBsk([]byte("10004"), "", "", "")
ppcs.PutChunk(ppcs)
ppcs.PutOff(1)
ppcs.PutTm(2)
ppcs.PutBool(true, "100000", "1", "2")
ppcs.PutInt8(1, "100003", "4", "5")
ppcs.PutInt16(2, "100006", "7", "8")
ppcs.PutInt32(1, "100003", "4", "5")
ppcs.PutInt64(2, "160000", "7", "8")
ppcs.PutUint8(1, "130000", "4", "5")
ppcs.PutUint16(2, "110016", "7", "8")
ppcs.PutUint32(1, "110013", "4", "5")
ppcs.PutUint64(2, "160011", "7", "8")
ppcs.PutFloat32(1, "130011", "4", "5")
ppcs.PutFloat64(2, "160022", "7", "8")
ppcs.PutComplex64(1, "130002", "4", "5")
ppcs.PutComplex128(2, "160033", "7", "8")
ppcs.PutString("1", "130033", "4", "5")
ppcs.PutBytes([]byte("110044"), "6", "7", "8")
ppcs.PutBsk([]byte("110004"), "", "", "")
ppcs.PutChunk(ppcs)
ppcs.PutOff(1)
ppcs.PutTm(2)
for i := 0; i < MAXSNADD1+1; i++ {
r[i] = 2
}
log.Println(ppcs)
log.Println(ppcs.Rollback(r, 1))
log.Println(ppcs)
}