package com.margelo.nitro.lunardatepicker.utils import android.util.Log import com.margelo.nitro.lunardatepicker.constants.DataConstants import java.time.LocalDate import java.time.ZoneId /** * Memory optimization utility for the lunar date picker * Manages object pools and provides memory usage monitoring */ object MemoryOptimizer { private const val TAG = DataConstants.LogTags.MAIN /** * Preloads object pools with commonly used objects * This reduces memory allocation during calendar usage */ fun preloadObjectPools() { try { // Preload GradientDrawable pool val gradientPool = ObjectPoolManager.gradientDrawablePool repeat(10) { val drawable = gradientPool.acquire() gradientPool.release(drawable) } // Preload LunarDate pool val lunarPool = ObjectPoolManager.lunarDatePool repeat(20) { val lunarDate = lunarPool.acquire() lunarPool.release(lunarDate) } // Precompute common dimensions for performance DimensionUtils.precomputeCommonDimensions() Log.i(TAG, "Object pools and dimensions preloaded successfully") } catch (e: Exception) { Log.e(TAG, "Failed to preload object pools", e) } } /** * Preloads lunar date cache for commonly accessed date ranges */ fun preloadLunarDateCache( dateConverter: DateConverter, timeZone: ZoneId = ZoneId.systemDefault() ) { try { val currentDate = LocalDate.now() val startDate = currentDate.minusMonths(6) val endDate = currentDate.plusMonths(6) Log.i(TAG, "Preloading lunar date cache from $startDate to $endDate") dateConverter.preloadLunarDateCache(startDate, endDate, timeZone) Log.i(TAG, "Lunar date cache preloaded successfully") } catch (e: Exception) { Log.e(TAG, "Failed to preload lunar date cache", e) } } /** * Logs comprehensive performance statistics including price indexing */ fun logPerformanceStats() { Log.i(TAG, "=== Performance Statistics ===") // Memory stats val runtime = Runtime.getRuntime() val maxMemory = runtime.maxMemory() val totalMemory = runtime.totalMemory() val freeMemory = runtime.freeMemory() val usedMemory = totalMemory - freeMemory Log.i( TAG, "Memory: ${usedMemory / 1024 / 1024}MB / ${maxMemory / 1024 / 1024}MB (${ "%.1f".format(usedMemory.toDouble() / maxMemory * 100) }%)" ) // Object pool stats ObjectPoolManager.logPoolStats() // Dimension cache stats val dimensionStats = DimensionUtils.getCacheStats() Log.i(TAG, "Dimension Cache: $dimensionStats") // Configuration cache stats logConfigurationCacheStats() // Color cache stats logColorCacheStats() } /** * Logs configuration cache statistics */ fun logConfigurationCacheStats() { try { val configBuilder = com.margelo.nitro.lunardatepicker.services.ConfigurationBuilder() val stats = configBuilder.getCacheStats() Log.i(TAG, "Configuration Cache: $stats") } catch (e: Exception) { Log.w(TAG, "Failed to get configuration cache stats", e) } } /** * Logs color cache statistics */ fun logColorCacheStats() { try { val colorStats = ColorUtils.getCacheStats() if (colorStats != null) { Log.i(TAG, "Color Cache: $colorStats") } } catch (e: Exception) { Log.w(TAG, "Failed to get color cache stats", e) } } /** * Logs performance stats for a specific price repository * @param priceRepository PriceRepository to analyze */ fun logPriceIndexingStats(priceRepository: com.margelo.nitro.lunardatepicker.repositories.PriceRepository) { try { val stats = priceRepository.getPerformanceStats() Log.i(TAG, "Price Indexing Stats: $stats") } catch (e: Exception) { Log.w(TAG, "Failed to get price indexing stats", e) } } /** * Logs all cache statistics for comprehensive performance monitoring * Should be called during app lifecycle events (like fragment cleanup) */ fun logAllCacheStats() { Log.i(TAG, "=== Cache Performance Summary ===") try { // Configuration cache stats logConfigurationCacheStats() // Color cache stats logColorCacheStats() // Dimension cache stats val dimensionStats = DimensionUtils.getCacheStats() Log.i(TAG, "Dimension Cache: $dimensionStats") // Object pool stats ObjectPoolManager.logPoolStats() Log.i(TAG, "=== End Cache Performance Summary ===") } catch (e: Exception) { Log.w(TAG, "Failed to log cache stats", e) } } }