You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
802 lines
24 KiB
802 lines
24 KiB
/**
|
|
* DailyNotificationPerformanceOptimizer.java
|
|
*
|
|
* Android Performance Optimizer for database, memory, and battery optimization
|
|
* Implements query optimization, memory management, and battery tracking
|
|
*
|
|
* @author Matthew Raymer
|
|
* @version 1.0.0
|
|
*/
|
|
|
|
package com.timesafari.dailynotification;
|
|
|
|
import android.content.Context;
|
|
import android.os.Debug;
|
|
import android.util.Log;
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
|
/**
|
|
* Optimizes performance through database, memory, and battery management
|
|
*
|
|
* This class implements the critical performance optimization functionality:
|
|
* - Database query optimization with indexes
|
|
* - Memory usage monitoring and optimization
|
|
* - Object pooling for frequently used objects
|
|
* - Battery usage tracking and optimization
|
|
* - Background CPU usage minimization
|
|
* - Network request optimization
|
|
*/
|
|
public class DailyNotificationPerformanceOptimizer {
|
|
|
|
// MARK: - Constants
|
|
|
|
private static final String TAG = "DailyNotificationPerformanceOptimizer";
|
|
|
|
// Performance monitoring intervals
|
|
private static final long MEMORY_CHECK_INTERVAL_MS = TimeUnit.MINUTES.toMillis(5);
|
|
private static final long BATTERY_CHECK_INTERVAL_MS = TimeUnit.MINUTES.toMillis(10);
|
|
private static final long PERFORMANCE_REPORT_INTERVAL_MS = TimeUnit.HOURS.toMillis(1);
|
|
|
|
// Memory thresholds
|
|
private static final long MEMORY_WARNING_THRESHOLD_MB = 50;
|
|
private static final long MEMORY_CRITICAL_THRESHOLD_MB = 100;
|
|
|
|
// Object pool sizes
|
|
private static final int DEFAULT_POOL_SIZE = 10;
|
|
private static final int MAX_POOL_SIZE = 50;
|
|
|
|
// MARK: - Properties
|
|
|
|
private final Context context;
|
|
private final DailyNotificationDatabase database;
|
|
private final ScheduledExecutorService scheduler;
|
|
|
|
// Performance metrics
|
|
private final PerformanceMetrics metrics;
|
|
|
|
// Object pools
|
|
private final ConcurrentHashMap<Class<?>, ObjectPool<?>> objectPools;
|
|
|
|
// Memory monitoring
|
|
private final AtomicLong lastMemoryCheck;
|
|
private final AtomicLong lastBatteryCheck;
|
|
|
|
// MARK: - Initialization
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param context Application context
|
|
* @param database Database instance for optimization
|
|
*/
|
|
public DailyNotificationPerformanceOptimizer(Context context, DailyNotificationDatabase database) {
|
|
this.context = context;
|
|
this.database = database;
|
|
this.scheduler = Executors.newScheduledThreadPool(2);
|
|
this.metrics = new PerformanceMetrics();
|
|
this.objectPools = new ConcurrentHashMap<>();
|
|
this.lastMemoryCheck = new AtomicLong(0);
|
|
this.lastBatteryCheck = new AtomicLong(0);
|
|
|
|
// Initialize object pools
|
|
initializeObjectPools();
|
|
|
|
// Start performance monitoring
|
|
startPerformanceMonitoring();
|
|
|
|
Log.d(TAG, "PerformanceOptimizer initialized");
|
|
}
|
|
|
|
// MARK: - Database Optimization
|
|
|
|
/**
|
|
* Optimize database performance
|
|
*/
|
|
public void optimizeDatabase() {
|
|
try {
|
|
Log.d(TAG, "Optimizing database performance");
|
|
|
|
// Add database indexes
|
|
addDatabaseIndexes();
|
|
|
|
// Optimize query performance
|
|
optimizeQueryPerformance();
|
|
|
|
// Implement connection pooling
|
|
optimizeConnectionPooling();
|
|
|
|
// Analyze database performance
|
|
analyzeDatabasePerformance();
|
|
|
|
Log.i(TAG, "Database optimization completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing database", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add database indexes for query optimization
|
|
*/
|
|
private void addDatabaseIndexes() {
|
|
try {
|
|
Log.d(TAG, "Adding database indexes for query optimization");
|
|
|
|
// Add indexes for common queries
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_contents_slot_time ON notif_contents(slot_id, fetched_at DESC)");
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_deliveries_status ON notif_deliveries(status)");
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_deliveries_fire_time ON notif_deliveries(fire_at)");
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_config_key ON notif_config(k)");
|
|
|
|
// Add composite indexes for complex queries
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_contents_slot_fetch ON notif_contents(slot_id, fetched_at)");
|
|
database.execSQL("CREATE INDEX IF NOT EXISTS idx_notif_deliveries_slot_status ON notif_deliveries(slot_id, status)");
|
|
|
|
Log.i(TAG, "Database indexes added successfully");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error adding database indexes", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Optimize query performance
|
|
*/
|
|
private void optimizeQueryPerformance() {
|
|
try {
|
|
Log.d(TAG, "Optimizing query performance");
|
|
|
|
// Set database optimization pragmas
|
|
database.execSQL("PRAGMA optimize");
|
|
database.execSQL("PRAGMA analysis_limit=1000");
|
|
database.execSQL("PRAGMA optimize");
|
|
|
|
// Enable query plan analysis
|
|
database.execSQL("PRAGMA query_only=0");
|
|
|
|
Log.i(TAG, "Query performance optimization completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing query performance", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Optimize connection pooling
|
|
*/
|
|
private void optimizeConnectionPooling() {
|
|
try {
|
|
Log.d(TAG, "Optimizing connection pooling");
|
|
|
|
// Set connection pool settings
|
|
database.execSQL("PRAGMA cache_size=10000");
|
|
database.execSQL("PRAGMA temp_store=MEMORY");
|
|
database.execSQL("PRAGMA mmap_size=268435456"); // 256MB
|
|
|
|
Log.i(TAG, "Connection pooling optimization completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing connection pooling", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Analyze database performance
|
|
*/
|
|
private void analyzeDatabasePerformance() {
|
|
try {
|
|
Log.d(TAG, "Analyzing database performance");
|
|
|
|
// Get database statistics
|
|
long pageCount = database.getPageCount();
|
|
long pageSize = database.getPageSize();
|
|
long cacheSize = database.getCacheSize();
|
|
|
|
Log.i(TAG, String.format("Database stats: pages=%d, pageSize=%d, cacheSize=%d",
|
|
pageCount, pageSize, cacheSize));
|
|
|
|
// Update metrics
|
|
metrics.recordDatabaseStats(pageCount, pageSize, cacheSize);
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error analyzing database performance", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Memory Optimization
|
|
|
|
/**
|
|
* Optimize memory usage
|
|
*/
|
|
public void optimizeMemory() {
|
|
try {
|
|
Log.d(TAG, "Optimizing memory usage");
|
|
|
|
// Check current memory usage
|
|
long memoryUsage = getCurrentMemoryUsage();
|
|
|
|
if (memoryUsage > MEMORY_CRITICAL_THRESHOLD_MB) {
|
|
Log.w(TAG, "Critical memory usage detected: " + memoryUsage + "MB");
|
|
performCriticalMemoryCleanup();
|
|
} else if (memoryUsage > MEMORY_WARNING_THRESHOLD_MB) {
|
|
Log.w(TAG, "High memory usage detected: " + memoryUsage + "MB");
|
|
performMemoryCleanup();
|
|
}
|
|
|
|
// Optimize object pools
|
|
optimizeObjectPools();
|
|
|
|
// Update metrics
|
|
metrics.recordMemoryUsage(memoryUsage);
|
|
|
|
Log.i(TAG, "Memory optimization completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing memory", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get current memory usage in MB
|
|
*
|
|
* @return Memory usage in MB
|
|
*/
|
|
private long getCurrentMemoryUsage() {
|
|
try {
|
|
Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
|
|
Debug.getMemoryInfo(memoryInfo);
|
|
|
|
long totalPss = memoryInfo.getTotalPss();
|
|
return totalPss / 1024; // Convert to MB
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error getting memory usage", e);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform critical memory cleanup
|
|
*/
|
|
private void performCriticalMemoryCleanup() {
|
|
try {
|
|
Log.w(TAG, "Performing critical memory cleanup");
|
|
|
|
// Clear object pools
|
|
clearObjectPools();
|
|
|
|
// Force garbage collection
|
|
System.gc();
|
|
|
|
// Clear caches
|
|
clearCaches();
|
|
|
|
Log.i(TAG, "Critical memory cleanup completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error performing critical memory cleanup", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform regular memory cleanup
|
|
*/
|
|
private void performMemoryCleanup() {
|
|
try {
|
|
Log.d(TAG, "Performing regular memory cleanup");
|
|
|
|
// Clean up expired objects in pools
|
|
cleanupObjectPools();
|
|
|
|
// Clear old caches
|
|
clearOldCaches();
|
|
|
|
Log.i(TAG, "Regular memory cleanup completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error performing memory cleanup", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Object Pooling
|
|
|
|
/**
|
|
* Initialize object pools
|
|
*/
|
|
private void initializeObjectPools() {
|
|
try {
|
|
Log.d(TAG, "Initializing object pools");
|
|
|
|
// Create pools for frequently used objects
|
|
createObjectPool(StringBuilder.class, DEFAULT_POOL_SIZE);
|
|
createObjectPool(String.class, DEFAULT_POOL_SIZE);
|
|
|
|
Log.i(TAG, "Object pools initialized");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error initializing object pools", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create object pool for a class
|
|
*
|
|
* @param clazz Class to create pool for
|
|
* @param initialSize Initial pool size
|
|
*/
|
|
private <T> void createObjectPool(Class<T> clazz, int initialSize) {
|
|
try {
|
|
ObjectPool<T> pool = new ObjectPool<>(clazz, initialSize);
|
|
objectPools.put(clazz, pool);
|
|
|
|
Log.d(TAG, "Object pool created for " + clazz.getSimpleName() + " with size " + initialSize);
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error creating object pool for " + clazz.getSimpleName(), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get object from pool
|
|
*
|
|
* @param clazz Class of object to get
|
|
* @return Object from pool or new instance
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public <T> T getObject(Class<T> clazz) {
|
|
try {
|
|
ObjectPool<T> pool = (ObjectPool<T>) objectPools.get(clazz);
|
|
if (pool != null) {
|
|
return pool.getObject();
|
|
}
|
|
|
|
// Create new instance if no pool exists
|
|
return clazz.newInstance();
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error getting object from pool", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return object to pool
|
|
*
|
|
* @param clazz Class of object
|
|
* @param object Object to return
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public <T> void returnObject(Class<T> clazz, T object) {
|
|
try {
|
|
ObjectPool<T> pool = (ObjectPool<T>) objectPools.get(clazz);
|
|
if (pool != null) {
|
|
pool.returnObject(object);
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error returning object to pool", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Optimize object pools
|
|
*/
|
|
private void optimizeObjectPools() {
|
|
try {
|
|
Log.d(TAG, "Optimizing object pools");
|
|
|
|
for (ObjectPool<?> pool : objectPools.values()) {
|
|
pool.optimize();
|
|
}
|
|
|
|
Log.i(TAG, "Object pools optimized");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing object pools", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clean up object pools
|
|
*/
|
|
private void cleanupObjectPools() {
|
|
try {
|
|
Log.d(TAG, "Cleaning up object pools");
|
|
|
|
for (ObjectPool<?> pool : objectPools.values()) {
|
|
pool.cleanup();
|
|
}
|
|
|
|
Log.i(TAG, "Object pools cleaned up");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error cleaning up object pools", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear object pools
|
|
*/
|
|
private void clearObjectPools() {
|
|
try {
|
|
Log.d(TAG, "Clearing object pools");
|
|
|
|
for (ObjectPool<?> pool : objectPools.values()) {
|
|
pool.clear();
|
|
}
|
|
|
|
Log.i(TAG, "Object pools cleared");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error clearing object pools", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Battery Optimization
|
|
|
|
/**
|
|
* Optimize battery usage
|
|
*/
|
|
public void optimizeBattery() {
|
|
try {
|
|
Log.d(TAG, "Optimizing battery usage");
|
|
|
|
// Minimize background CPU usage
|
|
minimizeBackgroundCPUUsage();
|
|
|
|
// Optimize network requests
|
|
optimizeNetworkRequests();
|
|
|
|
// Track battery usage
|
|
trackBatteryUsage();
|
|
|
|
Log.i(TAG, "Battery optimization completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing battery", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Minimize background CPU usage
|
|
*/
|
|
private void minimizeBackgroundCPUUsage() {
|
|
try {
|
|
Log.d(TAG, "Minimizing background CPU usage");
|
|
|
|
// Reduce scheduler thread pool size
|
|
// This would be implemented based on system load
|
|
|
|
// Optimize background task frequency
|
|
// This would adjust task intervals based on battery level
|
|
|
|
Log.i(TAG, "Background CPU usage minimized");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error minimizing background CPU usage", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Optimize network requests
|
|
*/
|
|
private void optimizeNetworkRequests() {
|
|
try {
|
|
Log.d(TAG, "Optimizing network requests");
|
|
|
|
// Batch network requests when possible
|
|
// Reduce request frequency during low battery
|
|
// Use efficient data formats
|
|
|
|
Log.i(TAG, "Network requests optimized");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error optimizing network requests", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Track battery usage
|
|
*/
|
|
private void trackBatteryUsage() {
|
|
try {
|
|
Log.d(TAG, "Tracking battery usage");
|
|
|
|
// This would integrate with battery monitoring APIs
|
|
// Track battery consumption patterns
|
|
// Adjust behavior based on battery level
|
|
|
|
Log.i(TAG, "Battery usage tracking completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error tracking battery usage", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Performance Monitoring
|
|
|
|
/**
|
|
* Start performance monitoring
|
|
*/
|
|
private void startPerformanceMonitoring() {
|
|
try {
|
|
Log.d(TAG, "Starting performance monitoring");
|
|
|
|
// Schedule memory monitoring
|
|
scheduler.scheduleAtFixedRate(this::checkMemoryUsage, 0, MEMORY_CHECK_INTERVAL_MS, TimeUnit.MILLISECONDS);
|
|
|
|
// Schedule battery monitoring
|
|
scheduler.scheduleAtFixedRate(this::checkBatteryUsage, 0, BATTERY_CHECK_INTERVAL_MS, TimeUnit.MILLISECONDS);
|
|
|
|
// Schedule performance reporting
|
|
scheduler.scheduleAtFixedRate(this::reportPerformance, 0, PERFORMANCE_REPORT_INTERVAL_MS, TimeUnit.MILLISECONDS);
|
|
|
|
Log.i(TAG, "Performance monitoring started");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error starting performance monitoring", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check memory usage
|
|
*/
|
|
private void checkMemoryUsage() {
|
|
try {
|
|
long currentTime = System.currentTimeMillis();
|
|
if (currentTime - lastMemoryCheck.get() < MEMORY_CHECK_INTERVAL_MS) {
|
|
return;
|
|
}
|
|
|
|
lastMemoryCheck.set(currentTime);
|
|
|
|
long memoryUsage = getCurrentMemoryUsage();
|
|
metrics.recordMemoryUsage(memoryUsage);
|
|
|
|
if (memoryUsage > MEMORY_WARNING_THRESHOLD_MB) {
|
|
Log.w(TAG, "High memory usage detected: " + memoryUsage + "MB");
|
|
optimizeMemory();
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error checking memory usage", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check battery usage
|
|
*/
|
|
private void checkBatteryUsage() {
|
|
try {
|
|
long currentTime = System.currentTimeMillis();
|
|
if (currentTime - lastBatteryCheck.get() < BATTERY_CHECK_INTERVAL_MS) {
|
|
return;
|
|
}
|
|
|
|
lastBatteryCheck.set(currentTime);
|
|
|
|
// This would check actual battery usage
|
|
// For now, we'll just log the check
|
|
Log.d(TAG, "Battery usage check performed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error checking battery usage", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Report performance metrics
|
|
*/
|
|
private void reportPerformance() {
|
|
try {
|
|
Log.i(TAG, "Performance Report:");
|
|
Log.i(TAG, " Memory Usage: " + metrics.getAverageMemoryUsage() + "MB");
|
|
Log.i(TAG, " Database Queries: " + metrics.getTotalDatabaseQueries());
|
|
Log.i(TAG, " Object Pool Hits: " + metrics.getObjectPoolHits());
|
|
Log.i(TAG, " Performance Score: " + metrics.getPerformanceScore());
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error reporting performance", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Utility Methods
|
|
|
|
/**
|
|
* Clear caches
|
|
*/
|
|
private void clearCaches() {
|
|
try {
|
|
Log.d(TAG, "Clearing caches");
|
|
|
|
// Clear database caches
|
|
database.execSQL("PRAGMA cache_size=0");
|
|
database.execSQL("PRAGMA cache_size=1000");
|
|
|
|
Log.i(TAG, "Caches cleared");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error clearing caches", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear old caches
|
|
*/
|
|
private void clearOldCaches() {
|
|
try {
|
|
Log.d(TAG, "Clearing old caches");
|
|
|
|
// This would clear old cache entries
|
|
// For now, we'll just log the action
|
|
|
|
Log.i(TAG, "Old caches cleared");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error clearing old caches", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Public API
|
|
|
|
/**
|
|
* Get performance metrics
|
|
*
|
|
* @return PerformanceMetrics with current statistics
|
|
*/
|
|
public PerformanceMetrics getMetrics() {
|
|
return metrics;
|
|
}
|
|
|
|
/**
|
|
* Reset performance metrics
|
|
*/
|
|
public void resetMetrics() {
|
|
metrics.reset();
|
|
Log.d(TAG, "Performance metrics reset");
|
|
}
|
|
|
|
/**
|
|
* Shutdown optimizer
|
|
*/
|
|
public void shutdown() {
|
|
try {
|
|
Log.d(TAG, "Shutting down performance optimizer");
|
|
|
|
scheduler.shutdown();
|
|
clearObjectPools();
|
|
|
|
Log.i(TAG, "Performance optimizer shutdown completed");
|
|
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error shutting down performance optimizer", e);
|
|
}
|
|
}
|
|
|
|
// MARK: - Data Classes
|
|
|
|
/**
|
|
* Object pool for managing object reuse
|
|
*/
|
|
private static class ObjectPool<T> {
|
|
private final Class<T> clazz;
|
|
private final java.util.Queue<T> pool;
|
|
private final int maxSize;
|
|
private int currentSize;
|
|
|
|
public ObjectPool(Class<T> clazz, int maxSize) {
|
|
this.clazz = clazz;
|
|
this.pool = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
|
this.maxSize = maxSize;
|
|
this.currentSize = 0;
|
|
}
|
|
|
|
public T getObject() {
|
|
T object = pool.poll();
|
|
if (object == null) {
|
|
try {
|
|
object = clazz.newInstance();
|
|
} catch (Exception e) {
|
|
Log.e(TAG, "Error creating new object", e);
|
|
return null;
|
|
}
|
|
} else {
|
|
currentSize--;
|
|
}
|
|
return object;
|
|
}
|
|
|
|
public void returnObject(T object) {
|
|
if (currentSize < maxSize) {
|
|
pool.offer(object);
|
|
currentSize++;
|
|
}
|
|
}
|
|
|
|
public void optimize() {
|
|
// Remove excess objects
|
|
while (currentSize > maxSize / 2) {
|
|
T object = pool.poll();
|
|
if (object != null) {
|
|
currentSize--;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void cleanup() {
|
|
pool.clear();
|
|
currentSize = 0;
|
|
}
|
|
|
|
public void clear() {
|
|
pool.clear();
|
|
currentSize = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Performance metrics
|
|
*/
|
|
public static class PerformanceMetrics {
|
|
private final AtomicLong totalMemoryUsage = new AtomicLong(0);
|
|
private final AtomicLong memoryCheckCount = new AtomicLong(0);
|
|
private final AtomicLong totalDatabaseQueries = new AtomicLong(0);
|
|
private final AtomicLong objectPoolHits = new AtomicLong(0);
|
|
private final AtomicLong performanceScore = new AtomicLong(100);
|
|
|
|
public void recordMemoryUsage(long usage) {
|
|
totalMemoryUsage.addAndGet(usage);
|
|
memoryCheckCount.incrementAndGet();
|
|
}
|
|
|
|
public void recordDatabaseQuery() {
|
|
totalDatabaseQueries.incrementAndGet();
|
|
}
|
|
|
|
public void recordObjectPoolHit() {
|
|
objectPoolHits.incrementAndGet();
|
|
}
|
|
|
|
public void updatePerformanceScore(long score) {
|
|
performanceScore.set(score);
|
|
}
|
|
|
|
public void recordDatabaseStats(long pageCount, long pageSize, long cacheSize) {
|
|
// Update performance score based on database stats
|
|
long score = Math.min(100, Math.max(0, 100 - (pageCount / 1000)));
|
|
updatePerformanceScore(score);
|
|
}
|
|
|
|
public void reset() {
|
|
totalMemoryUsage.set(0);
|
|
memoryCheckCount.set(0);
|
|
totalDatabaseQueries.set(0);
|
|
objectPoolHits.set(0);
|
|
performanceScore.set(100);
|
|
}
|
|
|
|
public long getAverageMemoryUsage() {
|
|
long count = memoryCheckCount.get();
|
|
return count > 0 ? totalMemoryUsage.get() / count : 0;
|
|
}
|
|
|
|
public long getTotalDatabaseQueries() {
|
|
return totalDatabaseQueries.get();
|
|
}
|
|
|
|
public long getObjectPoolHits() {
|
|
return objectPoolHits.get();
|
|
}
|
|
|
|
public long getPerformanceScore() {
|
|
return performanceScore.get();
|
|
}
|
|
}
|
|
}
|
|
|