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:
@@ -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
97
db.go
@@ -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, ",") + ")"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user