Files
hotime/example/batch_cache_tester.go
T

323 lines
9.3 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"time"
"code.hoteas.com/golang/hotime"
"code.hoteas.com/golang/hotime/cache"
. "code.hoteas.com/golang/hotime/common"
)
// TestBatchCacheOperations 测试所有批量缓存操作
func TestBatchCacheOperations(app *hotime.Application) {
fmt.Println("\n========== 批量缓存操作测试开始 ==========")
// 测试1: 测试 CacheMemory 批量操作
fmt.Println("\n--- 测试1: CacheMemory 批量操作 ---")
testCacheMemoryBatch(app)
// 测试2: 测试 CacheDb 批量操作
fmt.Println("\n--- 测试2: CacheDb 批量操作 ---")
testCacheDbBatch(app)
// 测试3: 测试 HoTimeCache 三级缓存批量操作
fmt.Println("\n--- 测试3: HoTimeCache 三级缓存批量操作 ---")
testHoTimeCacheBatch(app)
// 测试4: 测试 SessionIns 批量操作
fmt.Println("\n--- 测试4: SessionIns 批量操作 ---")
testSessionInsBatch(app)
// 测试5: 测试缓存反哺机制
fmt.Println("\n--- 测试5: 缓存反哺机制测试 ---")
testCacheBackfill(app)
// 测试6: 测试批量操作效率(一次性写入验证)
fmt.Println("\n--- 测试6: 批量操作效率测试 ---")
testBatchEfficiency(app)
fmt.Println("\n========== 批量缓存操作测试完成 ==========")
}
// testCacheMemoryBatch 测试内存缓存批量操作
func testCacheMemoryBatch(app *hotime.Application) {
memCache := &cache.CacheMemory{TimeOut: 3600, DbSet: true, SessionSet: true}
// 测试 CachesSet
testData := Map{
"mem_key1": "value1",
"mem_key2": "value2",
"mem_key3": "value3",
}
memCache.CachesSet(testData)
// 测试 CachesGet
keys := []string{"mem_key1", "mem_key2", "mem_key3", "mem_key_not_exist"}
result := memCache.CachesGet(keys)
if len(result) != 3 {
fmt.Printf(" [FAIL] CacheMemory.CachesGet: 期望3个结果,实际%d个\n", len(result))
} else {
fmt.Println(" [PASS] CacheMemory.CachesGet: 批量获取正确")
}
// 测试 CachesDelete
memCache.CachesDelete([]string{"mem_key1", "mem_key2"})
result2 := memCache.CachesGet(keys)
if len(result2) != 1 || result2["mem_key3"] == nil {
fmt.Printf(" [FAIL] CacheMemory.CachesDelete: 删除后期望1个结果,实际%d个\n", len(result2))
} else {
fmt.Println(" [PASS] CacheMemory.CachesDelete: 批量删除正确")
}
}
// testCacheDbBatch 测试数据库缓存批量操作
func testCacheDbBatch(app *hotime.Application) {
// 使用应用的数据库连接
dbCache := &cache.CacheDb{
TimeOut: 3600,
DbSet: true,
SessionSet: true,
Mode: cache.CacheModeNew,
Db: &app.Db,
}
// 清理测试数据
dbCache.CachesDelete([]string{"db_batch_key1", "db_batch_key2", "db_batch_key3"})
// 测试 CachesSet
testData := Map{
"db_batch_key1": "db_value1",
"db_batch_key2": "db_value2",
"db_batch_key3": "db_value3",
}
dbCache.CachesSet(testData)
// 测试 CachesGet
keys := []string{"db_batch_key1", "db_batch_key2", "db_batch_key3", "db_not_exist"}
result := dbCache.CachesGet(keys)
if len(result) != 3 {
fmt.Printf(" [FAIL] CacheDb.CachesGet: 期望3个结果,实际%d个\n", len(result))
} else {
fmt.Println(" [PASS] CacheDb.CachesGet: 批量获取正确")
}
// 验证值正确性
if result["db_batch_key1"] != "db_value1" {
fmt.Printf(" [FAIL] CacheDb.CachesGet: db_batch_key1 值不正确,期望 db_value1,实际 %v\n", result["db_batch_key1"])
} else {
fmt.Println(" [PASS] CacheDb.CachesGet: 值内容正确")
}
// 测试 CachesDelete
dbCache.CachesDelete([]string{"db_batch_key1", "db_batch_key2"})
result2 := dbCache.CachesGet(keys)
if len(result2) != 1 {
fmt.Printf(" [FAIL] CacheDb.CachesDelete: 删除后期望1个结果,实际%d个\n", len(result2))
} else {
fmt.Println(" [PASS] CacheDb.CachesDelete: 批量删除正确")
}
// 清理
dbCache.CachesDelete([]string{"db_batch_key3"})
}
// testHoTimeCacheBatch 测试 HoTimeCache 三级缓存批量操作
func testHoTimeCacheBatch(app *hotime.Application) {
htCache := app.HoTimeCache
// 清理测试数据
htCache.SessionsDelete([]string{
hotime.HEAD_SESSION_ADD + "ht_batch_key1",
hotime.HEAD_SESSION_ADD + "ht_batch_key2",
hotime.HEAD_SESSION_ADD + "ht_batch_key3",
})
// 测试 SessionsSet
testData := Map{
hotime.HEAD_SESSION_ADD + "ht_batch_key1": Map{"user": "test1", "role": "admin"},
hotime.HEAD_SESSION_ADD + "ht_batch_key2": Map{"user": "test2", "role": "user"},
hotime.HEAD_SESSION_ADD + "ht_batch_key3": Map{"user": "test3", "role": "guest"},
}
htCache.SessionsSet(testData)
// 测试 SessionsGet
keys := []string{
hotime.HEAD_SESSION_ADD + "ht_batch_key1",
hotime.HEAD_SESSION_ADD + "ht_batch_key2",
hotime.HEAD_SESSION_ADD + "ht_batch_key3",
hotime.HEAD_SESSION_ADD + "ht_not_exist",
}
result := htCache.SessionsGet(keys)
if len(result) != 3 {
fmt.Printf(" [FAIL] HoTimeCache.SessionsGet: 期望3个结果,实际%d个\n", len(result))
} else {
fmt.Println(" [PASS] HoTimeCache.SessionsGet: 批量获取正确")
}
// 测试 SessionsDelete
htCache.SessionsDelete([]string{
hotime.HEAD_SESSION_ADD + "ht_batch_key1",
hotime.HEAD_SESSION_ADD + "ht_batch_key2",
})
result2 := htCache.SessionsGet(keys)
if len(result2) != 1 {
fmt.Printf(" [FAIL] HoTimeCache.SessionsDelete: 删除后期望1个结果,实际%d个\n", len(result2))
} else {
fmt.Println(" [PASS] HoTimeCache.SessionsDelete: 批量删除正确")
}
// 清理
htCache.SessionsDelete([]string{hotime.HEAD_SESSION_ADD + "ht_batch_key3"})
}
// testSessionInsBatch 测试 SessionIns 批量操作
func testSessionInsBatch(app *hotime.Application) {
// 创建一个模拟的 SessionIns
session := &hotime.SessionIns{
SessionId: "test_batch_session_" + ObjToStr(time.Now().UnixNano()),
}
session.Init(app.HoTimeCache)
// 测试 SessionsSet
testData := Map{
"field1": "value1",
"field2": 123,
"field3": Map{"nested": "data"},
}
session.SessionsSet(testData)
// 测试 SessionsGet
result := session.SessionsGet("field1", "field2", "field3", "not_exist")
if len(result) != 3 {
fmt.Printf(" [FAIL] SessionIns.SessionsGet: 期望3个结果,实际%d个\n", len(result))
} else {
fmt.Println(" [PASS] SessionIns.SessionsGet: 批量获取正确")
}
// 验证值类型
if result["field1"] != "value1" {
fmt.Printf(" [FAIL] SessionIns.SessionsGet: field1 值不正确\n")
} else {
fmt.Println(" [PASS] SessionIns.SessionsGet: 字符串值正确")
}
var convErr Error
if ObjToInt(result["field2"], &convErr) != 123 {
fmt.Printf(" [FAIL] SessionIns.SessionsGet: field2 值不正确\n")
} else {
fmt.Println(" [PASS] SessionIns.SessionsGet: 数值类型正确")
}
// 测试 SessionsDelete
session.SessionsDelete("field1", "field2")
result2 := session.SessionsGet("field1", "field2", "field3")
if len(result2) != 1 {
fmt.Printf(" [FAIL] SessionIns.SessionsDelete: 删除后期望1个结果,实际%d个\n", len(result2))
} else {
fmt.Println(" [PASS] SessionIns.SessionsDelete: 批量删除正确")
}
}
// testCacheBackfill 测试缓存反哺机制
func testCacheBackfill(app *hotime.Application) {
htCache := app.HoTimeCache
// 直接写入数据库缓存(绕过 memory)模拟只有 db 有数据的情况
dbCache := &cache.CacheDb{
TimeOut: 3600,
DbSet: true,
SessionSet: true,
Mode: cache.CacheModeNew,
Db: &app.Db,
}
testKey := "backfill_test_key_" + ObjToStr(time.Now().UnixNano())
testValue := Map{"backfill": "test_data"}
// 直接写入 db
dbCache.Cache(testKey, testValue)
// 通过 HoTimeCache 批量获取,应该触发反哺到 memory
keys := []string{testKey}
result := htCache.CachesGet(keys)
if len(result) != 1 || result[testKey] == nil {
fmt.Println(" [FAIL] 缓存反哺: 从 DB 读取失败")
} else {
fmt.Println(" [PASS] 缓存反哺: 从 DB 读取成功")
}
// 清理
htCache.CachesDelete(keys)
}
// testBatchEfficiency 测试批量操作效率
func testBatchEfficiency(app *hotime.Application) {
session := &hotime.SessionIns{
SessionId: "efficiency_test_" + ObjToStr(time.Now().UnixNano()),
}
session.Init(app.HoTimeCache)
// 记录批量设置开始时间
startTime := time.Now()
// 设置10个字段
testData := Map{}
for i := 0; i < 10; i++ {
testData[fmt.Sprintf("eff_field_%d", i)] = fmt.Sprintf("value_%d", i)
}
session.SessionsSet(testData)
batchDuration := time.Since(startTime)
// 对比单个设置
session2 := &hotime.SessionIns{
SessionId: "efficiency_test_single_" + ObjToStr(time.Now().UnixNano()),
}
session2.Init(app.HoTimeCache)
startTime2 := time.Now()
for i := 0; i < 10; i++ {
session2.Session(fmt.Sprintf("single_field_%d", i), fmt.Sprintf("value_%d", i))
}
singleDuration := time.Since(startTime2)
fmt.Printf(" 批量设置10个字段耗时: %v\n", batchDuration)
fmt.Printf(" 单个设置10个字段耗时: %v\n", singleDuration)
if batchDuration < singleDuration {
fmt.Println(" [PASS] 批量操作效率: 批量操作更快")
} else {
fmt.Println(" [WARN] 批量操作效率: 批量操作未体现优势(可能数据量太小)")
}
// 批量获取测试
startTime3 := time.Now()
keys := make([]string, 10)
for i := 0; i < 10; i++ {
keys[i] = fmt.Sprintf("eff_field_%d", i)
}
session.SessionsGet(keys...)
batchGetDuration := time.Since(startTime3)
fmt.Printf(" 批量获取10个字段耗时: %v\n", batchGetDuration)
}
// getMapKeys 获取 Map 的所有键
func getMapKeys(m Map) []string {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}