Memoize database functions to reduce disk reads
This commit is contained in:
117
db.go
117
db.go
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"zkillsusser/models"
|
||||
|
||||
utils "git.site.quack-lab.dev/dave/cyutils"
|
||||
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
|
||||
"gorm.io/driver/sqlite"
|
||||
@@ -64,6 +66,14 @@ type DB interface {
|
||||
type DBWrapper struct {
|
||||
ch driver.Conn
|
||||
db *gorm.DB // For SQLite (EVE static data)
|
||||
|
||||
getTypeMemo func(context.Context, int32) (*models.InvType, error)
|
||||
getGroupMemo func(context.Context, int32) (*models.InvGroup, error)
|
||||
getCategoryMemo func(context.Context, int32) (*models.InvCategory, error)
|
||||
getMarketGroupMemo func(context.Context, int32) (*models.InvMarketGroup, error)
|
||||
getSystemMemo func(context.Context, int32) (*models.MapSolarSystem, error)
|
||||
getConstellationMemo func(context.Context, int32) (*models.MapConstellation, error)
|
||||
getRegionMemo func(context.Context, int32) (*models.MapRegion, error)
|
||||
}
|
||||
|
||||
var db *DBWrapper
|
||||
@@ -87,6 +97,71 @@ func GetDB() (DB, error) {
|
||||
ch: conn,
|
||||
db: sdb,
|
||||
}
|
||||
|
||||
getTypeFn := func(ctx context.Context, typeID int32) (*models.InvType, error) {
|
||||
var t models.InvType
|
||||
if err := db.db.Where("typeID = ?", typeID).First(&t).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get type %d: %w", typeID, err)
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
getGroupFn := func(ctx context.Context, groupID int32) (*models.InvGroup, error) {
|
||||
var g models.InvGroup
|
||||
if err := db.db.Where("groupID = ?", groupID).First(&g).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get group %d: %w", groupID, err)
|
||||
}
|
||||
return &g, nil
|
||||
}
|
||||
|
||||
getCategoryFn := func(ctx context.Context, categoryID int32) (*models.InvCategory, error) {
|
||||
var c models.InvCategory
|
||||
if err := db.db.Where("categoryID = ?", categoryID).First(&c).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get category %d: %w", categoryID, err)
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
getMarketGroupFn := func(ctx context.Context, marketGroupID int32) (*models.InvMarketGroup, error) {
|
||||
var mg models.InvMarketGroup
|
||||
if err := db.db.Where("marketGroupID = ?", marketGroupID).First(&mg).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get market group %d: %w", marketGroupID, err)
|
||||
}
|
||||
return &mg, nil
|
||||
}
|
||||
|
||||
getSystemFn := func(ctx context.Context, systemID int32) (*models.MapSolarSystem, error) {
|
||||
var s models.MapSolarSystem
|
||||
if err := db.db.Where("solarSystemID = ?", systemID).First(&s).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get solar system %d: %w", systemID, err)
|
||||
}
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
getConstellationFn := func(ctx context.Context, constellationID int32) (*models.MapConstellation, error) {
|
||||
var c models.MapConstellation
|
||||
if err := db.db.Where("constellationID = ?", constellationID).First(&c).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get constellation %d: %w", constellationID, err)
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
getRegionFn := func(ctx context.Context, regionID int32) (*models.MapRegion, error) {
|
||||
var r models.MapRegion
|
||||
if err := db.db.Where("regionID = ?", regionID).First(&r).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get region %d: %w", regionID, err)
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
db.getTypeMemo = utils.Memoized(getTypeFn).(func(context.Context, int32) (*models.InvType, error))
|
||||
db.getGroupMemo = utils.Memoized(getGroupFn).(func(context.Context, int32) (*models.InvGroup, error))
|
||||
db.getCategoryMemo = utils.Memoized(getCategoryFn).(func(context.Context, int32) (*models.InvCategory, error))
|
||||
db.getMarketGroupMemo = utils.Memoized(getMarketGroupFn).(func(context.Context, int32) (*models.InvMarketGroup, error))
|
||||
db.getSystemMemo = utils.Memoized(getSystemFn).(func(context.Context, int32) (*models.MapSolarSystem, error))
|
||||
db.getConstellationMemo = utils.Memoized(getConstellationFn).(func(context.Context, int32) (*models.MapConstellation, error))
|
||||
db.getRegionMemo = utils.Memoized(getRegionFn).(func(context.Context, int32) (*models.MapRegion, error))
|
||||
|
||||
err = db.Init()
|
||||
return db, err
|
||||
}
|
||||
@@ -237,57 +312,29 @@ func (db *DBWrapper) GetModuleSlots(moduleIDs []int64) (map[int64]ModuleSlot, er
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetType(ctx context.Context, typeID int32) (*models.InvType, error) {
|
||||
var t models.InvType
|
||||
if err := db.db.Where("typeID = ?", typeID).First(&t).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get type %d: %w", typeID, err)
|
||||
}
|
||||
return &t, nil
|
||||
return db.getTypeMemo(ctx, typeID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetGroup(ctx context.Context, groupID int32) (*models.InvGroup, error) {
|
||||
var g models.InvGroup
|
||||
if err := db.db.Where("groupID = ?", groupID).First(&g).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get group %d: %w", groupID, err)
|
||||
}
|
||||
return &g, nil
|
||||
return db.getGroupMemo(ctx, groupID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetCategory(ctx context.Context, categoryID int32) (*models.InvCategory, error) {
|
||||
var c models.InvCategory
|
||||
if err := db.db.Where("categoryID = ?", categoryID).First(&c).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get category %d: %w", categoryID, err)
|
||||
}
|
||||
return &c, nil
|
||||
return db.getCategoryMemo(ctx, categoryID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetMarketGroup(ctx context.Context, marketGroupID int32) (*models.InvMarketGroup, error) {
|
||||
var mg models.InvMarketGroup
|
||||
if err := db.db.Where("marketGroupID = ?", marketGroupID).First(&mg).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get market group %d: %w", marketGroupID, err)
|
||||
}
|
||||
return &mg, nil
|
||||
return db.getMarketGroupMemo(ctx, marketGroupID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetSolarSystem(ctx context.Context, systemID int32) (*models.MapSolarSystem, error) {
|
||||
var s models.MapSolarSystem
|
||||
if err := db.db.Where("solarSystemID = ?", systemID).First(&s).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get solar system %d: %w", systemID, err)
|
||||
}
|
||||
return &s, nil
|
||||
return db.getSystemMemo(ctx, systemID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetConstellation(ctx context.Context, constellationID int32) (*models.MapConstellation, error) {
|
||||
var c models.MapConstellation
|
||||
if err := db.db.Where("constellationID = ?", constellationID).First(&c).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get constellation %d: %w", constellationID, err)
|
||||
}
|
||||
return &c, nil
|
||||
return db.getConstellationMemo(ctx, constellationID)
|
||||
}
|
||||
|
||||
func (db *DBWrapper) GetRegion(ctx context.Context, regionID int32) (*models.MapRegion, error) {
|
||||
var r models.MapRegion
|
||||
if err := db.db.Where("regionID = ?", regionID).First(&r).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get region %d: %w", regionID, err)
|
||||
}
|
||||
return &r, nil
|
||||
return db.getRegionMemo(ctx, regionID)
|
||||
}
|
||||
|
||||
4
go.mod
4
go.mod
@@ -6,8 +6,9 @@ toolchain go1.24.11
|
||||
|
||||
require (
|
||||
git.site.quack-lab.dev/dave/cylogger v1.5.0
|
||||
git.site.quack-lab.dev/dave/cyutils v1.5.0
|
||||
git.site.quack-lab.dev/dave/cyutils v1.6.0
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.42.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/nsqio/go-nsq v1.1.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
golang.org/x/sync v0.19.0
|
||||
@@ -28,7 +29,6 @@ require (
|
||||
github.com/hexops/valast v1.5.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/paulmach/orb v0.12.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,7 +1,7 @@
|
||||
git.site.quack-lab.dev/dave/cylogger v1.5.0 h1:9H/eEMD1dqJ9hEudwbszxrzE9lN0P0iCeYOzYRPMWOA=
|
||||
git.site.quack-lab.dev/dave/cylogger v1.5.0/go.mod h1:wctgZplMvroA4X6p8f4B/LaCKtiBcT1Pp+L14kcS8jk=
|
||||
git.site.quack-lab.dev/dave/cyutils v1.5.0 h1:U5pojDNoXV4Kj/dlPaGm2COaT4aX6zu88gBF+nTYeJw=
|
||||
git.site.quack-lab.dev/dave/cyutils v1.5.0/go.mod h1:fBjALu2Cp2u2bDr+E4zbGVMBeIgFzROg+4TCcTNAiQU=
|
||||
git.site.quack-lab.dev/dave/cyutils v1.6.0 h1:l+2Xv3c10SUAW+lOkrW5qt/Nf9+ocbkm6J4h8xP8p1Q=
|
||||
git.site.quack-lab.dev/dave/cyutils v1.6.0/go.mod h1:fBjALu2Cp2u2bDr+E4zbGVMBeIgFzROg+4TCcTNAiQU=
|
||||
github.com/ClickHouse/ch-go v0.69.0 h1:nO0OJkpxOlN/eaXFj0KzjTz5p7vwP1/y3GN4qc5z/iM=
|
||||
github.com/ClickHouse/ch-go v0.69.0/go.mod h1:9XeZpSAT4S0kVjOpaJ5186b7PY/NH/hhF8R6u0WIjwg=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.42.0 h1:MdujEfIrpXesQUH0k0AnuVtJQXk6RZmxEhsKUCcv5xk=
|
||||
|
||||
Reference in New Issue
Block a user