| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package core
- // 显式主键查重短路的回归测试。
- //
- // 背景 (bench_ts profile): InsertRowWithID 对显式 pkID 逐行回表查重, 时序行存储
- // 按 pkID 取行是 O(段数+页内行扫), 顺序写入时占写入 CPU 36%。修复: pkID 大于等于
- // "历史发号上界" (nextPK, 只增不减) 时必然不存在, 跳过查重。这里钉住两件事:
- // 1. 短路生效 (大于上界的号免查, 写入提速);
- // 2. 短路不误伤 —— 已存在的号 (无论 < 还是触达过上界后又被显式复用) 仍报重复。
- import (
- "errors"
- "testing"
- "git.ycl.pub/yl32940/TsDB2/DB/core/page"
- "git.ycl.pub/yl32940/TsDB2/DB/core/types"
- )
- func dupCheckTable(t *testing.T, db *DB, name string) *Table {
- t.Helper()
- tbl, err := db.CreateTable(name, []types.FieldInfo{
- {FieldType: types.FieldType_Uint64, FieldName: []byte("id")},
- {FieldType: types.FieldType_Uint64, FieldName: []byte("v")},
- })
- if err != nil {
- t.Fatalf("建表: %v", err)
- }
- if _, err := tbl.CreateIndex("pk", page.IndexTypePrimary, []byte{0}); err != nil {
- t.Fatalf("建索引: %v", err)
- }
- return tbl
- }
- func TestExplicitPKDuplicateStillDetected(t *testing.T) {
- db := fixOpenDB(t)
- tbl := dupCheckTable(t, db, "t")
- // 顺序显式写入 1..100 (全部命中短路, 但不能因此漏检后面的重复)
- for i := uint64(1); i <= 100; i++ {
- if _, err := tbl.InsertRowWithID(i, []types.FieldValue{
- {FieldName: []byte("id"), Value: i},
- {FieldName: []byte("v"), Value: i},
- }); err != nil {
- t.Fatalf("insert %d: %v", i, err)
- }
- }
- if err := db.Commit(); err != nil {
- t.Fatalf("commit: %v", err)
- }
- // 已存在的号 (< nextPK) 仍必须报重复
- for _, id := range []uint64{1, 50, 100} {
- if _, err := tbl.InsertRowWithID(id, []types.FieldValue{
- {FieldName: []byte("id"), Value: id},
- {FieldName: []byte("v"), Value: id},
- }); !errors.Is(err, ErrDuplicatePK) {
- t.Fatalf("重复插入 id=%d 必须报 ErrDuplicatePK, 实际: %v", id, err)
- }
- }
- // 从未发放过的号 (>= nextPK) 正常写入; 二次插入同一号 (此时已 < nextPK) 报重复
- if _, err := tbl.InsertRowWithID(101, []types.FieldValue{
- {FieldName: []byte("id"), Value: uint64(101)},
- {FieldName: []byte("v"), Value: uint64(101)},
- }); err != nil {
- t.Fatalf("insert 101: %v", err)
- }
- if _, err := tbl.InsertRowWithID(101, []types.FieldValue{
- {FieldName: []byte("id"), Value: uint64(101)},
- {FieldName: []byte("v"), Value: uint64(101)},
- }); !errors.Is(err, ErrDuplicatePK) {
- t.Fatalf("第二次插入 id=101 必须报 ErrDuplicatePK, 实际: %v", err)
- }
- // 批量路径同规则: 批内显式重复 + 与既有行撞车都要拦住
- if _, err := tbl.InsertRowsWithIDs([]uint64{200, 200}, [][]types.FieldValue{
- {{FieldName: []byte("id"), Value: uint64(200)}, {FieldName: []byte("v"), Value: uint64(200)}},
- {{FieldName: []byte("id"), Value: uint64(200)}, {FieldName: []byte("v"), Value: uint64(200)}},
- }); !errors.Is(err, ErrDuplicatePK) {
- t.Fatalf("批内重复必须报 ErrDuplicatePK, 实际: %v", err)
- }
- if _, err := tbl.InsertRowsWithIDs([]uint64{50}, [][]types.FieldValue{
- {{FieldName: []byte("id"), Value: uint64(50)}, {FieldName: []byte("v"), Value: uint64(50)}},
- }); !errors.Is(err, ErrDuplicatePK) {
- t.Fatalf("批量撞既有行必须报 ErrDuplicatePK, 实际: %v", err)
- }
- }
|