mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 23:50:12 +01:00
perf: improve commander selection speed and fix color identity display
This commit is contained in:
parent
454269daab
commit
345dfb3e01
12 changed files with 321 additions and 106 deletions
|
|
@ -838,7 +838,29 @@ class DeckBuilder(
|
|||
if self._commander_df is not None:
|
||||
return self._commander_df
|
||||
|
||||
# M4: Load commanders from Parquet instead of CSV
|
||||
# M7: Try loading from dedicated commander cache first (fast path)
|
||||
from path_util import get_commander_cards_path
|
||||
from file_setup.data_loader import DataLoader
|
||||
|
||||
commander_path = get_commander_cards_path()
|
||||
if os.path.exists(commander_path):
|
||||
try:
|
||||
loader = DataLoader()
|
||||
df = loader.read_cards(commander_path, format="parquet")
|
||||
|
||||
# Ensure required columns exist with proper defaults
|
||||
if "themeTags" not in df.columns:
|
||||
df["themeTags"] = [[] for _ in range(len(df))]
|
||||
if "creatureTypes" not in df.columns:
|
||||
df["creatureTypes"] = [[] for _ in range(len(df))]
|
||||
|
||||
self._commander_df = df
|
||||
return df
|
||||
except Exception:
|
||||
# Fall through to legacy path if cache read fails
|
||||
pass
|
||||
|
||||
# M4: Fallback - Load commanders from full Parquet file (slower)
|
||||
from deck_builder import builder_utils as bu
|
||||
from deck_builder import builder_constants as bc
|
||||
|
||||
|
|
|
|||
|
|
@ -71,33 +71,61 @@ def _resolved_csv_dir(base_dir: str | None = None) -> str:
|
|||
return base_dir or csv_dir()
|
||||
|
||||
|
||||
# M7: Cache for all cards Parquet DataFrame to avoid repeated loads
|
||||
_ALL_CARDS_CACHE: Dict[str, Any] = {"df": None, "mtime": None}
|
||||
|
||||
|
||||
def _load_all_cards_parquet() -> pd.DataFrame:
|
||||
"""Load all cards from the unified Parquet file.
|
||||
"""Load all cards from the unified Parquet file with caching.
|
||||
|
||||
M4: Centralized Parquet loading for deck builder.
|
||||
M7: Added module-level caching to avoid repeated file loads.
|
||||
Returns empty DataFrame on error (defensive).
|
||||
Converts numpy arrays to Python lists for compatibility with existing code.
|
||||
"""
|
||||
global _ALL_CARDS_CACHE
|
||||
|
||||
try:
|
||||
from code.path_util import get_processed_cards_path
|
||||
from code.file_setup.data_loader import DataLoader
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
parquet_path = get_processed_cards_path()
|
||||
if not Path(parquet_path).exists():
|
||||
return pd.DataFrame()
|
||||
|
||||
data_loader = DataLoader()
|
||||
df = data_loader.read_cards(parquet_path, format="parquet")
|
||||
# M7: Check cache and mtime
|
||||
need_reload = _ALL_CARDS_CACHE["df"] is None
|
||||
if not need_reload:
|
||||
try:
|
||||
current_mtime = os.path.getmtime(parquet_path)
|
||||
cached_mtime = _ALL_CARDS_CACHE.get("mtime")
|
||||
if cached_mtime is None or current_mtime > cached_mtime:
|
||||
need_reload = True
|
||||
except Exception:
|
||||
# If mtime check fails, use cached version if available
|
||||
pass
|
||||
|
||||
# M4: Convert numpy arrays to Python lists for compatibility
|
||||
# Parquet stores lists as numpy arrays, but existing code expects Python lists
|
||||
list_columns = ['themeTags', 'creatureTypes', 'metadataTags', 'keywords']
|
||||
for col in list_columns:
|
||||
if col in df.columns:
|
||||
df[col] = df[col].apply(lambda x: x.tolist() if isinstance(x, np.ndarray) else x)
|
||||
if need_reload:
|
||||
data_loader = DataLoader()
|
||||
df = data_loader.read_cards(parquet_path, format="parquet")
|
||||
|
||||
# M4: Convert numpy arrays to Python lists for compatibility
|
||||
# Parquet stores lists as numpy arrays, but existing code expects Python lists
|
||||
list_columns = ['themeTags', 'creatureTypes', 'metadataTags', 'keywords']
|
||||
for col in list_columns:
|
||||
if col in df.columns:
|
||||
df[col] = df[col].apply(lambda x: x.tolist() if isinstance(x, np.ndarray) else x)
|
||||
|
||||
# M7: Cache the result
|
||||
_ALL_CARDS_CACHE["df"] = df
|
||||
try:
|
||||
_ALL_CARDS_CACHE["mtime"] = os.path.getmtime(parquet_path)
|
||||
except Exception:
|
||||
_ALL_CARDS_CACHE["mtime"] = None
|
||||
|
||||
return df
|
||||
return _ALL_CARDS_CACHE["df"]
|
||||
except Exception:
|
||||
return pd.DataFrame()
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,8 @@ class CommanderSelectionMixin:
|
|||
def _apply_commander_selection(self, row: pd.Series): # type: ignore[override]
|
||||
self.commander_name = row["name"]
|
||||
self.commander_row = row
|
||||
self.commander_tags = list(row.get("themeTags", []) or [])
|
||||
tags_value = row.get("themeTags", [])
|
||||
self.commander_tags = list(tags_value) if tags_value is not None else []
|
||||
self._initialize_commander_dict(row)
|
||||
|
||||
# ---------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue