777 lines
21 KiB
Go
777 lines
21 KiB
Go
package housing
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"math/rand"
|
|
"testing"
|
|
"time"
|
|
|
|
"zombiezen.com/go/sqlite/sqlitex"
|
|
)
|
|
|
|
// setupBenchmarkDB creates a test database with sample data for benchmarking
|
|
func setupBenchmarkDB(b *testing.B) (*DatabaseHousingManager, context.Context) {
|
|
// Create truly unique database name to avoid cross-benchmark contamination
|
|
dbName := fmt.Sprintf("file:bench_%s_%d.db?mode=memory&cache=shared", b.Name(), rand.Int63())
|
|
pool, err := sqlitex.NewPool(dbName, sqlitex.PoolOptions{})
|
|
if err != nil {
|
|
b.Fatalf("Failed to create benchmark database pool: %v", err)
|
|
}
|
|
|
|
dhm := NewDatabaseHousingManager(pool)
|
|
ctx := context.Background()
|
|
|
|
if err := dhm.EnsureHousingTables(ctx); err != nil {
|
|
b.Fatalf("Failed to create benchmark tables: %v", err)
|
|
}
|
|
|
|
return dhm, ctx
|
|
}
|
|
|
|
// insertBenchmarkData inserts a large dataset for benchmarking
|
|
func insertBenchmarkData(b *testing.B, dhm *DatabaseHousingManager, ctx context.Context, houseZones, playerHouses int) {
|
|
// Insert house zones
|
|
for i := 1; i <= houseZones; i++ {
|
|
zone := &HouseZone{
|
|
ID: int32(i),
|
|
Name: fmt.Sprintf("House Type %d", i),
|
|
ZoneID: int32(100 + i),
|
|
CostCoin: int64(50000 + i*10000),
|
|
CostStatus: int64(1000 + i*100),
|
|
UpkeepCoin: int64(5000 + i*1000),
|
|
UpkeepStatus: int64(100 + i*10),
|
|
Alignment: int8(i % 3 - 1), // -1, 0, 1
|
|
GuildLevel: int8(i % 50),
|
|
VaultSlots: int(4 + i%4),
|
|
MaxItems: int(100 + i*50),
|
|
MaxVisitors: int(10 + i*5),
|
|
UpkeepPeriod: 604800, // 1 week
|
|
Description: fmt.Sprintf("Benchmark house type %d description", i),
|
|
}
|
|
|
|
if err := dhm.SaveHouseZone(ctx, zone); err != nil {
|
|
b.Fatalf("Failed to insert benchmark house zone: %v", err)
|
|
}
|
|
}
|
|
|
|
// Insert player houses
|
|
for i := 1; i <= playerHouses; i++ {
|
|
houseData := PlayerHouseData{
|
|
CharacterID: int32(1000 + i),
|
|
HouseID: int32((i % houseZones) + 1),
|
|
InstanceID: int32(5000 + i),
|
|
UpkeepDue: time.Now().Add(time.Duration(i%168) * time.Hour), // Random within a week
|
|
EscrowCoins: int64(10000 + i*1000),
|
|
EscrowStatus: int64(200 + i*20),
|
|
Status: HouseStatusActive,
|
|
HouseName: fmt.Sprintf("House %d", i),
|
|
VisitPermission: int8(i % 3),
|
|
PublicNote: fmt.Sprintf("Welcome to house %d!", i),
|
|
PrivateNote: fmt.Sprintf("Private note %d", i),
|
|
AllowFriends: i%2 == 0,
|
|
AllowGuild: i%3 == 0,
|
|
RequireApproval: i%4 == 0,
|
|
ShowOnDirectory: i%5 != 0,
|
|
AllowDecoration: i%6 != 0,
|
|
TaxExempt: i%10 == 0,
|
|
}
|
|
|
|
_, err := dhm.AddPlayerHouse(ctx, houseData)
|
|
if err != nil {
|
|
b.Fatalf("Failed to insert benchmark player house: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// insertHouseRelatedData inserts deposits, history, access, etc. for benchmarking
|
|
func insertHouseRelatedData(b *testing.B, dhm *DatabaseHousingManager, ctx context.Context, houseID int64, entries int) {
|
|
// Insert deposits
|
|
for i := 1; i <= entries; i++ {
|
|
deposit := HouseDeposit{
|
|
Timestamp: time.Now().Add(-time.Duration(i) * time.Hour),
|
|
Amount: int64(1000 + i*100),
|
|
LastAmount: int64(2000 + i*100),
|
|
Status: int64(50 + i*5),
|
|
LastStatus: int64(100 + i*5),
|
|
Name: fmt.Sprintf("Player %d", i%10+1),
|
|
CharacterID: int32(2000 + i%10),
|
|
}
|
|
|
|
if err := dhm.SaveDeposit(ctx, houseID, deposit); err != nil {
|
|
b.Fatalf("Failed to insert benchmark deposit: %v", err)
|
|
}
|
|
}
|
|
|
|
// Insert history
|
|
for i := 1; i <= entries; i++ {
|
|
history := HouseHistory{
|
|
Timestamp: time.Now().Add(-time.Duration(i*2) * time.Hour),
|
|
Amount: int64(500 + i*50),
|
|
Status: int64(25 + i*2),
|
|
Reason: fmt.Sprintf("Transaction %d", i),
|
|
Name: fmt.Sprintf("Player %d", i%10+1),
|
|
CharacterID: int32(2000 + i%10),
|
|
PosFlag: int8(i % 2),
|
|
Type: int(i % 5),
|
|
}
|
|
|
|
if err := dhm.AddHistory(ctx, houseID, history); err != nil {
|
|
b.Fatalf("Failed to insert benchmark history: %v", err)
|
|
}
|
|
}
|
|
|
|
// Insert access entries
|
|
accessList := make([]HouseAccess, 0, entries/10) // Fewer access entries
|
|
for i := 1; i <= entries/10; i++ {
|
|
access := HouseAccess{
|
|
CharacterID: int32(3000 + i),
|
|
PlayerName: fmt.Sprintf("AccessPlayer%d", i),
|
|
AccessLevel: int8(i % 3),
|
|
Permissions: int32(i % 16), // 0-15
|
|
GrantedBy: int32(1001),
|
|
GrantedDate: time.Now().Add(-time.Duration(i*24) * time.Hour),
|
|
ExpiresDate: time.Now().Add(time.Duration(30-i) * 24 * time.Hour),
|
|
Notes: fmt.Sprintf("Access notes for player %d", i),
|
|
}
|
|
accessList = append(accessList, access)
|
|
}
|
|
|
|
if len(accessList) > 0 {
|
|
if err := dhm.SaveHouseAccess(ctx, houseID, accessList); err != nil {
|
|
b.Fatalf("Failed to insert benchmark access: %v", err)
|
|
}
|
|
}
|
|
|
|
// Insert amenities
|
|
for i := 1; i <= entries/5; i++ {
|
|
amenity := HouseAmenity{
|
|
ID: int32(i),
|
|
Type: int(i % 10),
|
|
Name: fmt.Sprintf("Amenity %d", i),
|
|
Cost: int64(1000 + i*500),
|
|
StatusCost: int64(20 + i*10),
|
|
PurchaseDate: time.Now().Add(-time.Duration(i*12) * time.Hour),
|
|
X: float32(100 + i*10),
|
|
Y: float32(200 + i*15),
|
|
Z: float32(50 + i*5),
|
|
Heading: float32(i % 360),
|
|
IsActive: i%2 == 0,
|
|
}
|
|
|
|
if err := dhm.SaveHouseAmenity(ctx, houseID, amenity); err != nil {
|
|
b.Fatalf("Failed to insert benchmark amenity: %v", err)
|
|
}
|
|
}
|
|
|
|
// Insert items
|
|
for i := 1; i <= entries/3; i++ {
|
|
item := HouseItem{
|
|
ID: int64(i),
|
|
ItemID: int32(10000 + i),
|
|
CharacterID: int32(1001),
|
|
X: float32(150 + i*5),
|
|
Y: float32(250 + i*7),
|
|
Z: float32(75 + i*3),
|
|
Heading: float32(i % 360),
|
|
PitchX: float32(i % 10),
|
|
PitchY: float32(i % 5),
|
|
RollX: float32(i % 15),
|
|
RollY: float32(i % 8),
|
|
PlacedDate: time.Now().Add(-time.Duration(i*6) * time.Hour),
|
|
Quantity: int32(1 + i%5),
|
|
Condition: int8(100 - i%100),
|
|
House: fmt.Sprintf("room_%d", i%5),
|
|
}
|
|
|
|
if err := dhm.SaveHouseItem(ctx, houseID, item); err != nil {
|
|
b.Fatalf("Failed to insert benchmark item: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHouseZones benchmarks loading all house zones
|
|
func BenchmarkLoadHouseZones(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 100, 0) // 100 house zones, no player houses
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
zones, err := dhm.LoadHouseZones(ctx)
|
|
if err != nil {
|
|
b.Fatalf("LoadHouseZones failed: %v", err)
|
|
}
|
|
if len(zones) != 100 {
|
|
b.Errorf("Expected 100 zones, got %d", len(zones))
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHouseZone benchmarks loading a single house zone
|
|
func BenchmarkLoadHouseZone(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 100, 0)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
zone, err := dhm.LoadHouseZone(ctx, int32((i%100)+1))
|
|
if err != nil {
|
|
b.Fatalf("LoadHouseZone failed: %v", err)
|
|
}
|
|
if zone == nil {
|
|
b.Error("LoadHouseZone returned nil zone")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkSaveHouseZone benchmarks saving a house zone
|
|
func BenchmarkSaveHouseZone(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
zone := &HouseZone{
|
|
ID: int32(1000 + i),
|
|
Name: fmt.Sprintf("Benchmark House %d", i),
|
|
ZoneID: int32(2000 + i),
|
|
CostCoin: int64(50000 + i*1000),
|
|
CostStatus: int64(1000 + i*10),
|
|
UpkeepCoin: int64(5000 + i*100),
|
|
UpkeepStatus: int64(100 + i),
|
|
Alignment: int8(i % 3 - 1),
|
|
GuildLevel: int8(i % 50),
|
|
VaultSlots: int(4 + i%4),
|
|
MaxItems: int(100 + i*10),
|
|
MaxVisitors: int(10 + i),
|
|
UpkeepPeriod: 604800,
|
|
Description: fmt.Sprintf("Benchmark description %d", i),
|
|
}
|
|
|
|
if err := dhm.SaveHouseZone(ctx, zone); err != nil {
|
|
b.Fatalf("SaveHouseZone failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadPlayerHouses benchmarks loading player houses
|
|
func BenchmarkLoadPlayerHouses(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 1000) // 10 house types, 1000 player houses
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
characterID := int32(1000 + (i%1000) + 1)
|
|
houses, err := dhm.LoadPlayerHouses(ctx, characterID)
|
|
if err != nil {
|
|
b.Fatalf("LoadPlayerHouses failed: %v", err)
|
|
}
|
|
if len(houses) != 1 {
|
|
b.Errorf("Expected 1 house for character %d, got %d", characterID, len(houses))
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadPlayerHouse benchmarks loading a single player house
|
|
func BenchmarkLoadPlayerHouse(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 100)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
houseID := int64((i % 100) + 1)
|
|
house, err := dhm.LoadPlayerHouse(ctx, houseID)
|
|
if err != nil {
|
|
b.Fatalf("LoadPlayerHouse failed: %v", err)
|
|
}
|
|
if house == nil {
|
|
b.Error("LoadPlayerHouse returned nil house")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkAddPlayerHouse benchmarks adding player houses
|
|
func BenchmarkAddPlayerHouse(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 0) // Just house zones
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
houseData := PlayerHouseData{
|
|
CharacterID: int32(5000 + i),
|
|
HouseID: int32((i % 10) + 1),
|
|
InstanceID: int32(10000 + i),
|
|
UpkeepDue: time.Now().Add(24 * time.Hour),
|
|
EscrowCoins: int64(25000 + i*100),
|
|
EscrowStatus: int64(500 + i*5),
|
|
Status: HouseStatusActive,
|
|
HouseName: fmt.Sprintf("Benchmark House %d", i),
|
|
VisitPermission: int8(i % 3),
|
|
PublicNote: fmt.Sprintf("Welcome to benchmark house %d", i),
|
|
PrivateNote: fmt.Sprintf("Private note %d", i),
|
|
AllowFriends: i%2 == 0,
|
|
AllowGuild: i%3 == 0,
|
|
RequireApproval: i%4 == 0,
|
|
ShowOnDirectory: i%5 != 0,
|
|
AllowDecoration: i%6 != 0,
|
|
TaxExempt: i%10 == 0,
|
|
}
|
|
|
|
_, err := dhm.AddPlayerHouse(ctx, houseData)
|
|
if err != nil {
|
|
b.Fatalf("AddPlayerHouse failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadDeposits benchmarks loading house deposits
|
|
func BenchmarkLoadDeposits(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
// Insert deposit data for house ID 1
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 500) // 500 deposits
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
deposits, err := dhm.LoadDeposits(ctx, 1)
|
|
if err != nil {
|
|
b.Fatalf("LoadDeposits failed: %v", err)
|
|
}
|
|
if len(deposits) == 0 {
|
|
b.Error("LoadDeposits returned no deposits")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkSaveDeposit benchmarks saving deposits
|
|
func BenchmarkSaveDeposit(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
deposit := HouseDeposit{
|
|
Timestamp: time.Now(),
|
|
Amount: int64(1000 + i*10),
|
|
LastAmount: int64(2000 + i*10),
|
|
Status: int64(50 + i),
|
|
LastStatus: int64(100 + i),
|
|
Name: fmt.Sprintf("Benchmark Player %d", i),
|
|
CharacterID: int32(2000 + i),
|
|
}
|
|
|
|
if err := dhm.SaveDeposit(ctx, 1, deposit); err != nil {
|
|
b.Fatalf("SaveDeposit failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHistory benchmarks loading house history
|
|
func BenchmarkLoadHistory(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
// Insert history data for house ID 1
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 500) // 500 history entries
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
history, err := dhm.LoadHistory(ctx, 1)
|
|
if err != nil {
|
|
b.Fatalf("LoadHistory failed: %v", err)
|
|
}
|
|
if len(history) == 0 {
|
|
b.Error("LoadHistory returned no history")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkAddHistory benchmarks adding history entries
|
|
func BenchmarkAddHistory(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
history := HouseHistory{
|
|
Timestamp: time.Now(),
|
|
Amount: int64(500 + i*5),
|
|
Status: int64(25 + i),
|
|
Reason: fmt.Sprintf("Benchmark transaction %d", i),
|
|
Name: fmt.Sprintf("Benchmark Player %d", i),
|
|
CharacterID: int32(2000 + i),
|
|
PosFlag: int8(i % 2),
|
|
Type: int(i % 5),
|
|
}
|
|
|
|
if err := dhm.AddHistory(ctx, 1, history); err != nil {
|
|
b.Fatalf("AddHistory failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHouseAccess benchmarks loading house access
|
|
func BenchmarkLoadHouseAccess(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
// Insert access data for house ID 1
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 100) // Will create 10 access entries
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
access, err := dhm.LoadHouseAccess(ctx, 1)
|
|
if err != nil {
|
|
b.Fatalf("LoadHouseAccess failed: %v", err)
|
|
}
|
|
if len(access) == 0 {
|
|
b.Error("LoadHouseAccess returned no access entries")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkSaveHouseAccess benchmarks saving house access
|
|
func BenchmarkSaveHouseAccess(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
accessList := []HouseAccess{
|
|
{
|
|
CharacterID: int32(4000 + i),
|
|
PlayerName: fmt.Sprintf("BenchPlayer%d", i),
|
|
AccessLevel: int8(i % 3),
|
|
Permissions: int32(i % 16),
|
|
GrantedBy: 1001,
|
|
GrantedDate: time.Now(),
|
|
ExpiresDate: time.Now().Add(30 * 24 * time.Hour),
|
|
Notes: fmt.Sprintf("Benchmark access %d", i),
|
|
},
|
|
}
|
|
|
|
if err := dhm.SaveHouseAccess(ctx, 1, accessList); err != nil {
|
|
b.Fatalf("SaveHouseAccess failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHouseAmenities benchmarks loading house amenities
|
|
func BenchmarkLoadHouseAmenities(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
// Insert amenity data for house ID 1
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 100) // Will create 20 amenities
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
amenities, err := dhm.LoadHouseAmenities(ctx, 1)
|
|
if err != nil {
|
|
b.Fatalf("LoadHouseAmenities failed: %v", err)
|
|
}
|
|
if len(amenities) == 0 {
|
|
b.Error("LoadHouseAmenities returned no amenities")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkSaveHouseAmenity benchmarks saving house amenities
|
|
func BenchmarkSaveHouseAmenity(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
amenity := HouseAmenity{
|
|
ID: int32(5000 + i),
|
|
Type: int(i % 10),
|
|
Name: fmt.Sprintf("Benchmark Amenity %d", i),
|
|
Cost: int64(1000 + i*100),
|
|
StatusCost: int64(20 + i*2),
|
|
PurchaseDate: time.Now(),
|
|
X: float32(100 + i),
|
|
Y: float32(200 + i),
|
|
Z: float32(50 + i),
|
|
Heading: float32(i % 360),
|
|
IsActive: i%2 == 0,
|
|
}
|
|
|
|
if err := dhm.SaveHouseAmenity(ctx, 1, amenity); err != nil {
|
|
b.Fatalf("SaveHouseAmenity failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoadHouseItems benchmarks loading house items
|
|
func BenchmarkLoadHouseItems(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
// Insert item data for house ID 1
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 150) // Will create 50 items
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
items, err := dhm.LoadHouseItems(ctx, 1)
|
|
if err != nil {
|
|
b.Fatalf("LoadHouseItems failed: %v", err)
|
|
}
|
|
if len(items) == 0 {
|
|
b.Error("LoadHouseItems returned no items")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkSaveHouseItem benchmarks saving house items
|
|
func BenchmarkSaveHouseItem(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 1)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
item := HouseItem{
|
|
ID: int64(6000 + i),
|
|
ItemID: int32(20000 + i),
|
|
CharacterID: 1001,
|
|
X: float32(150 + i),
|
|
Y: float32(250 + i),
|
|
Z: float32(75 + i),
|
|
Heading: float32(i % 360),
|
|
PitchX: float32(i % 10),
|
|
PitchY: float32(i % 5),
|
|
RollX: float32(i % 15),
|
|
RollY: float32(i % 8),
|
|
PlacedDate: time.Now(),
|
|
Quantity: int32(1 + i%5),
|
|
Condition: int8(100 - i%100),
|
|
House: "benchmark",
|
|
}
|
|
|
|
if err := dhm.SaveHouseItem(ctx, 1, item); err != nil {
|
|
b.Fatalf("SaveHouseItem failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkUpdateHouseUpkeepDue benchmarks updating house upkeep due date
|
|
func BenchmarkUpdateHouseUpkeepDue(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 100)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
houseID := int64((i % 100) + 1)
|
|
newUpkeepDue := time.Now().Add(time.Duration(i) * time.Hour)
|
|
|
|
if err := dhm.UpdateHouseUpkeepDue(ctx, houseID, newUpkeepDue); err != nil {
|
|
b.Fatalf("UpdateHouseUpkeepDue failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkUpdateHouseEscrow benchmarks updating house escrow
|
|
func BenchmarkUpdateHouseEscrow(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 100)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
houseID := int64((i % 100) + 1)
|
|
coins := int64(50000 + i*1000)
|
|
status := int64(1000 + i*10)
|
|
|
|
if err := dhm.UpdateHouseEscrow(ctx, houseID, coins, status); err != nil {
|
|
b.Fatalf("UpdateHouseEscrow failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkGetHousesForUpkeep benchmarks getting houses for upkeep
|
|
func BenchmarkGetHousesForUpkeep(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 1000)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
cutoffTime := time.Now().Add(time.Duration(i%200) * time.Hour)
|
|
houses, err := dhm.GetHousesForUpkeep(ctx, cutoffTime)
|
|
if err != nil {
|
|
b.Fatalf("GetHousesForUpkeep failed: %v", err)
|
|
}
|
|
_ = houses // Prevent unused variable warning
|
|
}
|
|
}
|
|
|
|
// BenchmarkGetHouseStatistics benchmarks getting house statistics
|
|
func BenchmarkGetHouseStatistics(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 20, 2000)
|
|
|
|
// Add some deposits and history for more realistic stats
|
|
insertHouseRelatedData(b, dhm, ctx, 1, 100)
|
|
insertHouseRelatedData(b, dhm, ctx, 2, 150)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
stats, err := dhm.GetHouseStatistics(ctx)
|
|
if err != nil {
|
|
b.Fatalf("GetHouseStatistics failed: %v", err)
|
|
}
|
|
if stats.TotalHouses != 2000 {
|
|
b.Errorf("Expected 2000 total houses, got %d", stats.TotalHouses)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkGetHouseByInstance benchmarks finding houses by instance ID
|
|
func BenchmarkGetHouseByInstance(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 1000)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
instanceID := int32(5001 + (i % 1000))
|
|
house, err := dhm.GetHouseByInstance(ctx, instanceID)
|
|
if err != nil {
|
|
b.Fatalf("GetHouseByInstance failed: %v", err)
|
|
}
|
|
if house == nil {
|
|
b.Error("GetHouseByInstance returned nil house")
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkGetNextHouseID benchmarks getting the next house ID
|
|
func BenchmarkGetNextHouseID(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 5, 100)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
nextID, err := dhm.GetNextHouseID(ctx)
|
|
if err != nil {
|
|
b.Fatalf("GetNextHouseID failed: %v", err)
|
|
}
|
|
if nextID <= 100 {
|
|
b.Errorf("Expected next ID > 100, got %d", nextID)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkDeletePlayerHouse benchmarks deleting player houses
|
|
func BenchmarkDeletePlayerHouse(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
|
|
// We need to create houses to delete in each iteration
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
|
|
// Create a house to delete
|
|
houseData := PlayerHouseData{
|
|
CharacterID: int32(7000 + i),
|
|
HouseID: 1,
|
|
InstanceID: int32(8000 + i),
|
|
UpkeepDue: time.Now().Add(24 * time.Hour),
|
|
EscrowCoins: 25000,
|
|
EscrowStatus: 500,
|
|
Status: HouseStatusActive,
|
|
HouseName: fmt.Sprintf("DeleteMe %d", i),
|
|
VisitPermission: 1,
|
|
AllowFriends: true,
|
|
ShowOnDirectory: true,
|
|
}
|
|
|
|
houseID, err := dhm.AddPlayerHouse(ctx, houseData)
|
|
if err != nil {
|
|
b.Fatalf("Failed to create house for deletion: %v", err)
|
|
}
|
|
|
|
b.StartTimer()
|
|
|
|
// Delete the house
|
|
if err := dhm.DeletePlayerHouse(ctx, houseID); err != nil {
|
|
b.Fatalf("DeletePlayerHouse failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkConcurrentReads benchmarks concurrent read operations
|
|
func BenchmarkConcurrentReads(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 100)
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
characterID := int32(1001 + (i % 100))
|
|
houses, err := dhm.LoadPlayerHouses(ctx, characterID)
|
|
if err != nil {
|
|
b.Errorf("LoadPlayerHouses failed: %v", err)
|
|
}
|
|
if len(houses) != 1 {
|
|
b.Errorf("Expected 1 house, got %d", len(houses))
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
}
|
|
|
|
// BenchmarkConcurrentWrites benchmarks concurrent write operations
|
|
func BenchmarkConcurrentWrites(b *testing.B) {
|
|
dhm, ctx := setupBenchmarkDB(b)
|
|
insertBenchmarkData(b, dhm, ctx, 10, 0)
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
houseData := PlayerHouseData{
|
|
CharacterID: int32(10000 + i),
|
|
HouseID: int32((i % 10) + 1),
|
|
InstanceID: int32(20000 + i),
|
|
UpkeepDue: time.Now().Add(24 * time.Hour),
|
|
EscrowCoins: 25000,
|
|
EscrowStatus: 500,
|
|
Status: HouseStatusActive,
|
|
HouseName: fmt.Sprintf("Concurrent House %d", i),
|
|
VisitPermission: 1,
|
|
AllowFriends: true,
|
|
ShowOnDirectory: true,
|
|
}
|
|
|
|
_, err := dhm.AddPlayerHouse(ctx, houseData)
|
|
if err != nil {
|
|
b.Errorf("AddPlayerHouse failed: %v", err)
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
} |