Refactor QueryFits to handle module and group typeID expansion based on presence of modules; update calculateModuleStats to use filtered killmailIDs for improved accuracy. Adjust Dockerfile for better build efficiency.

This commit is contained in:
2026-01-06 00:28:34 +01:00
parent 689a485e1c
commit 41a96258a4
3 changed files with 69 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
# Build stage
FROM golang:bullseye as base
FROM golang:bullseye AS base
RUN adduser \
--disabled-password \
@@ -12,14 +12,16 @@ RUN adduser \
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN apt-get update && apt-get install -y \
gcc \
libc6-dev
RUN GOFLAGS=-mod=vendor \
CGO_ENABLED=1 \
RUN CGO_ENABLED=1 \
GOOS=linux \
GOARCH=amd64 \
CGO_LDFLAGS="-static -w -s" \

97
db.go
View File

@@ -366,10 +366,14 @@ func (db *DBWrapper) QueryFits(params QueryParams) (*FitStatistics, error) {
flog.Debug("Deduplicated modules: %d -> %d", len(params.Modules), len(modules))
// Expand groups to typeIDs
// If modules are present, groups expand to module typeIDs
// Otherwise, groups expand to ship typeIDs
var shipTypeIDs []int64
if params.Ship != 0 {
shipTypeIDs = []int64{params.Ship}
}
var groupModuleTypeIDs []int64
if len(params.Groups) > 0 {
var groupTypeIDs []int32
err := db.gormDB.Model(&models.InvType{}).
@@ -380,10 +384,20 @@ func (db *DBWrapper) QueryFits(params QueryParams) (*FitStatistics, error) {
flog.Error("Failed to expand groups to typeIDs: %v", err)
return nil, err
}
for _, typeID := range groupTypeIDs {
shipTypeIDs = append(shipTypeIDs, int64(typeID))
if len(modules) > 0 {
// When modules are present, groups should expand to module typeIDs
for _, typeID := range groupTypeIDs {
groupModuleTypeIDs = append(groupModuleTypeIDs, int64(typeID))
}
flog.Debug("Expanded %d groups to %d module typeIDs (modules filter active)", len(params.Groups), len(groupModuleTypeIDs))
} else {
// When no modules, groups expand to ship typeIDs
for _, typeID := range groupTypeIDs {
shipTypeIDs = append(shipTypeIDs, int64(typeID))
}
flog.Debug("Expanded %d groups to %d ship typeIDs", len(params.Groups), len(groupTypeIDs))
}
flog.Debug("Expanded %d groups to %d typeIDs", len(params.Groups), len(groupTypeIDs))
}
ctx := context.Background()
@@ -393,9 +407,14 @@ func (db *DBWrapper) QueryFits(params QueryParams) (*FitStatistics, error) {
var shipTypeIDsFromResults []int64
if len(modules) > 0 {
placeholders := make([]string, len(modules))
moduleArgs := make([]interface{}, len(modules))
for i, moduleID := range modules {
// Add group module typeIDs to modules filter
allModuleIDs := append(modules, groupModuleTypeIDs...)
allModuleIDs = deduplicateInt64(allModuleIDs)
flog.Debug("Combined modules and group modules: %d total module IDs", len(allModuleIDs))
placeholders := make([]string, len(allModuleIDs))
moduleArgs := make([]interface{}, len(allModuleIDs))
for i, moduleID := range allModuleIDs {
placeholders[i] = "?"
moduleArgs[i] = moduleID
}
@@ -553,7 +572,7 @@ func (db *DBWrapper) QueryFits(params QueryParams) (*FitStatistics, error) {
flog.Debug("Calculating module statistics for %d killmails", len(killmailIDs))
if err := db.calculateModuleStats(params, shipTypeIDs, stats, totalKillmails, flog); err != nil {
if err := db.calculateModuleStats(params, shipTypeIDs, killmailIDs, stats, totalKillmails, flog); err != nil {
flog.Error("Failed to calculate module stats: %v", err)
return nil, err
}
@@ -772,45 +791,57 @@ func (db *DBWrapper) getModuleSlots(moduleIDs []int64) (map[int64]string, error)
return result, nil
}
func (db *DBWrapper) calculateModuleStats(params QueryParams, shipTypeIDs []int64, stats *FitStatistics, total int64, flog *logger.Logger) error {
func (db *DBWrapper) calculateModuleStats(params QueryParams, shipTypeIDs []int64, killmailIDs []int64, stats *FitStatistics, total int64, flog *logger.Logger) error {
if total == 0 {
return nil
}
ctx := context.Background()
// Use shipTypeIDs filter instead of huge IN clause of killmailIDs
var shipPlaceholders []string
var query string
var args []interface{}
if len(shipTypeIDs) > 0 {
shipPlaceholders = make([]string, len(shipTypeIDs))
for i, shipID := range shipTypeIDs {
shipPlaceholders[i] = "?"
args = append(args, shipID)
// If we have filtered killmailIDs (from module/group filters), use them directly
// Otherwise, use shipTypeIDs filter
if len(killmailIDs) > 0 && len(killmailIDs) < 100000 {
// Use killmailIDs filter for better accuracy when modules/groups are filtered
placeholders := make([]string, len(killmailIDs))
for i := range killmailIDs {
placeholders[i] = "?"
args = append(args, killmailIDs[i])
}
} else if params.Ship != 0 {
shipPlaceholders = []string{"?"}
args = []interface{}{params.Ship}
}
var query string
if len(shipPlaceholders) > 0 {
query = "SELECT item_type_id, flag, count(DISTINCT killmail_id) as count FROM fitted_modules WHERE victim_ship_type_id IN (" + strings.Join(shipPlaceholders, ",") + ")"
query = "SELECT item_type_id, flag, count(DISTINCT killmail_id) as count FROM fitted_modules WHERE killmail_id IN (" + strings.Join(placeholders, ",") + ")"
} else {
query = "SELECT item_type_id, flag, count(DISTINCT killmail_id) as count FROM fitted_modules"
}
if len(params.Systems) > 0 {
sysPlaceholders := make([]string, len(params.Systems))
for i := range params.Systems {
sysPlaceholders[i] = "?"
args = append(args, params.Systems[i])
// Fallback to shipTypeIDs filter for performance when too many killmails
var shipPlaceholders []string
if len(shipTypeIDs) > 0 {
shipPlaceholders = make([]string, len(shipTypeIDs))
for i, shipID := range shipTypeIDs {
shipPlaceholders[i] = "?"
args = append(args, shipID)
}
} else if params.Ship != 0 {
shipPlaceholders = []string{"?"}
args = []interface{}{params.Ship}
}
if len(shipPlaceholders) > 0 {
query += " AND solar_system_id IN (" + strings.Join(sysPlaceholders, ",") + ")"
query = "SELECT item_type_id, flag, count(DISTINCT killmail_id) as count FROM fitted_modules WHERE victim_ship_type_id IN (" + strings.Join(shipPlaceholders, ",") + ")"
} else {
query += " WHERE solar_system_id IN (" + strings.Join(sysPlaceholders, ",") + ")"
query = "SELECT item_type_id, flag, count(DISTINCT killmail_id) as count FROM fitted_modules"
}
if len(params.Systems) > 0 {
sysPlaceholders := make([]string, len(params.Systems))
for i := range params.Systems {
sysPlaceholders[i] = "?"
args = append(args, params.Systems[i])
}
if len(shipPlaceholders) > 0 {
query += " AND solar_system_id IN (" + strings.Join(sysPlaceholders, ",") + ")"
} else {
query += " WHERE solar_system_id IN (" + strings.Join(sysPlaceholders, ",") + ")"
}
}
}

View File

@@ -44,7 +44,6 @@ func main() {
params := QueryParams{
Ship: 32872,
Modules: []int64{2456},
Groups: []int64{325},
}
stats, err := db.QueryFits(params)
if err != nil {