func TestPcacherMultiSimple(t *testing.T) { pc := pcacher.Create("/tmp/pcacher_multisimple_test.db", pcacher.PAGE_SIZE*50) var noPages uint32 wg := sync.WaitGroup{} noWorkers := 200 wg.Add(noWorkers) worker := func(id int) { for i := 0; i < 80; i++ { op := rand.Int() % 20 if op == 0 { // New Page data := utils.RandBytes(pcacher.PAGE_SIZE) pgno := pc.NewPage(data) pg, err := pc.GetPage(pgno) if err != nil { if err == cacher.ErrCacheFull { continue } utils.Fatal(err) } atomic.AddUint32(&noPages, 1) pg.Release() } else if op < 20 { // Read mod := atomic.LoadUint32(&noPages) if mod == 0 { continue } pgno := pcacher.Pgno((rand.Uint32() % mod) + 1) pg, err := pc.GetPage(pgno) if err != nil { if err == cacher.ErrCacheFull { continue } utils.Fatal(err) } pg.Release() } } wg.Done() } for i := 0; i < noWorkers; i++ { go worker(i) } wg.Wait() }
func TestPcacherMulti(t *testing.T) { pc := pcacher.Create("/tmp/pcacher_multi_test.db", pcacher.PAGE_SIZE*10) mpc := pcacher.NewMock() lockNew := sync.Mutex{} var noPages uint32 wg := sync.WaitGroup{} noWorkers := 30 wg.Add(noWorkers) worker := func(id int) { for i := 0; i < 1000; i++ { op := rand.Int() % 20 if op == 0 { // New Page data := utils.RandBytes(pcacher.PAGE_SIZE) lockNew.Lock() // 为了让pc和mpc同步更新, 多个线程同时new, 页号可能会出错. pc.NewPage(data) mpc.NewPage(data) lockNew.Unlock() atomic.AddUint32(&noPages, 1) } else if op < 10 { // Check mod := atomic.LoadUint32(&noPages) if mod == 0 { continue } pgno := pcacher.Pgno((rand.Uint32() % mod) + 1) pg, err := pc.GetPage(pgno) if err != nil { if err == cacher.ErrCacheFull { continue } utils.Fatal(err) } mpg, _ := mpc.GetPage(pgno) pg.Lock() if bytes.Compare(mpg.Data(), pg.Data()) != 0 { utils.Fatal("error") } pg.Unlock() pg.Release() } else { // Update mod := atomic.LoadUint32(&noPages) if mod == 0 { continue } pgno := pcacher.Pgno((rand.Uint32() % mod) + 1) pg, err := pc.GetPage(pgno) if err != nil { if err == cacher.ErrCacheFull { continue } utils.Fatal(err) } mpg, _ := mpc.GetPage(pgno) newData := utils.RandBytes(pcacher.PAGE_SIZE) pg.Lock() mpg.Dirty() copy(mpg.Data(), newData) pg.Dirty() copy(pg.Data(), newData) pg.Unlock() pg.Release() } } wg.Done() } for i := 0; i < noWorkers; i++ { go worker(i) } wg.Wait() }
func genSQL(i int) string { sql := "insert into student values " + string(utils.RandBytes(50)) + " " + strconv.Itoa(i) + " " + utils.Int32ToStr(int32(rand.Uint32()%1000000000)) + " " return sql }