{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "71f85f2a-423f-44d2-b80d-da9ac8d3961a", "metadata": {}, "outputs": [], "source": [ "import simpy\n", "import random\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "from enum import Enum\n", "import os\n", "import shutil\n", "from tqdm import tqdm\n", "import math\n", "\n", "# Types of cache\n", "class CacheType(Enum):\n", " LRU = 1\n", " RANDOM_EVICTION = 2\n", " TTL = 3\n", "\n", "# Constants\n", "SEED = 42\n", "ACCESS_COUNT_LIMIT = 10 # Total time to run the simulation\n", "EXPERIMENT_BASE_DIR = \"./experiments/\"\n", "TEMP_BASE_DIR = \"./.aoi_cache/\"\n", "\n", "ZIPF_CONSTANT = 2 # Shape parameter for the Zipf distribution (controls skewness) Needs to be: 1< \n", "\n", "# Set random seeds\n", "random.seed(SEED)\n", "np.random.seed(SEED)\n", "\n", "os.makedirs(TEMP_BASE_DIR, exist_ok=True)" ] }, { "cell_type": "markdown", "id": "9a37d7a3-3e11-4b89-8dce-6091dd38b16f", "metadata": {}, "source": [ "How to set certain parameters for specific scenarios\n", "\n", "\n", "| Name | Cache Capacity | MAX_REFRESH_RATE | cache_type | CACHE_TTL |\n", "| -------------------- | -------------------- | ---------------- | ------------------------- | --------- |\n", "| Default | DATABASE_OBJECTS | 1< | CacheType.LRU | 5 |\n", "| No Refresh | DATABASE_OBJECTS | 0 | CacheType.LRU | 5 |\n", "| Infinite TTL | DATABASE_OBJECTS / 2 | 0 | CacheType.LRU | 0 |\n", "| Random Eviction (RE) | DATABASE_OBJECTS / 2 | 1< | CacheType.RANDOM_EVICTION | 5 |\n", "| RE without Refresh | DATABASE_OBJECTS / 2 | 0 | CacheType.RANDOM_EVICTION | 5 |\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "3d0ab5b1-162a-42c8-80a3-d31f763101f1", "metadata": {}, "outputs": [], "source": [ "# Configuration (Just example, will be overwritten in next block\n", "DATABASE_OBJECTS = 100\n", "CACHE_CAPACITY = DATABASE_OBJECTS # Maximum number of objects the cache can hold\n", "\n", "# MAX_REFRESH_RATE is used as the maximum for a uniform\n", "# distribution for mu.\n", "# If MAX_REFRESH_RATE is 0, we do not do any refreshes.\n", "MAX_REFRESH_RATE = 0\n", "\n", "cache_type = CacheType.LRU\n", "\n", "# CACHE_TTL is used to determin which TTL to set when an\n", "# object is pulled into the cache\n", "# If CACHE_TTL is set to 0, the TTL is infinite\n", "CACHE_TTL = 5\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "3ff299ca-ec65-453b-b167-9a0f7728a207", "metadata": {}, "outputs": [], "source": [ "configurations = {\n", " \"default\": (100, 100, 10, CacheType.LRU, 5),\n", " \"No Refresh\": (100, 100, 0, CacheType.LRU, 5),\n", " \"Infinite TTL\": (100, 50, 0, CacheType.LRU, 0),\n", " \"Random Eviction\": (100, 50, 10, CacheType.RANDOM_EVICTION, 5),\n", " \"RE without Refresh\": (100, 50, 0, CacheType.RANDOM_EVICTION, 5),\n", " \"No Refresh (0.5s ttl)\": (100, 100, 0, CacheType.TTL, 0.5),\n", " \"No Refresh (1.0s ttl)\": (100, 100, 0, CacheType.TTL, 1),\n", " \"No Refresh (2.0s ttl)\": (100, 100, 0, CacheType.TTL, 2),\n", " \"No Refresh (3.0s ttl)\": (100, 100, 0, CacheType.TTL, 3),\n", " \"No Refresh (4.0s ttl)\": (100, 100, 0, CacheType.TTL, 4),\n", " \"No Refresh (5.0s ttl)\": (100, 100, 0, CacheType.TTL, 5),\n", " \"No Refresh (tests ttl)\": (3, 3, 0, CacheType.TTL, 1),\n", "}\n", "\n", "experiment_name = \"No Refresh (tests ttl)\"\n", "config = configurations[experiment_name]\n", "\n", "DATABASE_OBJECTS = config[0]\n", "CACHE_CAPACITY = config[1]\n", "MAX_REFRESH_RATE = config[2]\n", "cache_type = config[3]\n", "CACHE_TTL = config[4]\n", "\n", "if cache_type == CacheType.TTL:\n", " assert CACHE_TTL > 0, \"Needs CACHE_TTL to be greater than 0 when using TTL-Cache.\"\n", " assert CACHE_CAPACITY >= DATABASE_OBJECTS, \"Cache Size needs to be greater or equal to the amount of Database Objects.\"" ] }, { "cell_type": "code", "execution_count": 4, "id": "5cea042f-e9fc-4a1e-9750-de212ca70601", "metadata": {}, "outputs": [], "source": [ "class Database:\n", " def __init__(self):\n", " # Each object now has a specific refresh rate 'mu'\n", " self.data = {i: f\"Object {i}\" for i in range(1, DATABASE_OBJECTS + 1)}\n", " self.lambda_values = {i: np.random.zipf(ZIPF_CONSTANT) for i in range(1, DATABASE_OBJECTS + 1)} # Request rate 'lambda' for each object\n", " # Refresh rate 'mu' for each object\n", " if MAX_REFRESH_RATE == 0:\n", " self.mu_values = {i: 0 for i in range(1,DATABASE_OBJECTS + 1)} \n", " else:\n", " self.mu_values = {i: np.random.uniform(1, MAX_REFRESH_RATE) for i in range(1, DATABASE_OBJECTS + 1)}\n", " self.next_request = {i: np.random.exponential(1/self.lambda_values[i]) for i in range(1, DATABASE_OBJECTS + 1)}\n", "\n", "\n", " def get_object(self, obj_id):\n", " # print(f\"[{env.now:.2f}] Database: Fetched {self.data.get(obj_id, 'Unknown')} for ID {obj_id}\")\n", " return self.data.get(obj_id, None)" ] }, { "cell_type": "code", "execution_count": 5, "id": "499bf543-b2c6-4e4d-afcc-0a6665ce3ae1", "metadata": {}, "outputs": [], "source": [ "class Cache:\n", " def __init__(self, env, db, cache_type):\n", " self.cache_type = cache_type\n", " self.env = env\n", " self.db = db\n", " self.storage = {} # Dictionary to store cached objects\n", " self.ttl = {} # Dictionary to store TTLs\n", " self.initial_fetch = {} # Dictionary to store when an object was fetched from the databse to determine the age\n", " self.cache_size_over_time = [] # To record cache state at each interval\n", " self.cache_next_request_over_time = []\n", " self.request_log = {i: [] for i in range(1, DATABASE_OBJECTS + 1)}\n", " self.hits = {i: 0 for i in range(1, DATABASE_OBJECTS + 1)} # Track hits per object\n", " self.misses = {i: 0 for i in range(1, DATABASE_OBJECTS + 1)} # Track misses per object\n", " self.cumulative_age = {i: [] for i in range(1, DATABASE_OBJECTS + 1)} # Track cumulative age per object\n", " self.access_count = {i: 0 for i in range(1, DATABASE_OBJECTS + 1)} # Track access count per object\n", " self.next_refresh = {} # Track the next refresh time for each cached object\n", " self.object_start_time = {} # Used as helper variable to determine the starting time of an object in the cache\n", " self.cumulative_cache_time = {i: 0 for i in range(1, DATABASE_OBJECTS + 1)} # Stores the cumulative time the object has spent between its eviction and when it was first pulled into the cache\n", " \n", " def get(self, obj_id):\n", " if obj_id in self.storage:\n", " # Cache hit: Refresh TTL if TTL-Cache\n", " if self.cache_type == CacheType.TTL:\n", " if self.ttl[obj_id] > env.now:\n", " self.ttl[obj_id] = env.now + CACHE_TTL\n", " \n", " # Cache hit: increment hit count and update cumulative age\n", " self.hits[obj_id] += 1\n", " self.access_count[obj_id] += 1\n", "\n", " age = env.now - self.initial_fetch[obj_id]\n", " self.cumulative_age[obj_id].append(age)\n", "\n", " assert len(self.cumulative_age[obj_id]) == self.access_count[obj_id], \"Age values collected and object access count do not match.\"\n", "\n", " print(f\"[{env.now:.2f}] {obj_id} Hit: Current Age {age:.2f} (Average: {sum(self.cumulative_age[obj_id])/len(self.cumulative_age[obj_id]):.2f}) \")\n", " # Cache hit: Refresh database object on hit\n", " # self.initial_fetch[obj_id] = env.now\n", " else:\n", " assert obj_id not in self.storage.keys(), \"Found object in cache on miss. It should've been deleted.\"\n", " assert obj_id not in self.initial_fetch.keys(), \"Found age timer on miss. It should've been deleted.\"\n", " assert obj_id not in self.object_start_time.keys(), \"Found cache time ratio timer on miss. It should've been deleted.\"\n", " # Cache miss: Add TTL if TTL-Cache\n", " # When full cache: If non-TTL-Cache: Evict. If TTL-Cache: Don't add to Cache.\n", " if self.cache_type == CacheType.TTL:\n", " assert obj_id not in self.ttl.keys(), \"Found cache time ratio timer on miss. It should've been deleted.\"\n", " self.ttl[obj_id] = env.now + CACHE_TTL\n", " else:\n", " if len(self.storage) == DATABASE_OBJECTS:\n", " if self.cache_type == CacheType.LRU:\n", " self.evict_oldest()\n", " elif self.cache_type == CacheType.RANDOM_EVICTION:\n", " self.evict_random()\n", " elif self.cache_type == CacheType.TTL:\n", " return\n", " \n", " # Cache miss: increment miss count\n", " self.misses[obj_id] += 1\n", " self.access_count[obj_id] += 1\n", " \n", " # Cache miss: Fetch the object from the database\n", " self.storage[obj_id] = self.db.get_object(obj_id)\n", " self.object_start_time[obj_id] = env.now\n", " \n", " self.initial_fetch[obj_id] = env.now\n", " age = env.now - self.initial_fetch[obj_id]\n", " assert age == 0, \"Initial age at miss is not 0\"\n", " self.cumulative_age[obj_id].append(age)\n", "\n", " assert len(self.cumulative_age[obj_id]) == self.access_count[obj_id], \"Age values collected and object access count do not match.\"\n", " \n", " print(f\"[{env.now:.2f}] {obj_id} Miss: Average Age {sum(self.cumulative_age[obj_id])/len(self.cumulative_age[obj_id]):.2f} \")\n", " \n", " if MAX_REFRESH_RATE != 0:\n", " self.next_refresh[obj_id] = env.now + np.random.exponential(1/self.db.mu_values[obj_id]) # Schedule refresh\n", " \n", " \n", " def evict_oldest(self):\n", " \"\"\"Remove the oldest item from the cache to make space.\"\"\"\n", " oldest_id = min(self.initial_fetch, key=self.initial_fetch.get) # Find the oldest item by age\n", " print(f\"[{env.now:.2f}] Cache: Evicting oldest object {oldest_id} to make space at {self.ttl[oldest_id]:.2f}\")\n", " self.cumulative_cache_time[obj_id] += (env.now - self.object_start_time[obj_id])\n", " del self.storage[oldest_id]\n", " del self.initial_fetch[oldest_id]\n", " del self.object_start_time[obj_id]\n", "\n", " def evict_random(self):\n", " \"\"\"Remove a random item from the cache to make space.\"\"\"\n", " random_id = np.random.choice(list(self.storage.keys())) # Select a random key from the cache\n", " print(f\"[{env.now:.2f}] Cache: Evicting random object {random_id} to make space at {self.ttl[random_id]:.2f}\")\n", " self.cumulative_cache_time[obj_id] += (env.now - self.object_start_time[obj_id])\n", " del self.storage[random_id]\n", " del self.initial_fetch[random_id]\n", " del self.object_start_time[obj_id]\n", " \n", " def refresh_object(self, obj_id):\n", " \"\"\"Refresh the object from the database to keep it up-to-date. TTL is increased on refresh.\"\"\"\n", " obj = self.db.get_object(obj_id)\n", " self.storage[obj_id] = obj\n", " if self.cache_type == CacheType.TTL:\n", " self.ttl[obj_id] = env.now + CACHE_TTL\n", " self.cumulative_cache_time[obj_id] += (env.now - self.object_start_time[obj_id])\n", " # print(f\"[{env.now:.2f}] Cache: Refreshed object {obj_id}\")\n", " \n", " def check_expired(self):\n", " \"\"\"Increment age of each cached object.\"\"\"\n", " evicted_objects = []\n", " for obj_id in list(self.ttl.keys()):\n", " if self.ttl[obj_id] <= env.now:\n", " # Remove object if its TTL expired\n", " print(f\"[{env.now:.2f}] Cache: Object {obj_id} expired\")\n", " evicted_objects.append(obj_id)\n", " self.cumulative_cache_time[obj_id] += (env.now - self.object_start_time[obj_id])\n", " del self.storage[obj_id]\n", " del self.ttl[obj_id]\n", " del self.initial_fetch[obj_id]\n", " del self.object_start_time[obj_id]\n", " return evicted_objects\n", "\n", " \n", " def record_cache_state(self):\n", " \"\"\"Record the current cache state (number of objects in cache) over time.\"\"\"\n", " self.cache_size_over_time.append((env.now, len(self.storage)))\n", " self.cache_next_request_over_time.append((env.now, self.db.next_request.copy()))" ] }, { "cell_type": "code", "execution_count": 6, "id": "7286d498-aa6c-4efb-bb28-fe29736eab64", "metadata": {}, "outputs": [], "source": [ "def age_cache_process(env, cache):\n", " \"\"\"Process that ages cache objects over time, removes expired items, and refreshes based on object-specific intervals.\"\"\"\n", " while True:\n", " if cache.cache_type == CacheType.TTL:\n", " if cache.storage:\n", " obj_id, next_eviction = min(cache.ttl.items(), key=lambda x: x[1])\n", " print(f\"[{env.now:.2f}] Waiting for next eviction...\")\n", " yield env.timeout(next_eviction - env.now) # Wait till next request (subject to change when object has been hit)\n", "\n", " \n", " if next_eviction == cache.ttl[obj_id]:\n", " print(f\"[{env.now:.2f}] Object {obj_id} needs to be evicted (At time: {next_eviction})\")\n", " evicted_objects = cache.check_expired()\n", " print(f\"[{env.now:.2f}] Evicted {len(evicted_objects)} object(s).\")\n", " assert len(evicted_objects) != 0, \"There was no object to evict.\"\n", " else:\n", " print(f\"[{env.now:.2f}] Object TTL was extended.\")\n", " evicted_objects = cache.check_expired()\n", " assert len(evicted_objects) == 0, \"There would've been an object to evict.\"\n", " continue\n", " else:\n", " obj_id, next_request = min(cache.db.next_request.items(), key=lambda x: x[1])\n", " print(f\"[{env.now:.2f}] Waiting for next request...\")\n", " yield env.timeout(next_request - env.now) # Wait till next request (subject to change when object has been hit)\n", " \n", " evicted_objects = cache.check_expired()\n", " assert len(evicted_objects) == 0, \"There would've been an object to evict.\"\n", " evicted_objects = cache.check_expired()\n", " assert len(evicted_objects) == 0, \"There would've been an object to evict.\"\n", " else:\n", " yield env.timeout(0.05) # Run every 0.05 second\n", " \n", " if MAX_REFRESH_RATE != 0:\n", " # Refresh objects based on their individual refresh intervals\n", " for obj_id in list(cache.storage.keys()):\n", " # Check if it's time to refresh this object based on next_refresh\n", " if env.now >= cache.next_refresh[obj_id]:\n", " cache.refresh_object(obj_id)\n", " # Schedule the next refresh based on the object's mu\n", " cache.next_refresh[obj_id] = env.now + np.random.exponential(1/cache.db.mu_values[obj_id])\n", " \n", " cache.record_cache_state() # Record cache state at each time step" ] }, { "cell_type": "code", "execution_count": 7, "id": "687f5634-8edf-4337-b42f-bbb292d47f0f", "metadata": {}, "outputs": [], "source": [ "def client_request_process(env, cache, event):\n", " \"\"\"Client process that makes requests for objects from the cache.\"\"\"\n", " last_print = 0\n", " with tqdm(total=ACCESS_COUNT_LIMIT, desc=\"Progress\", leave=True) as pbar:\n", " while True:\n", " obj_id, next_request = min(cache.db.next_request.items(), key=lambda x: x[1])\n", " yield env.timeout(next_request - env.now)\n", "\n", " # For progress bar\n", " if (int(env.now) % 1) == 0 and int(env.now) != last_print:\n", " last_print = int(env.now)\n", " pbar.n = min(cache.access_count.values())\n", " pbar.refresh()\n", " \n", " if env.now >= next_request:\n", " # print(f\"[{env.now:.2f}] Client: Requesting object {obj_id}\")\n", " cache.get(obj_id)\n", " \n", " # print(f\"[{env.now:.2f}] Client: Schedule next request for {obj_id}\")\n", " next_request = env.now + np.random.exponential(1/cache.db.lambda_values[obj_id])\n", " cache.request_log[obj_id].append(next_request)\n", " cache.db.next_request[obj_id] = next_request\n", " \n", " # Simulation stop condition\n", " if all(access_count >= ACCESS_COUNT_LIMIT for access_count in cache.access_count.values()):\n", " print(f\"Simulation ended after {env.now} seconds.\")\n", " for obj_id in cache.storage.keys():\n", " cache.cumulative_cache_time[obj_id] += (env.now - cache.object_start_time[obj_id])\n", " event.succeed()" ] }, { "cell_type": "code", "execution_count": 8, "id": "c8516830-9880-4d9e-a91b-000338baf9d6", "metadata": { "scrolled": true }, "outputs": [], "source": [ "# Initialize simulation environment\n", "env = simpy.Environment()\n", "\n", "# Instantiate components\n", "db = Database()\n", "cache = Cache(env, db, cache_type)\n", "stop_event = env.event()" ] }, { "cell_type": "code", "execution_count": 9, "id": "2ba34b36-9ed5-4996-9600-11dfd25d8e60", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.00] Waiting for next request...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Progress: 70%|████████████████████████████████████████████████████████████████▍ | 7/10 [00:00<00:00, 1560.05it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[0.06] Waiting for next request...\n", "[0.06] 1 Miss: Average Age 0.00 \n", "[0.06] Waiting for next eviction...\n", "[0.67] 2 Miss: Average Age 0.00 \n", "[0.68] 2 Hit: Current Age 0.01 (Average: 0.00) \n", "[0.92] 3 Miss: Average Age 0.00 \n", "[1.06] Object 1 needs to be evicted (At time: 1.0598387686086808)\n", "[1.06] Cache: Object 1 expired\n", "[1.06] Evicted 1 object(s).\n", "[1.06] Waiting for next eviction...\n", "[1.29] 1 Miss: Average Age 0.00 \n", "[1.53] 1 Hit: Current Age 0.24 (Average: 0.08) \n", "[1.68] Object 2 needs to be evicted (At time: 1.6773433908263593)\n", "[1.68] Cache: Object 2 expired\n", "[1.68] Evicted 1 object(s).\n", "[1.68] Waiting for next eviction...\n", "[1.73] 1 Hit: Current Age 0.44 (Average: 0.17) \n", "[1.85] 2 Miss: Average Age 0.00 \n", "[1.92] Object 3 needs to be evicted (At time: 1.9190821536272646)\n", "[1.92] Cache: Object 3 expired\n", "[1.92] Evicted 1 object(s).\n", "[1.92] Waiting for next eviction...\n", "[1.93] 1 Hit: Current Age 0.64 (Average: 0.26) \n", "[1.97] 2 Hit: Current Age 0.12 (Average: 0.03) \n", "[2.15] 2 Hit: Current Age 0.31 (Average: 0.09) \n", "[2.27] 2 Hit: Current Age 0.42 (Average: 0.14) \n", "[2.58] 2 Hit: Current Age 0.74 (Average: 0.23) \n", "[2.63] 2 Hit: Current Age 0.79 (Average: 0.30) \n", "[2.68] 1 Hit: Current Age 1.39 (Average: 0.45) \n", "[2.71] 3 Miss: Average Age 0.00 \n", "[2.73] Object TTL was extended.\n", "[2.73] Waiting for next eviction...\n", "[2.75] 2 Hit: Current Age 0.90 (Average: 0.37) \n", "[3.13] 1 Hit: Current Age 1.84 (Average: 0.65) \n", "[3.26] 2 Hit: Current Age 1.42 (Average: 0.47) \n", "[3.31] 3 Hit: Current Age 0.61 (Average: 0.20) \n", "[3.36] 1 Hit: Current Age 2.06 (Average: 0.83) \n", "[3.40] 1 Hit: Current Age 2.11 (Average: 0.97) \n", "[3.50] 2 Hit: Current Age 1.66 (Average: 0.58) \n", "[3.57] 2 Hit: Current Age 1.72 (Average: 0.67) \n", "[3.59] 2 Hit: Current Age 1.74 (Average: 0.76) \n", "[3.63] Object TTL was extended.\n", "[3.63] Waiting for next eviction...\n", "[4.21] 3 Hit: Current Age 1.51 (Average: 0.53) \n", "[4.31] Object TTL was extended.\n", "[4.31] Waiting for next eviction...\n", "[4.34] 1 Hit: Current Age 3.05 (Average: 1.18) \n", "[4.40] Object TTL was extended.\n", "[4.40] Waiting for next eviction...\n", "[4.58] 2 Hit: Current Age 2.73 (Average: 0.90) \n", "[4.59] Object TTL was extended.\n", "[4.59] Waiting for next eviction...\n", "[4.70] 2 Hit: Current Age 2.86 (Average: 1.03) \n", "[4.73] 2 Hit: Current Age 2.89 (Average: 1.14) \n", "[5.12] 2 Hit: Current Age 3.27 (Average: 1.27) \n", "[5.21] Object 3 needs to be evicted (At time: 5.211951106151475)\n", "[5.21] Cache: Object 3 expired\n", "[5.21] Evicted 1 object(s).\n", "[5.21] Waiting for next eviction...\n", "[5.31] 2 Hit: Current Age 3.47 (Average: 1.39) \n", "[5.34] Object 1 needs to be evicted (At time: 5.33890464876055)\n", "[5.34] Cache: Object 1 expired\n", "[5.34] Evicted 1 object(s).\n", "[5.34] Waiting for next eviction...\n", "[5.36] 2 Hit: Current Age 3.51 (Average: 1.50) \n", "[5.58] 2 Hit: Current Age 3.74 (Average: 1.62) \n", "[5.60] 2 Hit: Current Age 3.75 (Average: 1.72) \n", "[5.99] 1 Miss: Average Age 1.07 \n", "[6.29] 1 Hit: Current Age 0.30 (Average: 1.01) \n", "[6.31] Object TTL was extended.\n", "[6.31] Waiting for next eviction...\n", "[6.40] 2 Hit: Current Age 4.55 (Average: 1.85) \n", "[6.52] 2 Hit: Current Age 4.67 (Average: 1.97) \n", "[6.60] Object TTL was extended.\n", "[6.60] Waiting for next eviction...\n", "[6.76] 2 Hit: Current Age 4.92 (Average: 2.09) \n", "[7.03] 2 Hit: Current Age 5.18 (Average: 2.22) \n", "[7.10] 2 Hit: Current Age 5.25 (Average: 2.33) \n", "[7.29] Object 1 needs to be evicted (At time: 7.290693998414112)\n", "[7.29] Cache: Object 1 expired\n", "[7.29] Evicted 1 object(s).\n", "[7.29] Waiting for next eviction...\n", "[7.38] 1 Miss: Average Age 0.93 \n", "[7.58] 3 Miss: Average Age 0.42 \n", "[8.10] Object 2 needs to be evicted (At time: 8.096464406708787)\n", "[8.10] Cache: Object 2 expired\n", "[8.10] Evicted 1 object(s).\n", "[8.10] Waiting for next eviction...\n", "[8.26] 2 Miss: Average Age 2.25 \n", "[8.38] Object 1 needs to be evicted (At time: 8.376949796979092)\n", "[8.38] Cache: Object 1 expired\n", "[8.38] Evicted 1 object(s).\n", "[8.38] Waiting for next eviction...\n", "[8.58] Object 3 needs to be evicted (At time: 8.582581448612647)\n", "[8.58] Cache: Object 3 expired\n", "[8.58] Evicted 1 object(s).\n", "[8.58] Waiting for next eviction...\n", "[8.87] 1 Miss: Average Age 0.86 \n", "[9.01] 2 Hit: Current Age 0.75 (Average: 2.19) \n", "[9.26] Object TTL was extended.\n", "[9.26] Waiting for next eviction...\n", "[9.78] 1 Hit: Current Age 0.91 (Average: 0.87) \n", "[9.86] 2 Hit: Current Age 1.60 (Average: 2.17) \n", "[9.87] Object TTL was extended.\n", "[9.87] Waiting for next eviction...\n", "[9.87] 1 Hit: Current Age 1.00 (Average: 0.87) \n", "[9.92] 1 Hit: Current Age 1.05 (Average: 0.88) \n", "[9.93] 2 Hit: Current Age 1.67 (Average: 2.16) \n", "[10.10] 2 Hit: Current Age 1.84 (Average: 2.14) \n", "[10.20] 2 Hit: Current Age 1.94 (Average: 2.14) \n", "[10.31] 1 Hit: Current Age 1.44 (Average: 0.92) \n", "[10.39] 3 Miss: Average Age 0.35 \n", "[10.72] 3 Hit: Current Age 0.33 (Average: 0.35) \n", "[10.75] 1 Hit: Current Age 1.88 (Average: 0.97) \n", "[10.78] Object TTL was extended.\n", "[10.78] Waiting for next eviction...\n", "[10.79] 2 Hit: Current Age 2.53 (Average: 2.15) \n", "[10.91] 1 Hit: Current Age 2.04 (Average: 1.02) \n", "[10.98] 1 Hit: Current Age 2.11 (Average: 1.07) \n", "[11.20] Object TTL was extended.\n", "[11.20] Waiting for next eviction...\n", "[11.33] 2 Hit: Current Age 3.07 (Average: 2.18) \n", "[11.50] 3 Hit: Current Age 1.11 (Average: 0.44) \n", "[11.72] Object TTL was extended.\n", "[11.72] Waiting for next eviction...\n", "[11.72] 3 Hit: Current Age 1.33 (Average: 0.54) \n", "[11.73] 3 Hit: Current Age 1.34 (Average: 0.62) \n", "Simulation ended after 11.726962652128046 seconds.\n", "CPU times: user 9.22 ms, sys: 2.17 ms, total: 11.4 ms\n", "Wall time: 9.47 ms\n" ] } ], "source": [ "%%time\n", "\n", "# Start processes\n", "env.process(age_cache_process(env, cache))\n", "env.process(client_request_process(env, cache, stop_event))\n", "\n", "# Run the simulation\n", "env.run(until=stop_event)\n", "simulation_end_time = env.now" ] }, { "cell_type": "code", "execution_count": 10, "id": "3b6f7c1f-ea54-4496-bb9a-370cee2d2751", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Object 1: Hit Rate = 0.76, Expected Hit Rate = 0.63, Average Time spend in Cache: 0.87, Average Age = 1.07, Expected Age = 1.82\n", "Object 2: Hit Rate = 0.91, Expected Hit Rate = 0.95, Average Time spend in Cache: 0.91, Average Age = 2.18, Expected Age = 1.80\n", "Object 3: Hit Rate = 0.60, Expected Hit Rate = 0.63, Average Time spend in Cache: 0.50, Average Age = 0.62, Expected Age = 0.94\n" ] } ], "source": [ "statistics = []\n", "# Calculate and print hit rate and average age for each object\n", "for obj_id in range(1, DATABASE_OBJECTS + 1):\n", " if cache.access_count[obj_id] != 0:\n", " hit_rate = cache.hits[obj_id] / max(1, cache.access_count[obj_id]) # Avoid division by zero\n", " expected_hit_rate = 1-math.exp(-db.lambda_values[obj_id]*CACHE_TTL)\n", " avg_cache_time = cache.cumulative_cache_time[obj_id] / max(1, simulation_end_time) # Only average over hits\n", " avg_age = sum(cache.cumulative_age[obj_id]) / len(cache.cumulative_age[obj_id])\n", " expected_age = hit_rate / (db.lambda_values[obj_id] * (1 - pow(hit_rate,2)))\n", " print(f\"Object {obj_id}: Hit Rate = {hit_rate:.2f}, Expected Hit Rate = {expected_hit_rate:.2f}, Average Time spend in Cache: {avg_cache_time:.2f}, Average Age = {avg_age:.2f}, Expected Age = {expected_age:.2f}\")\n", " statistics.append({\"obj_id\": obj_id,\"hit_rate\": hit_rate, \"expected_hit_rate\": expected_hit_rate, \"avg_cache_time\":avg_cache_time, \"avg_age\": avg_age, \"expected_age\": expected_age})" ] }, { "cell_type": "code", "execution_count": 11, "id": "b2d18372-cdba-4151-ae32-5bf45466bf94", "metadata": {}, "outputs": [], "source": [ "stats = pd.DataFrame(statistics)\n", "stats.to_csv(f\"{TEMP_BASE_DIR}/hit_age.csv\",index=False)\n", "stats.drop(\"obj_id\", axis=1).describe().to_csv(f\"{TEMP_BASE_DIR}/overall_hit_age.csv\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "80971714-44f1-47db-9e89-85be7c885bde", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
access_counthitsmissesmulambdahit_rateexpected_hit_rateexpected_hit_rate_deltaavg_cache_timecache_time_deltaavg_ageexpected_ageage_deltaage_delta in %
121165010.7619050.6321210.1297840.870220-0.1083161.0722191.816216-0.743997-0.409641
234313030.9117650.950213-0.0384480.914511-0.0027462.1776191.8017090.3759100.208641
31064010.6000000.632121-0.0321210.4984860.1015140.6230420.937500-0.314458-0.335422
\n", "
" ], "text/plain": [ " access_count hits misses mu lambda hit_rate expected_hit_rate \\\n", "1 21 16 5 0 1 0.761905 0.632121 \n", "2 34 31 3 0 3 0.911765 0.950213 \n", "3 10 6 4 0 1 0.600000 0.632121 \n", "\n", " expected_hit_rate_delta avg_cache_time cache_time_delta avg_age \\\n", "1 0.129784 0.870220 -0.108316 1.072219 \n", "2 -0.038448 0.914511 -0.002746 2.177619 \n", "3 -0.032121 0.498486 0.101514 0.623042 \n", "\n", " expected_age age_delta age_delta in % \n", "1 1.816216 -0.743997 -0.409641 \n", "2 1.801709 0.375910 0.208641 \n", "3 0.937500 -0.314458 -0.335422 " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "access_count = pd.DataFrame.from_dict(cache.access_count, orient='index', columns=['access_count'])\n", "hits = pd.DataFrame.from_dict(cache.hits, orient='index', columns=['hits'])\n", "misses = pd.DataFrame.from_dict(cache.misses, orient='index', columns=['misses'])\n", "mu = pd.DataFrame.from_dict(db.mu_values, orient='index', columns=['mu'])\n", "lmbda = pd.DataFrame.from_dict(db.lambda_values, orient='index', columns=['lambda'])\n", "\n", "hit_rate = pd.DataFrame(stats['hit_rate'])\n", "hit_rate.index = range(1,DATABASE_OBJECTS + 1)\n", "expected_hit_rate = pd.DataFrame(stats['expected_hit_rate'])\n", "expected_hit_rate.index = range(1,DATABASE_OBJECTS + 1)\n", "expected_hit_rate_delta = pd.DataFrame((hit_rate.to_numpy()-expected_hit_rate.to_numpy()), columns=['expected_hit_rate_delta'])\n", "expected_hit_rate_delta.index = range(1,DATABASE_OBJECTS + 1)\n", "avg_cache_time = pd.DataFrame(stats['avg_cache_time'])\n", "avg_cache_time.index = range(1,DATABASE_OBJECTS + 1)\n", "cache_time_delta = pd.DataFrame((hit_rate.to_numpy()-avg_cache_time.to_numpy()), columns=['cache_time_delta'])\n", "cache_time_delta.index = range(1,DATABASE_OBJECTS + 1)\n", "\n", "avg_age = pd.DataFrame(stats['avg_age'])\n", "avg_age.index = range(1,DATABASE_OBJECTS + 1)\n", "expected_age = pd.DataFrame(stats['expected_age'])\n", "expected_age.index = range(1,DATABASE_OBJECTS + 1)\n", "age_delta = pd.DataFrame((avg_age.to_numpy()-expected_age.to_numpy()), columns=['age_delta'])\n", "age_delta.index = range(1,DATABASE_OBJECTS + 1)\n", "age_delta_p = pd.DataFrame(age_delta.to_numpy().T[0]/expected_age.to_numpy().T[0], columns=['age_delta in %'])\n", "age_delta_p.index = range(1,DATABASE_OBJECTS + 1)\n", "\n", "merged = access_count.merge(hits, left_index=True, right_index=True).merge(misses, left_index=True, right_index=True) \\\n", " .merge(mu, left_index=True, right_index=True).merge(lmbda, left_index=True, right_index=True) \\\n", " .merge(hit_rate, left_index=True, right_index=True).merge(expected_hit_rate, left_index=True, right_index=True).merge(expected_hit_rate_delta, left_index=True, right_index=True) \\\n", " .merge(avg_cache_time, left_index=True, right_index=True).merge(cache_time_delta, left_index=True, right_index=True) \\\n", " .merge(avg_age, left_index=True, right_index=True).merge(expected_age, left_index=True, right_index=True).merge(age_delta, left_index=True, right_index=True).merge(age_delta_p, left_index=True, right_index=True)\n", "merged.to_csv(f\"{TEMP_BASE_DIR}/details.csv\", index_label=\"obj_id\")\n", "merged" ] }, { "cell_type": "code", "execution_count": 13, "id": "01f8f9ee-c278-4a22-8562-ba02e77f5ddd", "metadata": {}, "outputs": [ { "data": { "image/png": "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OlWo+x4wYIAcDodef/11tW3bVq+++qqmTp2qHj16qHLlynrjjTdUp04dTZgwQWvXrs2z/WuvvaZffvlFTz31lMaMGaMVK1aoe/fuuQqWVq1apU6dOikxMVEvvvii/ve//+ncuXPq1q2btmzZkmefd911l1JTU/W///1PDzzwwEWznz59Wu3bt9eyZcs0cuRIvfbaa0pPT9ctt9yi77//XpLUqVOnnKnZevTooS+//DLPVG3/9tNPP0mSBg8efMH1zs7Ouvvuu3X27Nk8RWVz5szRe++9p1GjRmnixInas2ePunXrptOnT1/0+aTsczh48GDVrVtX77zzjsaNG6eVK1eqU6dOOnfuXM64FStWqFOnTvr77781duxYTZkyRV27dtXPP/8sSXrooYfUo0cPSco5zvPHumLFCg0aNEjlypXTG2+8oddff11dunTJcwwF0b9/fyUlJWny5Mnq37+/Zs+erUmTJl1ym/379ysiIkL9+vWTj4/PZZ8jMTFRn376qbp06aI33nhDL730kmJjY9WrVy/t3Lkz19jhw4dr3Lhxqlq1qt544w09/fTTcnd316ZNm3KNW7dunUaOHKmBAwfqzTffVHp6uu644w6dOXMmZ8zp06d13XXX6bffftPo0aM1bdo01alTR8OHD9fUqVMvmfnXX3+V3W6/6DUkZV9fWVlZOcVgAwYM0Nq1axUdHZ0n66lTpzRw4MCcZQ899JCeeOIJXX/99Zo2bZqGDRumr7/+Wr169crTYSwyMlKDBg1Sjx49NG3aNDVr1uyS2a/Go48+qv3792vSpEm65ZZbNHPmTD3//PPq27ev7Ha7/ve//6lDhw5666238rwGC3JMAAAAAACgBDAAAAAAAACKsVmzZhmSjD///NM4ePCg4ezsbIwZMyZnfefOnY2GDRvmPD58+LAhyZg1a1aefUkyXnzxxZzHL774oiHJePDBB3OWZWVlGVWqVDEsFovx+uuv5yw/e/as4eHhYQwZMiRn2erVqw1JRuXKlY3ExMSc5d9++60hyZg2bZphGIbhcDiMunXrGr169TIcDkfOuNTUVKNmzZpGjx498mQaNGhQvs7PuHHjDEnGH3/8kbMsKSnJqFmzplGjRg3DbrfnOv5Ro0Zddp/9+vUzJBlnz5696JhFixYZkoz33nvPMIz/P+8eHh7GiRMncsZt3rzZkGQ89thjeY7xvCNHjhhOTk7Ga6+9lus5du/ebTg7O+csz8rKMmrWrGlUr149T7Z/n9dRo0YZF/q119ixYw1fX18jKyvrsufgvy527dx///25xt12221G+fLlL7mvH374wZBkvPvuu/l67qysLCMjIyPXsrNnzxoVK1bM9fyrVq0yJOV6fZz37/MjyXB1dTUOHDiQs+yvv/4yJBnvv/9+zrLhw4cbISEhRlxcXK59DRw40PDz8zNSU1Mvmvn8dbljx46Ljtm+fbshyRg/frxhGIYRGRmZJ4NhGMbIkSMNb2/vnOf7448/DEnG119/nWvc0qVL8yyvXr26IclYunTpRXNcTMOGDY3OnTtfcF316tVzvRecf5/672u8Xbt2hsViMR5++OGcZeffY/6974IcEwAAAAAAKBnolAUAAAAAAEqMWrVq6b777tPMmTMVFRVVaPsdMWJEzp+dnJzUqlUrGYah4cOH5yz39/dXaGioDh06lGf7wYMH5+p4dOeddyokJERLliyRJO3cuVP79+/X3XffrTNnziguLk5xcXFKSUnRDTfcoLVr18rhcOTa58MPP5yv7EuWLFGbNm1yTXHo7e2tBx98UEeOHNHff/+dv5PwL0lJSZJ0yS5O59clJibmWt6vXz9Vrlw553GbNm3Utm3bnHNxIYsWLZLD4VD//v1zzk1cXJyCg4NVt27dnGn6duzYocOHD2vcuHHy9/fPtY9LTcd4nr+/v1JSUrRixYrLjs2v//49dezYUWfOnMlzXv7t/Lr8dMmSsq9JV1dXSdlT3MXHxysrK0utWrXS9u3bc8YtXLhQFotFL774Yp59/Pf8dO/eXbVr18553KRJE/n6+uZc34ZhaOHCherbt68Mw8j199KrVy8lJCTkeu7/upJrqF69emrWrJnmz5+fM8Zut+u7775T37595eHhIUlasGCB/Pz81KNHj1y5WrZsKW9v7zzTOtasWVO9evW6aI7CNHz48Fznum3btnneS86/x/z7vaSgxwQAAAAAAIo/Z7MDAAAAAAAAFMRzzz2nL7/8Uq+//rqmTZtWKPusVq1arsd+fn5yd3dXhQoV8iz/9/Ru59WtWzfXY4vFojp16ujIkSOSsqerk6QhQ4ZcNENCQoLKlSuX87hmzZr5yn706FG1bds2z/L69evnrG/UqFG+9nXe+WKZpKSkPMVP512s6Oa/50LKLrb59ttvL/p8+/fvl2EYF9xWklxcXCRJBw8elKQCH895I0eO1LfffqvevXurcuXK6tmzp/r3768bb7zxivYn5b12zv8dnj17Vr6+vhfc5vzy8+cwP7744gtNmTJFERERuaay+/d1cvDgQVWqVEkBAQEFzn0++9mzZyVJsbGxOnfunGbOnKmZM2decB8xMTEX3f+/r6GLudA1NGDAAD3zzDM6efKkKleurDVr1igmJkYDBgzIGbN//34lJCQoKCgoX7ny+1oqDBd6L5GkqlWr5ll+/lxLBT8mAAAAAABQ/FGUBQAAAAAASpRatWrp3nvv1cyZM/X000/nWX+xjkl2u/2i+3RycsrXMim7g1BBne+C9dZbb6lZs2YXHOPt7Z3r8fmuQGaoX7++Fi9erF27dqlTp04XHLNr1y5JUoMGDa76+RwOhywWi3799dcLnvf/npsrFRQUpJ07d2rZsmX69ddf9euvv2rWrFkaPHiwvvjiiyva55VcJ2FhYZKk3bt35+s5vvrqKw0dOlT9+vXTE088oaCgIDk5OWny5Mk5hWoFdbnc56/Ze++996LFhE2aNLno/s8XBe7ateui1/yFrqEBAwZo4sSJWrBggcaNG6dvv/1Wfn5+uQrnHA6HgoKC9PXXX19wv4GBgbkeX8vX0sXO64WW//saKegxAQAAAACA4o+iLAAAAAAAUOI899xz+uqrr/TGG2/kWXe+U9G5c+dyLT969GiR5TnfCes8wzB04MCBnKKV89PE+fr6qnv37oX63NWrV1dkZGSe5RERETnrC+rmm2/W5MmTNWfOnAsWZdntds2dO1flypXT9ddfn2vdf8+FJO3bt081atS46PPVrl1bhmGoZs2aqlev3iXHSdKePXsueR4vNZWhq6ur+vbtq759+8rhcGjkyJH6+OOP9fzzz6tOnToX3a4w1atXT6Ghofrhhx80bdq0yxadfffdd6pVq5YWLVqU69j+O01h7dq1tWzZMsXHx+erW9alBAYGysfHR3a7/Yqu2d69e8vJyUlffvmlBg8efMExc+bMkbOzc66Cq5o1a6pNmzaaP3++Ro8erUWLFqlfv35yc3PLGVO7dm399ttvuv76600tXixMpfGYAAAAAAAo66xmBwAAAAAAACio2rVr695779XHH3+s6OjoXOt8fX1VoUIFrV27NtfyGTNmFFmeOXPm5Jqm7bvvvlNUVJR69+4tSWrZsqVq166tt99+W8nJyXm2j42NveLn7tOnj7Zs2aKNGzfmLEtJSdHMmTNVo0aNK+pk1b59e3Xv3l2zZs3Szz//nGf9s88+q3379unJJ5/MU0CyePFinTx5Mufxli1btHnz5pxzcSG33367nJycNGnSpDwdpgzDyJkyskWLFqpZs6amTp2ap+ju39t5eXlJyluY99+pJ61Wa07hXEZGxkXzFYVJkybpzJkzGjFihLKysvKsX758ec65P99l6d/HuHnz5lx/55J0xx13yDAMTZo0Kc/+CtrhzcnJSXfccYcWLlyoPXv25Fl/uWu2atWqGjZsmH777Td9+OGHedZ/9NFHWrVqlYYPH64qVarkWjdgwABt2rRJn3/+ueLi4nJNXShJ/fv3l91u1yuvvJJnv1lZWXn+3kuC0nhMAAAAAACUdXTKAgAAAAAAJdKzzz6rL7/8UpGRkWrYsGGudSNGjNDrr7+uESNGqFWrVlq7dq327dtXZFkCAgLUoUMHDRs2TKdPn9bUqVNVp04dPfDAA5Kyi38+/fRT9e7dWw0bNtSwYcNUuXJlnTx5UqtXr5avr69++umnK3rup59+Wt9884169+6tMWPGKCAgQF988YUOHz6shQsXymq9su/kzZkzRzfccINuvfVW3X333erYsaMyMjK0aNEirVmzRgMGDNATTzyRZ7s6deqoQ4cOeuSRR5SRkaGpU6eqfPnyevLJJy/6XLVr19arr76qiRMn6siRI+rXr598fHx0+PBhff/993rwwQc1YcIEWa1Wffjhh+rbt6+aNWumYcOGKSQkRBEREdq7d6+WLVsmKbsITpLGjBmjXr16ycnJSQMHDtSIESMUHx+vbt26qUqVKjp69Kjef/99NWvWLGe6vWtlwIAB2r17t1577TXt2LFDgwYNUvXq1XXmzBktXbpUK1eu1Ny5cyVldy5btGiRbrvtNt100006fPiwPvroIzVo0CBXkV/Xrl1133336b333tP+/ft14403yuFw6I8//lDXrl01evToAmV8/fXXtXr1arVt21YPPPCAGjRooPj4eG3fvl2//fab4uPjL7n9u+++q4iICI0cOVJLly7N6Yi1bNky/fDDD+rcubOmTJmSZ7v+/ftrwoQJmjBhggICAvJ06urcubMeeughTZ48WTt37lTPnj3l4uKi/fv3a8GC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urq61NTUtBqrqalJfX193nzzzbz66qtpbGzc4Jxly5ZtdN0pU6bk4osvXm/8vvvuy3bbbVea8GzS7Nmzi5q/+JVCnltZme07NOfz+zamb8NT+a/7ntpC6QCADSl2/wYAys/+DbBxqxuSjhWVeauhKU8sX1XuOPD/FPLimtXlDgGw1VVXNGfMvo3Zfvljueeex8odB4rm799sjn22r8jitypywz2/zcd6N5U7DhuxZs2aNs8tupR1/vnn5/777891112X008/PdOnT89f//rXfO9738sVV1xR7HIfCBMnTkxtbW3L6/r6+vTu3TsjR47conf+4p0G4ezZs3P88cenqqrtz4AuLK3LD59ckgP32DnnjD5kCyYEAP7e5u7fAED52L8B2uawj76ZP7/S9n9ghy3p7bffzqKFizJ4yOB06PC+HnwC0O7s17NLdtm+Y7ljQNH8/Zv3Y48Br2fV2rczdM9u6dihotxx2Ih3n77XFkX/FP/zn/88N998c44++uiMGTMmRx55ZPr27Zs999wzt9xySz772c8Wu2Sb9ezZM8uXL281tnz58nTt2jWdO3dOZWVlKisrNzinZ8+eG123uro61dXV641XVVX5g3IrKfa9rqx857duoVDwNQKAMvGzEgC0P/ZvgE3ba9eq7LWr/1GXD4aGhoasfqY5H923xv4NAO2Mv3+zOYb06V7uCLRBMd/bRVfrVq5cmb333jtJ0rVr16xcuTJJcsQRR+SBBx4odrmiDB8+PHPmzGk1Nnv27AwfPjxJ0rFjxwwZMqTVnKampsyZM6dlDgAAAAAAAAAAwJZUdClr7733zrPPPpsk2W+//XLHHXckeecOWjvttFNRa61atSqLFy/O4sWLkyTPPvtsFi9enOeffz7JO48VPOOMM1rm/8u//Ev+9Kc/5YILLsiyZcvy3e9+N3fccUfOO++8ljm1tbW5/vrrc9NNN+Xxxx/PV77ylaxevTpjxowp9lIBAAAAAAAAAACKVvTjC8eMGZPHHnssH/3oRzNhwoScdNJJufbaa9PQ0JCpU6cWtdYjjzySY445puV1bW1tkuTMM8/MjTfemBdffLGloJUkffr0yS9+8Yucd955+c53vpM99tgjP/jBDzJq1KiWOaeddlpeeumlTJo0KXV1dRk0aFBmzZqVmpqaYi8VAAAAAAAAAACgaEWXsv72rlQjRozI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iRNTW1vb8rq+vj69e/fOyJEj3/MN5P1paGjI7Nmzc/zxx6eqqqrN5xWW1uXGJ5dk5513zsc+dsgWTAgA/L3N3b8BgPKxfwNA+2P/BoD2x/4N2753n77XFkWXsl555ZV8+tOfzv33359CoZCnnnoqe++9d77whS+kW7duueqqq9q8Vvfu3VNZWZnly5e3Gl++fHl69uy5yXNXr16d2267LZdccsl7fp6999473bt3z9NPP73BUlZ1dXWqq6vXG6+qqvIH5VZS7HtdWfnOb91CoeBrBABl4mclAGh/7N8A0P7YvwGg/bF/w7armO/timIXP++881JVVZXnn3++1aP9TjvttMyaNauotTp27JghQ4Zkzpw5LWNNTU2ZM2dOq8cZbsiPf/zjrF27Np/73Ofe8/P85S9/ySuvvJLddtutqHwAAAAAAAAAAADFKvpOWffdd1/uvffe7LHHHq3G+/Xrl+eee67oALW1tTnzzDMzdOjQHHrooZk2bVpWr16dMWPGJEnOOOOM7L777pkyZUqr82644Yaccsop2WWXXVqNr1q1KhdffHH+6Z/+KT179swzzzyTCy64IH379s2oUaOKzgcAAAAAAAAAAFCMoktZq1evbnWHrHetXLlyg48AfC+nnXZaXnrppUyaNCl1dXUZNGhQZs2alZqamiTJ888/n4qK1jf0euKJJ/Lggw/mvvvuW2+9ysrKLFmyJDfddFNee+219OrVKyNHjsyll166WfkAAAAAAAAAAACKUXQp68gjj8zNN9+cSy+9NElSKBTS1NSUK6+8Msccc8xmhRg3blzGjRu3wWNz585db2zfffdNc3PzBud37tw5995772blAAAAAAAAAAAAeL+KLmVdeeWVOe644/LII49k3bp1ueCCC/KHP/whK1euzEMPPbQlMgIAAAAAAAAAALQbFe89pbWDDjooTz75ZI444oicfPLJWb16dT75yU/m0UcfzT777LMlMgIAAAAAAAAAALQbRd8pK0l23HHH/Pu//3upswAAAAAAAAAAALR7m1XKevXVV3PDDTfk8ccfT5IccMABGTNmTHbeeeeShgMAAAAAAAAAAGhvin584QMPPJC99torV199dV599dW8+uqrufrqq9OnT5888MADWyIjAAAAAAAAAABAu1H0nbLOPvvsnHbaabnuuutSWVmZJGlsbMy//uu/5uyz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p7a2NpMnT86iRYsycODAjBo1KitWrNjg/Llz5+Yzn/lM7r///sybNy+9e/fOyJEj89e//rXVvBNOOCEvvvhiy8ett966NS4HAAAAAAAAAAD4kOtQ7gBTp07N2LFjM2bMmCTJjBkz8otf/CIzZ87MhAkT1pt/yy23tHr9gx/8ID/96U8zZ86cnHHGGS3j1dXV6dmzZ5syrF27NmvXrm15XV9fnyRpaGhIQ0ND0ddE2737/hb7Pjc2vp0kaW5u9jUCgK1sc/dvAKB87N8A0P7YvwGg/bF/w7avmO/vspay1q1bl4ULF2bixIktYxUVFRkxYkTmzZvXpjXWrFmThoaG7Lzzzq3G586dmx49eqRbt2459thjc9lll2WXXXbZ4BpTpkzJxRdfvN74fffdl+22266IK2JzzZ49u6j5j75SSFKZlStX5p577tkyoQCATSp2/wYAys/+DQDtj/0bANof+zdsu9asWdPmuWUtZb388stpbGxMTU1Nq/GamposW7asTWv827/9W3r16pURI0a0jJ1wwgn55Cc/mT59+uSZZ57J1772tZx44omZN29eKisr11tj4sSJqa2tbXldX1/f8ljErl27bubV0RYNDQ2ZPXt2jj/++FRVVbX5vMLSutz45JLsvPPO+djHDtmCCQGAv7e5+zcAUD72bwBof+zfAND+2L9h2/fu0/faouyPL3w/rrjiitx2222ZO3duOnXq1DI+evToll/3798/AwYMyD777JO5c+fmuOOOW2+d6urqVFdXrzdeVVXlD8qtpNj3urLynd+6hULB1wgAysTPSgDQ/ti/AaD9sX8DQPtj/4ZtVzHf2xVbMMd76t69eyorK7N8+fJW48uXL0/Pnj03ee63vvWtXHHFFbnvvvsyYMCATc7de++907179zz99NPvOzMAAAAAAAAAAMCmlLWU1bFjxwwZMiRz5sxpGWtqasqcOXMyfPjwjZ535ZVX5tJLL82sWbMydOjQ9/w8f/nLX/LKK69kt912K0luAAAAAAAAAACAjSlrKStJamtrc/311+emm27K448/nq985StZvXp1xowZkyQ544wzMnHixJb53/jGN3LRRRdl5syZ2WuvvVJXV5e6urqsWrUqSbJq1aqcf/75+e1vf5s///nPmTNnTk4++eT07ds3o0aNKss1AgAAAAAAAAAAHx4dyh3gtNNOy0sv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6+vLnGTb19DQkDVr1qS+vj5VVVXljgMAtIH9GwDaH/s3ALQ/9m8AaH/s37Dte7dL9G63aFOUsjbgjTfeSJL07t27zEkAAAAAAAAAAIAPkjfeeCM77rjjJucUmttS3fqQaWpqygsvvJAuXbqkUCiUO842rb6+Pr17985///d/p2vXruWOAwC0gf0bANof+zcAtD/2bwBof+zfsO1rbm7OG2+8kV69eqWiomKTc90pawMqKiqyxx57lDvGh0rXrl1tSgDQzti/AaD9sX8DQPtj/waA9sf+Ddu297pD1rs2XdkCAAAAAAAAAACgKEpZAAAAAAAAAAAAJaSURVlVV1dn8uTJqa6uLncUAKCN7N8A0P7YvwGg/bF/A0D7Y/8G/lahubm5udwhAAAAAAAAAAAAthXulAUAAAAAAAAAAFBCSlkAAAAAAAAAAAAlpJQFAAAAAAAAAABQQkpZAAAAAAAAAAAAJaSURdlMnz49e+21Vzp16pRhw4ZlwYIF5Y4EAGzElClTcsghh6RLly7p0aNHTjnllDzxxBPljgUAFOGKK65IoVDI+PHjyx0FANiEv/71r/nc5z6XXXbZJZ07d07//v3zyCOPlDsWALARjY2Nueiii9KnT5907tw5++yzTy699NI0NzeXOxpQZkpZlMXtt9+e2traTJ48OYsWLcrAgQMzatSorFixotzRAIAN+PWvf52zzz47v/3tbzN79uw0NDRk5MiRWb16dbmjAQBt8Lvf/S7f+973MmDAgHJHAQA24dVXX83hhx+eqqqq/PKXv8wf//jHXHXVVenWrVu5owEAG/GNb3wj1113Xa699to8/vjj+cY3vpErr7wy11xzTbmjAWVWaFbPpAyGDRuWQw45JNdee22SpKmpKb17985Xv/rVTJgwoczpAID38tJLL6VHjx759a9/naOOOqrccQCATVi1alUGDx6c7373u7nssssyaNCgTJs2rdyxAIANmDBhQh566KH85je/KXcUAKCNPvGJT6SmpiY33HBDy9g//dM/pXPnzvk//+f/lDEZUG7ulMVWt27duixcuDAjRoxoGauoqMiIESMyb968MiYDANrq9ddfT5LsvPPOZU4CALyXs88+Ox//+Mdb/T0cAPhg+r//9/9m6NChOfXUU9OjR48cfPDBuf7668sdCwDYhMMOOyxz5szJk08+mSR57LHH8uCDD+bEE08sczKg3DqUOwAfPi+//HIaGxtTU1PTarympibLli0rUyoAoK2ampoyfvz4HH744TnooIPKHQcA2ITbbrstixYtyu9+97tyRwEA2uBPf/pTrrvuutTW1uZrX/tafve73+Wcc85Jx44dc+aZZ5Y7HgCwARMmTEh9fX3222+/VFZWprGxMf/xH/+Rz372s+WOBpSZUhYAAEU5++yzs3Tp0jz44IPljgIAbMJ///d/59xzz83s2bPTqVOncscBANqgqakpQ4cOzeWXX54kOfjgg7N06dLMmDFDKQsAPqDuuOOO3HLLLfnRj36UAw88MIsXL8748ePTq1cv+zd8yCllsdV17949lZWVWb58eavx5cuXp2fPnmVKBQC0xbhx43L33XfngQceyB577FHuOADAJixcuDArVqzI4MGDW8YaGxvzwAMP5Nprr83atWtTWVlZxoQAwN/bbbfdcsABB7Qa23///fPTn/60TIkAgPdy/vnnZ8KECRk9enSSpH///nnuuecyZcoUpSz4kKsodwA+fDp27JghQ4Zkzpw5LWNNTU2ZM2dOhg8fXsZkAMDGNDc3Z9y4cfnZz36WX/3qV+nTp0+5IwEA7+G4447L73//+yxevLjlY+jQofnsZz+bxYsXK2QBwAfQ4YcfnieeeKLV2JNPPpk999yzTIkAgPeyZs2aVFS0rl5UVlamqampTImADwp3yqIsamtrc+aZZ2bo0KE59NBDM23atKxevTpjxowpdzQAYAPOPvvs/OhHP8p//ud/pkuXLqmrq0uS7LjjjuncuXOZ0wEAG9KlS5ccdNBBrca233777LLLLuuNAwAfDOedd14OO+ywXH755fn0pz+dBQsW5Pvf/36+//3vlzsaALARJ510Uv7jP/4j//AP/5ADDzwwjz76aKZOnZrPf/7z5Y4GlFmhubm5udwh+HC69tpr881vfjN1dXUZNGhQrr766gwbNqzcsQCADSgUChsc/+EPf5izzjpr64YBADbb0UcfnUGDBmXatGnljgIAbMTdd9+diRMn5qmnnkqfPn1SW1ubsWPHljsWALARb7zxRi666KL87Gc/y4oVK9KrV6985jOfyaRJk9KxY8dyxwPKSCkLAAAAAAAAAACghCreewoAAAAAAAAAAABtpZQFAAAAAAAAAABQQkpZAAAAAAAAAAAAJaSUBQAAAAAAAAAAUEJKWQAAAAAAAAAAACWklAUAAAAAAAAAAFBCSlkAAAAAAAAAAAAlpJQFAAAAAAAAAABQQkpZAAAAAGxzzjrrrJxyyill+/ynn356Lr/88jbNHT16dK666qotnAgAAACAranQ3NzcXO4QAAAAANBWhUJhk8cnT56c8847L83Nzdlpp522Tqi/8dhjj+XYY4/Nc889lx122OE95y9dujRHHXVUnn322ey4445bISEAAAAAW5pSFgAAAADtSl1dXcuvb7/99kyaNClPPPFEy9gOO+zQpjLUlvLFL34xHTp0yIwZM9p8ziGHHJKzzjorZ5999hZMBgAAAMDW4vGFAAAAALQrPXv2bPnYcccdUygUWo3tsMMO6z2+8Oijj85Xv/rVjB8/Pt26dUtNTU2uv/76rF69OmPGjEmXLl3St2/f/PKXv2z1uZYuXZoTTzwxO+ywQ2pqanL66afn5Zdf3mi2xsbG/OQnP8lJJ53Uavy73/1u+vXrl06dOqWmpiaf+tSnWh0/6aSTctttt73/NwcAAACADwSlLAAAAAA+FG666aZ07949CxYsyFe/+tV85StfyamnnprDDjssixYtysiRI3P66adnzZo1SZLXXnstxx57bA4++OA88sgjmTVrVpYvX55Pf/rTG/0cS5Ysyeuvv56hQ4e2jD3yyCM555xzcskll+SJJ57IrFmzctRRR7U679BDD82CBQuydu3aLXPxAAAAAGxVSlkAAAAAfCgMHDgwF154Yfr165eJEyemU6dO6d69e8aOHZt+/fpl0qRJeeWVV7JkyZIkybXXXpuDDz44l19+efbbb78cfPDBmTlzZu6///48+eSTG/wczz33XCorK9OjR4+Wseeffz7bb799PvGJT2TPPffMwQcfnHPOOafVeb169cq6detaPZoRAAAAgPZLKQsAAACAD4UBAwa0/LqysjK77LJL+vfv3zJWU1OTJFmxYkWS5LHHHsv999+fHXbYoeVjv/32S5I888wzG/wcb775Zqqrq1MoFFrGjj/++Oy5557Ze++9c/rpp+eWW25puRvXuzp37pwk640DAAAA0D4pZQEAAADwoVBVVdXqdaFQaDX2bpGqqakpSbJq1aqcdNJJWbx4cauPp556ar3HD76re/fuWbNmTdatW9cy1qVLlyxatCi33nprdtttt0yaNCkDBw7Ma6+91jJn5cqVSZJdd921JNcKAAAAQHkpZQEAAADABgwePDh/+MMfstdee6Vv376tPrbffvsNnjNo0KAkyR//+MdW4x06dMiIESNy5ZVXZsmSJfnzn/+cX/3qVy3Hly5dmj322CPdu3ffYtcDAAAAwNajlAUAAAAAG3D22Wdn5cqV+cxnPpPf/e53eeaZZ3LvvfdmzJgxaWxs3OA5u+66awYPHpwHH3ywZezuu+/O1VdfncWLF+e5557LzTffnKampuy7774tc37zm99k5MiRW/yaAAAAANg6lLIAAAAAYAN69eqVhx56KI2NjRk5cmT69++f8ePHZ6eddkpFxcb/We2LX/xibrnllpbXO+20U+68884ce+yx2X///TNjxozceuutOfDAA5Mkb731Vu66666MHTt2i18TAAAAAFtHobm5ubncIQAAAABgW/Hmm29m3333ze23357hw4e/5/zrrrsuP/vZz3LfffdthXQAAAAAbA3ulAUAAAAAJdS5c+fcfPPNefnll9s0v6qqKtdcc80WTgUAAADA1uROWQAAAAAAAAAAACXkTlkAAAAAAAAAAAAlpJQFAAAAAAAAAABQQkpZAAAAAAAAAAAAJaSUBQAAAAAAAAAAUEJKWQAAAAAAAAAAACWklAUAAAAAAAAAAFBCSlkAAAAAAAAAAAAlpJQFAAAAAAAAAABQQkpZAAAAAAAAAAAAJfT/A6JaIEnqPlYdAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Extract recorded data for plotting\n", "times, cache_sizes = zip(*cache.cache_size_over_time)\n", "\n", "# Plot the cache size over time\n", "plt.figure(figsize=(30, 5))\n", "plt.plot(times, cache_sizes, label=\"Objects in Cache\")\n", "plt.xlabel(\"Time (s)\")\n", "plt.ylabel(\"Number of Cached Objects\")\n", "plt.title(\"Number of Objects in Cache Over Time\")\n", "plt.legend()\n", "plt.grid(True)\n", "plt.savefig(f\"{TEMP_BASE_DIR}/objects_in_cache_over_time.pdf\")\n", "\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 14, "id": "f30a0497-9b2e-4ea9-8ebf-6687de19aaa9", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAr4AAAIjCAYAAADlfxjoAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABKVUlEQVR4nO3deVyU5f7/8feAMqAGoiiLknuYK6ZJWC4VimaeqI6pv07gUplHT3koTVrUtK+obbZYHsu1czqaa+eUuYRb7rmQS1pKqGmCosIIFhjcvz/6Ot9GQGEcGOR+PR+P+1Fz3dd93Z97bsd5d3fd91gMwzAEAAAAVHIe7i4AAAAAKA8EXwAAAJgCwRcAAACmQPAFAACAKRB8AQAAYAoEXwAAAJgCwRcAAACmQPAFAACAKRB8AQAAYAoEXwBwg2+++UadOnVS9erVZbFYlJyc7O6SHDRs2FD333+/09tbLBaNHz/edQWV0NGjR2WxWPT66687PcbAgQPVsGFDl9Xk6vGKM3fuXFksFh09etTedr3nEahsCL5AJXbgwAH95S9/Ub169WS1WhUSEqJHH31UBw4ccHdppnbp0iX17dtX586d01tvvaWPP/5YDRo0cHdZAFDpVXF3AQDKxtKlSzVgwADVqlVLQ4YMUaNGjXT06FHNmjVLixcv1oIFC/Tggw+6u0xTSklJ0bFjx/Thhx/q8ccfd3c5KGMffvihCgoK3F0GABF8gUopJSVFjz32mBo3bqyNGzeqTp069nXPPPOMOnfurMcee0x79+5V48aN3VhpYRcvXlS1atXcXUaZOn36tCSpZs2a7i0E5aJq1aruLgHA/2KqA1AJvfbaa7p48aJmzpzpEHolKSAgQP/4xz+Uk5OjqVOnOqw7efKkhgwZopCQEFmtVjVq1EjDhg1TXl6evU9mZqb+/ve/q2HDhrJarapfv75iY2OVkZEhqeh5hpK0fv16WSwWrV+/3t7WrVs3tWrVSrt27VKXLl1UrVo1vfDCC5Kkzz77TL1797bX0qRJE02cOFH5+fkO414e47vvvtPdd9+tatWqqV69eoWOTZJ+/fVXjR8/Xrfccou8vb0VHByshx56SCkpKfY+BQUFmjZtmlq2bClvb28FBgZq6NChOn/+fIne+7Vr16pz586qXr26atasqQceeEAHDx60rx84cKC6du0qSerbt68sFou6det21TEzMzM1cuRIhYaGymq1qmnTppoyZUqhq4ivv/66OnXqpNq1a8vHx0ft27fX4sWLixzzn//8pzp27Khq1arJ399fXbp00erVqwv127Rpkzp27Chvb281btxY8+fPL9H7cKVjx47pr3/9q8LCwuTj46PatWurb9++hf6cXP7zs2nTJj399NOqU6eOatasqaFDhyovL0+ZmZmKjY2Vv7+//P39NXr0aBmGUeQ+33rrLTVo0EA+Pj7q2rWr9u/fX6jP8uXL1apVK3l7e6tVq1ZatmxZkWOV5r290pVzfP84D3nmzJlq0qSJrFarbr/9dn3zzTclGvPAgQO655575OPjo/r16+vVV1+96lXl1atXKzw8XN7e3mrRooWWLl1aov0AlQ1XfIFK6L///a8aNmyozp07F7m+S5cuatiwob744gt7288//6yOHTsqMzNTTz75pJo3b66TJ09q8eLFunjxory8vJSdna3OnTvr4MGDGjx4sG677TZlZGToP//5j06cOKGAgIBS13r27Fn16tVL/fv311/+8hcFBgZK+j0A1ahRQ/Hx8apRo4bWrl2rsWPHymaz6bXXXnMY4/z58+rZs6ceeughPfLII1q8eLGef/55tW7dWr169ZIk5efn6/7771dSUpL69++vZ555RhcuXNCaNWu0f/9+NWnSRJI0dOhQzZ07V4MGDdLTTz+t1NRUvffee9qzZ482b9581at3X331lXr16qXGjRtr/Pjx+uWXX/Tuu+/qzjvv1O7du9WwYUMNHTpU9erV06RJk/T000/r9ttvtx9zUS5evKiuXbvq5MmTGjp0qG6++WZt2bJFCQkJOnXqlKZNm2bv+/bbb+tPf/qTHn30UeXl5WnBggXq27evPv/8c/Xu3dve75VXXtH48ePVqVMnTZgwQV5eXtq+fbvWrl2rHj162PsdOXJEf/7znzVkyBDFxcVp9uzZGjhwoNq3b6+WLVuW/CTr95v5tmzZov79+6t+/fo6evSoPvjgA3Xr1k3fffddoav8f/vb3xQUFKRXXnlF27Zt08yZM1WzZk1t2bJFN998syZNmqQVK1botddeU6tWrRQbG+uw/fz583XhwgUNHz5cv/76q95++23dc8892rdvn/39Xr16tR5++GG1aNFCiYmJOnv2rAYNGqT69esXqr+k721pfPLJJ7pw4YKGDh0qi8Wi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Lqo4kZGRWrFihUPbmjVrFBkZKUny8vJS+/btlZSUZL9JrqCgQElJSRoxYkSZ1QUAAICKz6nn+BY5kIeH4uPj9dZbb5V4m+zsbCUnJys5OVnS7zfNJScn6/jx45J+n4IQGxtr7//UU0/pxx9/1OjRo3Xo0CG9//77+vTTT/X3v//d3ic+Pl4ffvih5s2bp4MHD2rYsGHKycnRoEGDXHOgAAAAuCG59Oa2lJQU/fbbbyXuv3PnTt19993215fn2cbFxWnu3Lk6deqUPQRLvz9G7YsvvtDf//53vf3226pfv74++ugj+zN8Jalfv346c+aMxo4dq7S0NIWHh2vlypWFbngDAACAuTj1HN8/3ggmSYZh6NSpU/riiy8UFxdnf4bujYrn+MKMKvqduACuje8SuFt5fpeU23N89+zZ4/Daw8NDderU0RtvvHHNJz4AAAAA7uBU8F23bp2r6wAAAADKlFM3t6Wmpurw4cOF2g8fPqyjR49eb00AAACAyzkVfAcOHKgtW7YUat++fbsGDhx4vTUBAAAALudU8N2zZ4/uvPPOQu133HGH/dFkAAAAQEXiVPC1WCy6cOFCofasrCzl5+dfd1EAAACAqzkVfLt06aLExESHkJufn6/ExETdddddLisOAAAAcBWnnuowZcoUdenSRWFhYercubMk6euvv5bNZtPatWtdWiAAAADgCk5d8W3RooX27t2rRx55RKdPn9aFCxcUGxurQ4cOqVWrVq6uEQAAALhuTv9kcUhIiCZNmuTKWgAAAIAy49QV3zlz5mjRokWF2hctWqR58+Zdd1EAAACAqzkVfBMTExUQUPi3mOvWrctVYAAAAFRITgXf48ePq1GjRoXaGzRooOPHj193UQAAAICrORV869atq7179xZq//bbb1W7du3rLgoAAABwNaeC74ABA/T0009r3bp1ys/PV35+vtauXatnnnlG/fv3d3WNAAAAwHVz6qkOEydO1NGjR3XvvfeqSpXfh8jPz1dcXBxzfAEAAFAhORV8vby8tHDhQj333HM6evSofHx81Lp1azVo0MDV9QEAAAAuUergm5mZqRdffFELFy7U+fPnJUn+/v7q37+/Xn31VdWsWdPVNQIAAADXrVTB99y5c4qMjNTJkyf16KOP6tZbb5Ukfffdd5o7d66SkpK0ZcsW+fv7l0mxAAAAgLNKFXwnTJgg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qsrcgoODNWPGDC1ZskRLlixRaGiounXrpt27d7u7tEqnoKBAI0eO1J133unwi5ZXKu5zwrxr1yvpOeG7pGzt27dPNWrUkNVq1VNPPaVly5apRYsWRfbl81E+SnNOXPX5cPtPFlcGkZGRDv+F0qlTJ9166636xz/+oYkTJ7qxMqBiCAsLU1hYmP11p06dlJKSorfeeksff/yxGyurfIYPH679+/dr06ZN7i4F/6uk54TvkrIVFham5ORkZWVlafHixYqLi9OGDRuKDVooe6U5J676fBB8rxAQECBPT0+lp6c7tKenpysoKKhEY1StWlXt2rXTkSNHyqJEXENQUFCR58/X11c+Pj5uqgpX6tixI+HMxUaMGKHPP/9cGzduVP369a/at7jPSUn/nkPJlOacXInvEtfy8vJS06ZNJUnt27fXN998o7ffflv/+Mc/CvXl81E+SnNOruTs54OpDlfw8vJS+/btlZSUZG8rKChQUlLSVeed/FF+fr727dun4ODgsioTVxEZGelw/iRpzZo1JT5/KB/Jycl8RlzEMAyNGDFCy5Yt09q1a9WoUaNrbsPnpGw5c06uxHdJ2SooKFBubm6R6/h8uMfVzsmVnP58XPftcZXQggULDKvVasydO9f47rvvjCeffNKoWbOmkZaWZhiGYTz22GPGmDFj7P1feeUVY9WqVUZKSoqxa9cuo3///oa3t7dx4MABdx1CpXLhwgVjz549xp49ewxJxptvvmns2bPHOHbsmGEYhjFmzBjjscces/f/8ccfjWrVqhmjRo0yDh48aEyfPt3w9PQ0Vq5c6a5DqHRKe07eeustY/ny5cbhw4eNffv2Gc8884zh4eFhfPXVV+46hEpl2LBhhp+fn7F+/Xrj1KlT9uXixYv2Plf+vbV582ajSpUqxuuvv24cPHjQGDdunFG1alVj37597jiESseZc8J3SdkZM2aMsWHDBiM1NdXYu3evMWbMGMNisRirV682DIPPhzuU9py46vNB8C3Gu+++a9x8882Gl5eX0bFjR2Pbtm32dV27djXi4uLsr0eOHGnvGxgYaNx3333G7t273VB15XT5UVhXLpfPQVxcnNG1a9dC24SHhxteXl5G48aNjTlz5pR73ZVZac/JlClTjCZNmhje3t5GrVq1jG7duhlr1651T/GVUFHnQpLDn/sr/94yDMP49NNPjVtuucXw8vIyWrZsaXzxxRflW3gl5sw54buk7AwePNho0KCB4eXlZdSpU8e499577QHLMPh8uENpz4mrPh8WwzCM0l0jBgAAAG48zPEFAACAKRB8AQAAYAoEXwAAAJgCwRcAAACmQPAFAACAKRB8AQAAYAoEXwAAAJgCwRcAAACmQPAFABM7evSoLBaLkpOT3V0KAJQ5gi8AuNnAgQNlsVg0efJkh/bly5fLYrG4qSoAqHwIvgBQAXh7e2vKlCk6f/68u0txiby8PHeXAACFEHwBoAKIiopSUFCQEhMTi1w/fvx4hYeHO7RNmzZNDRs2tL8eOHCgYmJiNGnSJAUGBqpmzZqaMGGCfvvtN40aNUq1atVS/fr1NWfOnELjHzp0SJ06dZK3t7datWqlDRs2OKzfv3+/evXqpRo1aigwMFCPPfaYMjIy7Ou7deumESNGaOTIkQoICFB0dLTzbwYAlBGCLwBUAJ6enpo0aZLeffddnThxwulx1q5dq59//lkbN27Um2++qXHjxun++++Xv7+/tm/frqeeekpDhw4ttI9Ro0bp2Wef1Z49exQZGak+ffro7NmzkqTMzEzdc889ateunXbu3KmVK1cqPT1djzzyiMMY8+bNk5eXlzZv3qwZM2Y4fQwAUFYIvgBQQTz44IMKDw/XuHHjnB6jVq1aeueddxQWFqbBgwcrLCxMFy9e1AsvvKBmzZopISFBXl5e2rRpk8N2I0aM0MMPP6xbb71VH3zwgfz8/DRr1ixJ0nvvvad27dpp0qRJat68udq1a6fZs2dr3bp1+uGHH+xjNGvWTFOnTlVYWJjCwsKcPgYAKCsEXwCoQKZMmaJ58+bp4MGDTm3fsmVLeXj831/tgYGBat26tf21p6enateurdOnTztsFxkZaf/3KlWqqEOHDvYavv32W61bt041atSwL82bN5ckpaSk2Ldr3769UzUDQHmp4u4CAAD/p0uXLoqOjlZCQoIGDhxob/fw8JBhGA59L126VGj7qlWrOry2WCxFthUUFJS4puzsbPXp00dTpkwptC44ONj+79WrVy/xmADgDgRfAKhgJk+erPDwcIfpAnXq1FFaWpoMw7A/4syVz97dtm2bunTpIkn67bfftGvXLo0YMUKSdNttt2nJkiVq2LChqlThawPAjYupDgBQwbRu3VqPPvqo3nnnHXtbt27ddObMGU2dOlUpKSmaPn26vvzyS5ftc/r06Vq2bJkOHTqk4cOH6/z58xo8eLAkafjw4Tp37pwGDBigb775RikpKVq1apUGDRqk/Px8l9UAAGWN4AsAFdCECRMcpiPceuutev/99zV9+nS1bdtWO3bs0HPPPeey/U2ePFmTJ09W27ZttWnTJv3nP/9RQECAJCkkJESbN29Wfn6+evToodatW2vkyJGqWbOmw3xiAKjoLMaVk8YAAACASoj/VAcAAIApEHwBAABgCgRfAAAAmALBFwAAAKZA8AUAAIApEHwBAABgCgRfAAAAmALBFwAAAKZA8AUAAIApEHwBAABgCgRfAAAAmML/B6A85o235FlJAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from collections import Counter\n", "# Count occurrences of each number\n", "count = Counter(list(db.lambda_values.values()))\n", "\n", "# Separate the counts into two lists for plotting\n", "x = list(count.keys()) # List of unique numbers\n", "y = list(count.values()) # List of their respective counts\n", "\n", "# Plot the data\n", "plt.figure(figsize=(8, 6))\n", "plt.bar(x, y, color='skyblue')\n", "\n", "# Adding labels and title\n", "plt.xlabel('Number')\n", "plt.ylabel('Occurrences')\n", "plt.title('Occurance of each lambda in db')\n", "plt.savefig(f\"{TEMP_BASE_DIR}/lambda_distribution.pdf\")\n", "\n", "# Show the plot\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 15, "id": "c192564b-d3c6-40e1-a614-f7a5ee787c4e", "metadata": {}, "outputs": [ { "data": { "image/png": "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3G63m5EjR+b7HoWGhpro6GiTlZWVb7tXHmc326P58+cbSeahhx667twrJSUlGUmmbt26Ji0tzTH+22+/mVq1ahlJ5ssvv3SMexpkJZlRo0Y5hewPPvjASDIjRoxwmt+mTRvDeSagYLi0AICT4OBghYaG5htv166d6tevr40bN7p83BNPPKFq1ao5lmNiYnT33XcrPT1dzz77rMLDwx3rWrRooWrVqunf//63221VrlzZsezr66uXX35Zkpz+pJt3ecILL7ygcuXKOcZvu+02PfHEEy63HRcXl2/Mx8dHI0eOVG5urjZv3uzycVcqX768evbsqR9++EE7d+50Wrdw4UJJ0kMPPeQ0XqZMGZUpUybftsLCwq67vzx5b/IaNGiQYyzv33nr8nz77bf6/vvv1bp1az366KP5tnVlfxcsWKCsrCw99dRTuv3226859x//+Ick6b333nPquc1m08yZM2Wz2bRkyRKnx/v6+srb2zvfdq8+zm6mRykpKflqLYgFCxZIunyJTHBwsGM8JCREU6ZMkaRrXrpRUOXKldMrr7wiL6///7/dwYMHy8fHR999991Nbx/4o+LNXgDySUxM1Ouvv67t27fr119/1aVLlxzrfH19XT6mSZMm+caioqKuuW779u0ut3XPPffkG4uPj5ePj4927drlGMsLwq7muxqTpMzMTM2aNUurVq3SoUOHlJWV5bT+xIkTLh93tYEDB2rJkiVauHCh7rjjDkmX34i1Zs0aNWzY0Omd8X379tXEiRPVoEED9e/fX+3atdPdd9+toKCgAu1LkrKzs/XRRx+pfPny6tWrl2O8Xbt2iomJ0cqVK3X27FmFhIRIuhxkJalz587X3faNzN22bZvKlSvn9m4JAQEB+umnnxzLffv21dtvv60GDRqob9++ateuneLj4xUQEOD0uMLokSfyjqe2bdvmW9euXTtJ0u7du296P7Vq1VJgYKDTmI+PjyIiIpSWlnbT2wf+qAiyAJwsW7ZMffr0UWBgoLp06aKqVauqbNmyjje4uHuDk6vA4ePjc811VwbkK0VEROQb8/b2VlhYmNLT0x1j6enp8vLyUsWKFQu0jYsXL6pt27bauXOnbr/9dg0cOFBhYWHy8fHRkSNHtGDBAmVnZ7us6WqdO3dWRESEli5dqlmzZsnb21vLly/X+fPnNXDgQKe5EyZMUFhYmObMmaO//e1vmjVrlnx8fHTffffptddec3mW+GqrVq3SmTNnNGTIEKcQ6OXlpQEDBmjmzJlavHixRo8e7eiNdPns9PXcyNzffvtNly5d0tSpU93OufKXgzfeeENxcXFKSEjQSy+9pJdeekn+/v568MEH9be//c3xvbvZHkVGRkqS/vvf/173OVwpIyNDXl5eTn8xyBMRESGbzaaMjIwb2qYr7gK5j49PvjfIASg4giwAJy+++KL8/f21Y8cO1axZ02nd0qVLi6WGU6dOqXbt2k5jubm5OnPmjFNADQ4Olt1u16+//poviJw6dSrfdlevXq2dO3dq2LBh+uCDD5zWLV261PFn5oLw9vZWv3799Prrr2vjxo3q0qWLFi5cKC8vL/Xv399prs1m09ChQzV06FCdOXNGX331lZYsWaJPPvlEBw4c0J49e1z+6f1KeZcOJCQkKCEhwe2cvCBboUIFSQULdlfOrVq16jXnBgUFyWaz6ddff73udqXLQW3ChAmaMGGCTpw4oaSkJCUkJOjDDz9USkqK1q9fL+nme3TXXXdJuvzXBLvd7vQn/Os9H7vdrtOnT6tSpUpO61JTU2WMcQqhedt19UvYlb9kASgeXCMLwMmhQ4dUt27dfCH25MmT+vnnn4ulhq+++irf2NatW3Xp0iWnazjz/nzvar6rsbzbh/Xo0aNA868n78zrRx99pOPHjyspKUnt2rW75pnNsLAw9ezZUx9//LHat2+vH374QQcPHrzmfo4ePapNmzYpIiJCw4YNc/kVFxenXbt2Of5U3rx5c0nShg0brvs8bmRuixYtdObMGR04cOC6c68WHR2tfv36ad26dapRo4Y2btyo8+fP55vnSY9q1Kih1q1b6/jx49f9heTKs+55x5OrW3LljV15aUzepRuufkG48rKXm5EX2DlTC1wfQRaAk9jYWB08eNDpjOaFCxf02GOPubyPa1F444039MsvvziWL168qGeffVaSnO6nmRckp02b5vTn7P/+979644038m03NjZWkvT11187jSclJen999+/4TrvuOMO1atXTytXrtS7774rY0y+ywqky4HIGOM0lpOTo99++02S5O/vf839JCQkyG63a8SIEfrggw9cfk2aNEnS/z9ze+edd+rOO+/Ul19+6fK5XRnEBg8erMDAQP3tb39zeT3olXPHjh0rSY4zp1dLSUnRjz/+KOlyYNyyZUu+OVlZWTp37pzKlCnjOMN5sz2SLh83AQEBevzxx/Xxxx+7nPPVV1+pffv2juXBgwdLkqZOnep0CUF6errj8om8OZLUtGlT2Ww2LV26VBcuXHCMHzhwwOUx54m8N8EdP368ULYH3Mq4tAD4A9m7d6/bG6vXqVNHkyZN0pgxYzRmzBjdfvvteuCBB3Tp0iV9/vnnMsaocePGbu80UJhatmypxo0bq0+fPipXrpzWrFmj/fv36/7771fv3r0d89q1a6chQ4Y4PoihV69eys7O1scff6yWLVtq7dq1Ttvt3r27qlatqldffVXJyclq0KCB9u/fr7Vr16pXr15avnz5Ddc6cOBATZ48Wa+++qrKli3rVF+enj17KigoSC1btlRsbKxycnL0+eef64cfftADDzzgCNiu2O12JSQkXPem+H369NG4ceO0aNEizZo1S/7+/lq0aJHatm2r4cOHa+HChYqPj9eFCxe0b98+7dq1yxFEK1WqpA8//FB9+/ZV8+bN9ec//1m1a9fWr7/+qu3bt6tq1apatWqVJKlr1656/vnnNX36dNWoUUNdu3ZVbGyszpw5o4MHD+qrr77SSy+9pLp16+r8+fO66667VKtWLTVt2lRVqlTRuXPntHbtWqWkpGjChAny8/O76R7ladKkidasWaMHH3xQffv21bRp09S6dWuFhobqt99+0zfffKO9e/eqRo0ajse0bt1aY8aM0VtvvaUGDRqod+/eMsbo008/1S+//KKxY8eqdevWjvl5Z5UXL16spk2bqmvXrkpNTdXKlSvVtWvXG/6AC1fat2+v5cuXq3fv3urWrZv8/f3VuHFjx6eWAbhCSd77C0DxyLuP7LW+2rRpY4y5fD/Qd955x9SvX9/4+/ubyMhIM2zYMJOamury/pZ595HdvHlzvv3m3Rf28OHD+da52lbe/EOHDpmZM2eaGjVqGF9fXxMbG2tefPFFk52dnW87ly5dMjNmzDDVqlUzvr6+plq1aub//t//aw4ePOj2PrK9e/c24eHhpmzZsubOO+80S5cudXsP0Os5duyY8fLyMpJMv379XM55++23zZ///GcTGxtr/P39TVhYmGnevLmZM2eOuXjx4jW3v379eqfvz7UMGDDASDKLFi1yjKWkpJgnnnjC0Z/Q0FDTokUL8/e//z3f43ft2mUefPBBExERYcqUKWOioqJMt27dzNq1a/PN/fzzz0337t1NeHi4KVOmjImMjDTx8fFm+vTp5tixY8YYYy5evGheeeUV07lzZ1O5cmXj6+trIiIiTOvWrc3ixYudPsThZnp0tTNnzpjp06ebli1bmpCQEOPj42PCwsJM27ZtzZtvvul0/9s88+bNM3feeacpW7as47iYN2+ey+3//vvvZuzYsSYiIsL4+fmZRo0amUWLFl3zPrLuvn+xsbEmNjbWaSwnJ8dMnDjRVKlSxfj4+Lg8jgFcZjPmqr/lAAAAABbANbIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALKlUfSDCnDlzNGfOHB05ckSSVL9+fb3wwgvq1q2bJKlt27ZKSkpyesyIESP0zjvvFHgfdrtdJ06cUPny5WWz2QqtdgAAABQOY4wyMzMVHR3t+ARAV0rVfWTXrFkjb29v1axZU8YYLViwQH/961+1a9cu1a9fX23btlWtWrU0bdo0x2PKli2roKCgAu/jl19+UUxMTFGUDwAAgEJ0/PhxVa5c2e36UnVG9uqP33v55Zc1Z84cbdu2TfXr15d0ObhGRkZ6vI/y5ctLutyYGwnAnrLb7Tp9+rTCw8Ov+RvFHxG9cY2+uEZf3KM3rtEX9+iNa/TFveLuTUZGhmJiYhy5zZ1SFWSvlJubq2XLlikrK0vx8fGO8UWLFumjjz5SZGSkunfvrueff15ly5Z1u53s7GxlZ2c7ljMzMyVJgYGBCgwMLLon8L/sdrvOnz+vwMBAfiiuQm9coy+u0Rf36I1r9MU9euMafXGvuHtjt9sl6bqXgZa6ILt3717Fx8frwoULCgwM1MqVK1WvXj1JUv/+/RUbG6vo6Gjt2bNHzzzzjPbv368VK1a43d6MGTM0derUfOOnT5/WhQsXiux55LHb7UpPT5cxhh+Kq9Ab1+iLa/TFPXrjGn1xj964Rl/cK+7e5J14vJ5SdY2sJF28eFHHjh1Tenq6li9frg8++EBJSUmOMHulL774Qh06dNDBgwdVvXp1l9u7+oxs3qnqs2fPcmlBCaM3rtEX1+iLe/TGNfriHr1xjb64VxKXFoSEhCg9Pf2aea3UnZH19fVVjRo1JElNmzbVd999pzfeeEPvvvtuvrktWrSQpGsGWT8/P/n5+eUb9/LyKraD1GazFev+rITeuEZfXKMv7tEb1+iLe/TGNfriXnH2pqD7KPXfJbvd7nRG9Uq7d++WJEVFRRVjRQAAACgNStUZ2cmTJ6tbt26qUqWKMjMztXjxYiUmJmr9+vU6dOiQFi9erHvvvVdhYWHas2ePnnzySbVu3VqNGjUq6dIBAABQzEpVkE1NTdWgQYN08uRJBQcHq1GjRlq/fr06deqk48ePa+PGjXr99deVlZWlmJgY9e7dW88991xJlw0AAIASUKqC7Ny5c92ui4mJyfepXgAAAPjjKvXXyAIAAACuEGQBAABgSQRZAAAAWBJBFgAAAJZEkAUAAIAlEWQBAABgSQRZAAAAuGW325WcnOz4stvtJV2SQ6m6jywAAABKjy1btmj2O+/pP0dPqGqVGB05dly1YqM1euRwtWrVqqTL44wsAAAA8tuyZYsmPj9NP53zV9Wuw1Wt4wBV7Tpc+7P8NfH5adqyZUtJl0iQBQAAgDO73a7Z77yn88FV1bj7UAVHVZG3TxkFR1VRoz8N1YUKVfX2u++X+GUGBFkAAAA42bdvn/Yf+a/i7uwom83mtM5msym2WQf9dPgX7du3r4QqvIwgCwAAACdnz57VxUu5Klcx0uX6wLBIXbyUq7NnzxZzZc4IsgAAAHASEhIiXx9vZf2a4nL9uTMp8vXxVkhISDFX5owgCwAAACf169dX7aq36cj3G2WMcVpnjNHR7zepTlxl1a9fv4QqvIwgCwAAACdeXl4aPXK4/NOOaM/aeUo7eVS5OReVdvKo9qydJ/+0Ixo14lF5eZVslCTIAgAAIJ9WrVrp1ekvqHa5Czq67n39vGmxjq57X3UCs/Xq9BdKxX1k+UAEAAAAuNSqVSu1bNlSycnJSk1NVaVKldSgQYMSPxObhyALAAAAt7y8vNSgQQNHkC0tIVbi0gIAAABYFEEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCWVqiA7Z84cNWrUSEFBQQoKClJ8fLz+9a9/OdZfuHBBo0ePVlhYmAIDA9W7d2+dOnWqBCsGAABASSlVQbZy5cqaOXOmduzYoe+//17t27dXjx49tG/fPknSk08+qTVr1mjZsmVKSkrSiRMndP/995dw1QAAACgJPiVdwJW6d+/utPzyyy9rzpw52rZtmypXrqy5c+dq8eLFat++vSQpISFBdevW1bZt29SyZcuSKBkAAAAlpFQF2Svl5uZq2bJlysrKUnx8vHbs2KGcnBx17NjRMadOnTqqUqWKtm7d6jbIZmdnKzs727GckZEhSbLb7bLb7UX7JP53P8aYYtmX1dAb1+iLa/TFPXrjGn1xj964Rl/cK+7eFHQ/pS7I7t27V/Hx8bpw4YICAwO1cuVK1atXT7t375avr68qVKjgND8iIkIpKSlutzdjxgxNnTo13/jp06d14cKFwi4/H7vdrvT0dBlj5OVVqq7kKHH0xjX64hp9cY/euEZf3KM3rtEX94q7N5mZmQWaV+qCbO3atbV7926lp6dr+fLlGjx4sJKSkjze3uTJkzV+/HjHckZGhmJiYhQeHq6goKDCKPma7Ha7bDabwsPD+aG4Cr1xjb64Rl/cozeu0Rf36I1r9MW94u6Nv79/geaVuiDr6+urGjVqSJKaNm2q7777Tm+88Yb69OmjixcvKi0tzems7KlTpxQZGel2e35+fvLz88s37uXlVWwHqc1mK9b9WQm9cY2+uEZf3KM3rtEX9+iNa/TFveLsTUH3Ueq/S3a7XdnZ2WratKnKlCmjTZs2Odbt379fx44dU3x8fAlWCAAAgJJQqs7ITp48Wd26dVOVKlWUmZmpxYsXKzExUevXr1dwcLCGDRum8ePHKzQ0VEFBQRozZozi4+O5YwEAAMAfUKkKsqmpqRo0aJBOnjyp4OBgNWrUSOvXr1enTp0kSa+99pq8vLzUu3dvZWdnq0uXLnr77bdLuGoAAACUhFIVZOfOnXvN9f7+/po9e7Zmz55dTBUBAACgtCr118gCAAAArhBkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWVKqC7IwZM3TnnXeqfPnyqlSpknr27Kn9+/c7zWnbtq1sNpvT18iRI0uoYgAAAJSUUhVkk5KSNHr0aG3btk2ff/65cnJy1LlzZ2VlZTnNe/TRR3Xy5EnH16uvvlpCFQMAAKCk+HjyoGPHjik8PFwBAQEu158/f16nT59WlSpVbmi769atc1qeP3++KlWqpB07dqh169aO8bJlyyoyMvLGCwcAAMAtw6MgGxcXp4ULF6p///4u1//zn/9U//79lZube1PFpaenS5JCQ0OdxhctWqSPPvpIkZGR6t69u55//nmVLVvW5Tays7OVnZ3tWM7IyJAk2e122e32m6qvIOx2u4wxxbIvq6E3rtEX1+iLe/TGNfriHr1xjb64V9y9Keh+PAqyxphrrs/JyZGX181dtWC32zVu3DjdddddatCggWO8f//+io2NVXR0tPbs2aNnnnlG+/fv14oVK1xuZ8aMGZo6dWq+8dOnT+vChQs3VWNB2O12paenyxhz0z251dAb1+iLa/TFPXrjGn1xj964Rl/cK+7eZGZmFmhegYNsRkaG0tLSHMtnzpzRsWPH8s1LS0vT0qVLFRUVVdBNuzR69GglJyfr66+/dhofPny4498NGzZUVFSUOnTooEOHDql69er5tjN58mSNHz/e6XnExMQoPDxcQUFBN1VjQdjtdtlsNoWHh/NDcRV64xp9cY2+uEdvXKMv7tEb1+iLe8XdG39//wLNK3CQfe211zRt2jRJks1m07hx4zRu3DiXc40xeumllwq66Xwef/xxrV27Vl9++aUqV658zbktWrSQJB08eNBlkPXz85Ofn1++cS8vr2I7SG02W7Huz0rojWv0xTX64h69cY2+uEdvXKMv7hVnbwq6jwIH2c6dOyswMFDGGE2cOFH9+vXTHXfc4TTHZrOpXLlyatq0qZo1a3ZjFetyAB4zZoxWrlypxMRExcXFXfcxu3fvlqSbPgMMAAAAaylwkI2Pj1d8fLwkKSsrS71793a6drUwjB49WosXL9bq1atVvnx5paSkSJKCg4MVEBCgQ4cOafHixbr33nsVFhamPXv26Mknn1Tr1q3VqFGjQq0FAAAApZtHb/aaMmVKYdchSZozZ46kyx96cKWEhAQ9/PDD8vX11caNG/X6668rKytLMTEx6t27t5577rkiqQcAAACll0dBVpLOnj2rJUuW6Oeff9bZs2fz3cnAZrNp7ty5N7TN690NISYmRklJSTdcKwAAAG49HgXZ9evX64EHHlBWVpaCgoIUEhKSb47NZrvp4gAAAAB3PAqyTz31lCIjI7VixQo1bNiwsGsCAAAArsuj+yccPHhQY8eOJcQCAACgxHgUZGvWrFngT1wAAAAAioJHQfall17S22+/rSNHjhRyOQAAAEDBeHSN7KZNmxQeHq66deuqU6dOiomJkbe3t9Mcm82mN954o1CKBAAAAK7mUZD9xz/+4fj32rVrXc4hyAIAAKAoeRRk7XZ7YdcBAAAA3BCPrpEFAAAAShpBFgAAAJbk0aUFXl5eBfrkrtzcXE82DwAAAFyXR0H2hRdeyBdkc3NzdeTIEa1atUq1a9fWn/70p0IpEAAAAHDFoyD74osvul138uRJtWzZUrVq1fK0JgAAAOC6Cv0a2aioKI0cOVLTp08v7E0DAAAADkXyZq9y5crp8OHDRbFpAAAAQFIRBNnk5GS9+eabXFoAAACAIuXRNbJxcXEu71qQlpam9PR0lS1bVqtWrbrZ2gAAAAC3PAqybdq0yRdkbTabQkJCVL16dfXt21ehoaGFUiAAAADgikdBdv78+YVcBgAAAHBjCuUa2fPnz+v8+fOFsSkAAACgQDwOsseOHdOQIUMUERGhwMBABQYGKiIiQkOHDtXRo0cLs0YAAAAgH48uLfjpp5909913Ky0tTZ06dVLdunUd4x9++KHWrFmjr7/+WrVr1y7UYgEAAIA8HgXZSZMmycvLS7t27VLDhg2d1iUnJ6tDhw6aNGmSVq5cWShFAgAAAFfz6NKCpKQkjR07Nl+IlaQGDRro8ccfV2Ji4s3WBgAAALjlUZDNyclRQECA2/Vly5ZVTk6Ox0UBAAAA1+NRkL399tv1wQcfKD09Pd+6jIwMzZ07V3fcccdNFwcAAAC449E1slOnTlXXrl1Vp04dDRkyxPFxtPv379eCBQt05swZzZ49u1ALBQAAAK7kUZBt3769PvvsMz399NOaOXOm07omTZpo4cKFateuXaEUCAAAALjiUZCVpI4dO2rXrl1KSUlx3Dc2NjZWkZGRhVYcAAAA4I7HQTZPZGQk4RUAAADFrsBv9jpw4ID8/f01ceLEa857+umnFRAQoMOHD990cQAAAIA7BQ6yb775piIjI/Xyyy9fc97LL7+syMhIvfnmmzddHAAAAOBOgYPshg0b1LdvX5UpU+aa83x9fdW3b1/961//uuniAAAAAHcKHGSPHTum2rVrF2huzZo1HW8AAwAAAIpCgYOsn5+fzp07V6C5WVlZ8vX19bgoAAAA4HoKHGTr1KmjjRs3Fmjupk2bVLduXY+LAgAAAK6nwEG2T58+Wrt2rVatWnXNeatXr9batWvVp0+fm60NAAAAcKvAQXbUqFG6/fbb9Ze//EWPPfaYvvnmG2VkZMgYo4yMDH3zzTd67LHH9MADD6hx48YaNWpUUdYNAACAP7gCfyCCn5+f1q9fr8GDB+vdd9/Ve++9l2+OMUZdu3bVhx9+KD8/v0ItFAAAALjSDX2yV1hYmNauXatvv/1W//znP/Xjjz8qIyNDQUFBqlOnjrp3766WLVsWVa0AAACAg0cfUdu8eXM1b968sGsBAAAACqzA18gCAAAApQlBFgAAAJZEkAUAAIAlEWQBAABgSQRZAAAAWFKhBtmff/5ZP/74Y2FuEgAAAHDJoyD75ptvqm/fvk5jQ4YMUc2aNdWgQQM1a9ZMqamphVIgAAAA4IpHQfaDDz5QRESEY3n9+vVasGCBhg8frrfeeks///yzpk6dWmhFAgAAAFfz6AMRjh49qrp16zqWP/nkE8XFxWnOnDmSpJSUFC1cuLBwKgQAAABc8OiMrDHGaXnDhg3q1q2bY7lq1apKSUm5ucoAAACAa/AoyNaqVUsrV66UdPmyghMnTjgF2V9++UUVKlQolAIBAAAAVzy6tGDChAnq37+/QkJClJWVpbp166pLly6O9V988YWaNGlSWDUCAAAA+XgUZPv27auwsDB99tlnqlChgkaNGiUfn8ub+u233xQaGqqBAwcWaqEAAADAlTwKspLUqVMnderUKd94aGioVqxYcVNFAQAAANfjcZC92u+//66lS5cqOztb9957r2JjYwtr0wAAAEA+HgXZYcOGafv27UpOTpYkXbx4US1btnQsBwcH64svvtDtt99eeJUCAAAAV/DorgWbN2/W/fff71hevHixkpOTtWjRIiUnJysyMpIPRAAAAECR8ijIpqSkqGrVqo7lVatWqVmzZurXr5/q1aunRx99VNu3by+sGi3LbrcrOTnZ8WW320u6JAAAgFuGR5cWlCtXTmlpaZKkS5cuKTExUWPGjHGsL1++vNLT0wulQKvasmWLZr/znv5z9ISqVonRkWPHVSs2WqNHDlerVq1KujwAAADL8+iM7B133KH3339fu3bt0ssvv6zMzEx1797dsf7QoUOKiIgotCKtZsuWLZr4/DT9dM5fVbsOV7WOA1S163Dtz/LXxOenacuWLSVdIgAAgOV5FGRffvllpaamqlmzZpo6dap69+6t5s2bO9avXLlSd911V6EVaSV2u12z33lP54OrqnH3oQqOqiJvnzIKjqqiRn8aqgsVqurtd9/nMgMAAICb5NGlBc2aNdNPP/2kLVu2qEKFCmrTpo1jXVpamkaNGuU09keyb98+7T/yX8V1GyGbzSbJONbZbDbFNuugn/71nvbt26eGDRuWXKEAAAAW5/F9ZMPDw9WjR4984xUqVNATTzxxU0VZ2dmzZ3XxUq7KVYx0uT4wLFIXL+Xq7NmzxVwZAADArcWjSwskKTc3V0uXLtWIESPUq1cv7d27V5KUnp6uFStW6NSpU4VWpJWEhITI18dbWb+muFx/7kyKfH28FRISUsyVAQAA3Fo8CrJpaWm666671L9/fy1ZskT//Oc/dfr0aUlSYGCgxo4dqzfeeKNQC7WK+vXrq3bV23Tk+40yxjitM8bo6PebVCeusurXr19CFQIAANwaPAqykyZN0r59+7R+/Xr9/PPPToHN29tbDzzwgD777LNCK9JKvLy8NHrkcPmnHdGetfOUdvKocnMuKu3kUe1ZO0/+aUc0asSj8vLy+GQ4AAAA5GGQXbVqlcaMGaNOnTr97xuanNWqVUtHjhy52dosq1WrVnp1+guqXe6Cjq57Xz9vWqyj695XncBsvTr9Be4jCwAAUAg8erNXenq64uLi3K7PycnRpUuXPC7qVtCqVSu1bNlSycnJSk1NVaVKldSgQQPOxAIAABQSj4Js9erVtXPnTrfrN2zYoHr16nlc1K3Cy8tLDRo0cARZQiwAAEDh8ShZPfLII5o3b54+/vhjx/WxNptN2dnZevbZZ7Vu3TqNGDGiUAsFAAAAruTRGdknnnhC+/btU79+/VShQgVJUv/+/XXmzBldunRJI0aM0LBhwwqzTgAAAMCJR0HWZrPp/fff1+DBg7V8+XIdOHBAdrtd1atX14MPPqjWrVsXdp0AAACAE48/2UuS7r77bt19992FVQsAAABQYB5dI3v48GGtWbPG7fo1a9b8oW+/BQAAgKLn0RnZCRMmKCMjQ927d3e5fvbs2apQoYKWLl16U8UBAAAA7nh0Rnbr1q3q1KmT2/UdOnTQV1995XFRAAAAwPV4FGTPnj2r8uXLu10fGBioM2fO3PB2Z8yYoTvvvFPly5dXpUqV1LNnT+3fv99pzoULFzR69GiFhYUpMDBQvXv31qlTp254XwAAALA2j4JslSpV9M0337hd/9VXX6ly5co3vN2kpCSNHj1a27Zt0+eff66cnBx17txZWVlZjjlPPvmk1qxZo2XLlikpKUknTpzQ/fff78nTAAAAgIV5dI1sv379NH36dDVv3lyPP/644xOrcnNz9Y9//EMff/yxnn322Rve7rp165yW58+fr0qVKmnHjh1q3bq10tPTNXfuXC1evFjt27eXJCUkJKhu3bratm2bWrZs6cnTAQAAgAV5FGQnT56sr7/+WuPGjdPLL7+s2rVrS5L279+v06dPq23bth4F2aulp6dLkkJDQyVJO3bsUE5Ojjp27OiYU6dOHVWpUkVbt251GWSzs7OVnZ3tWM7IyJAk2e122e32m67xeux2u4wxxbIvq6E3rtEX1+iLe/TGNfriHr1xjb64V9y9Keh+PAqyfn5+2rBhgxYsWKAVK1bo0KFDkqTmzZurd+/eGjRokOMsrafsdrvGjRunu+66Sw0aNJAkpaSkyNfX1/FpYnkiIiKUkpLicjszZszQ1KlT842fPn1aFy5cuKkaC8Jutys9PV3GmJvuya2G3rhGX1yjL+7RG9foi3v0xjX64l5x9yYzM7NA8zz+QAQvLy8NGTJEQ4YM8XQT1zR69GglJyfr66+/vqntTJ48WePHj3csZ2RkKCYmRuHh4QoKCrrZMq/LbrfLZrMpPDycH4qr0BvX6Itr9MU9euMafXGP3rhGX9wr7t74+/sXaJ5HQfa3337TL7/8okaNGrlcv3fvXlWuXFkhISGebF6PP/641q5dqy+//NLpTWORkZG6ePGi0tLSnM7Knjp1SpGRkS635efnJz8/v3zjXl5exXaQ2my2Yt2fldAb1+iLa/TFPXrjGn1xj964Rl/cK87eFHQfHlXy5JNPavjw4W7XjxgxQhMmTLjh7Rpj9Pjjj2vlypX64osvFBcX57S+adOmKlOmjDZt2uQY279/v44dO6b4+Pgb3h8AAACsy6Mzsl988YUee+wxt+u7d++ud95554a3O3r0aC1evFirV69W+fLlHde9BgcHKyAgQMHBwRo2bJjGjx+v0NBQBQUFacyYMYqPj+eOBQAAAH8wHgXZ06dPq2LFim7Xh4WFKTU19Ya3O2fOHElS27ZtncYTEhL08MMPS5Jee+01eXl5qXfv3srOzlaXLl309ttv3/C+AAAAYG0eBdmoqCjt2rXL7fodO3YoPDz8hrdrjLnuHH9/f82ePVuzZ8++4e0DAADg1uHRNbI9e/bU3Llz9c9//jPfutWrVyshIUG9evW66eIAAAAAdzw6I/viiy9q48aN6tWrlxo3buy4z2tycrL+/e9/q27dui7v3QoAAAAUFo/OyAYHB2vbtm167rnnlJOTo+XLl2v58uXKycnR888/r+3bt+f70AIAAACgMHn8gQjlypXT1KlT3Z55PXv2rMf3kQUAAACup1DvaJudna1ly5apZ8+eioqKKsxNAwAAAE48PiObxxijTZs2adGiRVq5cqUyMjIUHh6u/v37F0Z9AAAAgEseB9kdO3Zo0aJFWrp0qVJSUmSz2dS3b189/vjjatmypWw2W2HWCQAAADi5oSD7888/a9GiRVq0aJEOHDig2267TQMGDFDz5s3Vp08f9e7dm4+KBQAAQLEocJCNj4/Xt99+q4oVK+qBBx7QBx98oLvvvluSdOjQoSIrEAAAAHClwEF2+/btiouL09///nfdd9998vG56ctrAQAAAI8V+K4F//jHPxQVFaVevXopMjJSI0aM0ObNmwv0sbIAAABAYStwkB01apS+/vprHTp0SOPGjdNXX32lDh066LbbbtMLL7wgm83GG7wAAABQbG74PrJxcXF67rnn9MMPP+i7775T3759lZiYKGOMRo0apeHDh2vt2rW6cOFCUdQLAAAASLrJD0Ro2rSp/v73v+v48ePasGGDunTpoo8//lh//vOfVbFixcKqEQAAAMinUD7Zy8vLSx07dtT8+fN16tQpLVmyRB06dCiMTQMAAAAuFepH1EqSv7+/+vTpo9WrVxf2pgEAAACHQg+yAAAAQHEgyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALIkgCwAAAEsiyAIAAMCSCLIAAACwJIIsAAAALKlUBdkvv/xS3bt3V3R0tGw2m1atWuW0/uGHH5bNZnP66tq1a8kUCwAAgBJVqoJsVlaWGjdurNmzZ7ud07VrV508edLxtWTJkmKsEAAAAKWFT0kXcKVu3bqpW7du15zj5+enyMjIYqoIAAAApVWpCrIFkZiYqEqVKikkJETt27fXSy+9pLCwMLfzs7OzlZ2d7VjOyMiQJNntdtnt9iKv1263yxhTLPuyGnrjGn1xjb64R29coy/u0RvX6It7xd2bgu7HUkG2a9euuv/++xUXF6dDhw7p//yf/6Nu3bpp69at8vb2dvmYGTNmaOrUqfnGT58+rQsXLhR1ybLb7UpPT5cxRl5epepKjhJHb1yjL67RF/fojWv0xT164xp9ca+4e5OZmVmgeZYKsn379nX8u2HDhmrUqJGqV6+uxMREdejQweVjJk+erPHjxzuWMzIyFBMTo/DwcAUFBRV5zXa7XTabTeHh4fxQXIXeuEZfXKMv7tEb1+iLe/TGNfriXnH3xt/fv0DzLBVkr1atWjVVrFhRBw8edBtk/fz85Ofnl2/cy8ur2A5Sm81WrPuzEnrjGn1xjb64R29coy/u0RvX6It7xdmbgu7D0t+lX375RWfOnFFUVFRJlwIAAIBiVqrOyJ47d04HDx50LB8+fFi7d+9WaGioQkNDNXXqVPXu3VuRkZE6dOiQJk6cqBo1aqhLly4lWDUAAABKQqkKst9//73atWvnWM67tnXw4MGaM2eO9uzZowULFigtLU3R0dHq3Lmzpk+f7vLSAQAAANzaSlWQbdu2rYwxbtevX7++GKsBAABAaWbpa2QBAADwx0WQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBFkAAABYEkG2CNntdiUnJzu+7HZ7SZcEAABwyyhVQfbLL79U9+7dFR0dLZvNplWrVjmtN8bohRdeUFRUlAICAtSxY0cdOHCgZIq9ji1btmjgw0M1bMwEvbtgiYaNmaCBDw/Vli1bSro0AACAW0KpCrJZWVlq3LixZs+e7XL9q6++qjfffFPvvPOOtm/frnLlyqlLly66cOFCMVd6bVu2bNHE56fpp3P+qtp1uKp1HKCqXYdrf5a/Jj4/jTALAABQCHxKuoArdevWTd26dXO5zhij119/Xc8995x69OghSfrwww8VERGhVatWqW/fvsVZqlt2u12z33lP54OrqnH3ofKySd4+2QqOqqJGfxqqPWvn6e1331fLli3l5VWqfo8AAACwlFIVZK/l8OHDSklJUceOHR1jwcHBatGihbZu3eo2yGZnZys7O9uxnJGRIely4CyKa1aTk5P1n6MnVK3rcHnZJJuMJCObjLxsNlVt1kH7172v5ORkNWjQoND3byV2u13GGK4dvgp9cY2+uEdvXKMv7tEb1+iLe8Xdm4LuxzJBNiUlRZIUERHhNB4REeFY58qMGTM0derUfOOnT58ukksSUlNTVbVKjKpFh8rbJ1s2GQV758imy3E2LCpUtioxSk1NVWpqaqHv30rsdrvS09NljOHs9BXoi2v0xT164xp9cY/euEZf3Cvu3mRmZhZonmWCrKcmT56s8ePHO5YzMjIUExOj8PBwBQUFFfr+KlWqpCPHjksnflNwVBXZZGQknc7xk5FNaSdTdPTYcVWqVEmVKlUq9P1bid1ul81mU3h4OC8YV6AvrtEX9+iNa/TFPXrjGn1xr7h74+/vX6B5lgmykZGRkqRTp04pKirKMX7q1Ck1adLE7eP8/Pzk5+eXb9zLy6tIvhENGjRQrdho7f9+oxr9aai8bDZdvsDAJruRjny/SXWq3qYGDRrwQyLJZrMV2ffCyuiLa/TFPXrjGn1xj964Rl/cK87eFHQflvkuxcXFKTIyUps2bXKMZWRkaPv27YqPjy/Bypx5eXlp9Mjh8k87oj1r5ynt5FHl5lxU2smj2rN2nvzTjmjUiEf5AQEAALhJpeqM7Llz53Tw4EHH8uHDh7V7926FhoaqSpUqGjdunF566SXVrFlTcXFxev755xUdHa2ePXuWXNEutGrVSq9Of0Gz33lP/1n3vmxVYnT02HHVqXqbRj31glq1alXSJQIAAFheqQqy33//vdq1a+dYzru2dfDgwZo/f74mTpyorKwsDR8+XGlpabr77ru1bt26Al9HUZxatWqlli1bKjk5WampqapUqRKXEwAAABSiUhVk27ZtK2OM2/U2m03Tpk3TtGnTirEqz3l5ealBgwaOIEuIBQAAKDwkKwAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFgSQRYAAACWRJAFAACAJRFkAQAAYEkEWQAAAFiST0kXUNyMMZKkjIyMYtmf3W5XZmam/P395eXF7w1Xojeu0RfX6It79MY1+uIevXGNvrhX3L3Jy2l5uc2dP1yQzczMlCTFxMSUcCUAAAC4lszMTAUHB7tdbzPXi7q3GLvdrhMnTqh8+fKy2WxFvr+MjAzFxMTo+PHjCgoKKvL9WQm9cY2+uEZf3KM3rtEX9+iNa/TFveLujTFGmZmZio6OvuYZ4D/cGVkvLy9Vrly52PcbFBTED4Ub9MY1+uIafXGP3rhGX9yjN67RF/eKszfXOhObhwtAAAAAYEkEWQAAAFgSQbaI+fn5acqUKfLz8yvpUkodeuMafXGNvrhHb1yjL+7RG9foi3ultTd/uDd7AQAA4NbAGVkAAABYEkEWAAAAlkSQBQAAgCURZAEAAGBJBNkb8OWXX6p79+6Kjo6WzWbTqlWrrvuYxMRE3XHHHfLz81ONGjU0f/78fHNmz56tqlWryt/fXy1atNC3335b+MUXsRvtzYoVK9SpUyeFh4crKChI8fHxWr9+vdOcF198UTabzemrTp06RfgsCt+N9iUxMTHfc7bZbEpJSXGa90c8Zh5++GGXvalfv75jzq1wzMyYMUN33nmnypcvr0qVKqlnz57av3//dR+3bNky1alTR/7+/mrYsKE+++wzp/XGGL3wwguKiopSQECAOnbsqAMHDhTV0yh0nvTl/fff1z333KOQkBCFhISoY8eO+X5WXB1XXbt2LcqnUqg86cv8+fPzPWd/f3+nOVY/XiTPetO2bVuXrzP33XefY47Vj5k5c+aoUaNGjg82iI+P17/+9a9rPqY0v74QZG9AVlaWGjdurNmzZxdo/uHDh3XfffepXbt22r17t8aNG6dHHnnEKbB9/PHHGj9+vKZMmaKdO3eqcePG6tKli1JTU4vqaRSJG+3Nl19+qU6dOumzzz7Tjh071K5dO3Xv3l27du1ymle/fn2dPHnS8fX1118XRflF5kb7kmf//v1Oz7tSpUqOdX/UY+aNN95w6snx48cVGhqqv/zlL07zrH7MJCUlafTo0dq2bZs+//xz5eTkqHPnzsrKynL7mC1btqhfv34aNmyYdu3apZ49e6pnz55KTk52zHn11Vf15ptv6p133tH27dtVrlw5denSRRcuXCiOp3XTPOlLYmKi+vXrp82bN2vr1q2KiYlR586d9d///tdpXteuXZ2OmSVLlhT10yk0nvRFuvzpTFc+56NHjzqtt/rxInnWmxUrVjj1JTk5Wd7e3vleZ6x8zFSuXFkzZ87Ujh079P3336t9+/bq0aOH9u3b53J+qX99MfCIJLNy5cprzpk4caKpX7++01ifPn1Mly5dHMvNmzc3o0ePdizn5uaa6OhoM2PGjEKttzgVpDeu1KtXz0ydOtWxPGXKFNO4cePCK6yEFaQvmzdvNpLM2bNn3c7hmLls5cqVxmazmSNHjjjGbrVjxhhjUlNTjSSTlJTkds6DDz5o7rvvPqexFi1amBEjRhhjjLHb7SYyMtL89a9/daxPS0szfn5+ZsmSJUVTeBErSF+udunSJVO+fHmzYMECx9jgwYNNjx49iqDCklGQviQkJJjg4GC362/F48UYz46Z1157zZQvX96cO3fOMXarHTPGGBMSEmI++OADl+tK++sLZ2SL0NatW9WxY0ensS5dumjr1q2SpIsXL2rHjh1Oc7y8vNSxY0fHnD8Ku92uzMxMhYaGOo0fOHBA0dHRqlatmgYMGKBjx46VUIXFq0mTJoqKilKnTp30zTffOMY5Zv6/uXPnqmPHjoqNjXUav9WOmfT0dEnK97Nxpeu91hw+fFgpKSlOc4KDg9WiRQvLHjcF6cvVfv/9d+Xk5OR7TGJioipVqqTatWvrscce05kzZwq11uJU0L6cO3dOsbGxiomJyXc27lY8XiTPjpm5c+eqb9++KleunNP4rXLM5ObmaunSpcrKylJ8fLzLOaX99YUgW4RSUlIUERHhNBYREaGMjAydP39ev/76q3Jzc13OufqayFvdrFmzdO7cOT344IOOsRYtWmj+/Plat26d5syZo8OHD+uee+5RZmZmCVZatKKiovTOO+/o008/1aeffqqYmBi1bdtWO3fulCSOmf914sQJ/etf/9IjjzziNH6rHTN2u13jxo3TXXfdpQYNGrid5+61Ju+YyPvvrXLcFLQvV3vmmWcUHR3t9D/crl276sMPP9SmTZv0yiuvKCkpSd26dVNubm5RlF6kCtqX2rVra968eVq9erU++ugj2e12tWrVSr/88oukW+94kTw7Zr799lslJyfne525FY6ZvXv3KjAwUH5+fho5cqRWrlypevXquZxb2l9ffIp8D8B1LF68WFOnTtXq1audrgXt1q2b49+NGjVSixYtFBsbq08++UTDhg0riVKLXO3atVW7dm3HcqtWrXTo0CG99tprWrhwYQlWVrosWLBAFSpUUM+ePZ3Gb7VjZvTo0UpOTrbcdb5FzZO+zJw5U0uXLlViYqLTG5v69u3r+HfDhg3VqFEjVa9eXYmJierQoUOh1l3UCtqX+Ph4p7NvrVq1Ut26dfXuu+9q+vTpRV1mifDkmJk7d64aNmyo5s2bO43fCsdM7dq1tXv3bqWnp2v58uUaPHiwkpKS3IbZ0owzskUoMjJSp06dcho7deqUgoKCFBAQoIoVK8rb29vlnMjIyOIstcQsXbpUjzzyiD755JN8f7q4WoUKFVSrVi0dPHiwmKorHZo3b+54zhwzl98dO2/ePA0cOFC+vr7XnGvlY+bxxx/X2rVrtXnzZlWuXPmac9291uQdE3n/vRWOmxvpS55Zs2Zp5syZ2rBhgxo1anTNudWqVVPFihUtd8x40pc8ZcqU0e233+54zrfS8SJ51pusrCwtXbq0QL8AW/GY8fX1VY0aNdS0aVPNmDFDjRs31htvvOFybml/fSHIFqH4+Hht2rTJaezzzz93/Cbs6+urpk2bOs2x2+3atGmT22tVbiVLlizRkCFDtGTJEqdbm7hz7tw5HTp0SFFRUcVQXemxe/dux3P+ox8z0uV3Ih88eLBA/4Ox4jFjjNHjjz+ulStX6osvvlBcXNx1H3O915q4uDhFRkY6zcnIyND27dstc9x40hfp8rupp0+frnXr1qlZs2bXnf/LL7/ozJkzljlmPO3LlXJzc7V3717Hc74Vjhfp5nqzbNkyZWdn66GHHrruXKsdM67Y7XZlZ2e7XFfqX1+K/O1kt5DMzEyza9cus2vXLiPJ/P3vfze7du0yR48eNcYYM2nSJDNw4EDH/J9//tmULVvWPP300+bHH380s2fPNt7e3mbdunWOOUuXLjV+fn5m/vz55ocffjDDhw83FSpUMCkpKcX+/G7GjfZm0aJFxsfHx8yePducPHnS8ZWWluaY89RTT5nExERz+PBh880335iOHTuaihUrmtTU1GJ/fp660b689tprZtWqVebAgQNm79695oknnjBeXl5m48aNjjl/1GMmz0MPPWRatGjhcpu3wjHz2GOPmeDgYJOYmOj0s/H777875gwcONBMmjTJsfzNN98YHx8fM2vWLPPjjz+aKVOmmDJlypi9e/c65sycOdNUqFDBrF692uzZs8f06NHDxMXFmfPnzxfr8/OUJ32ZOXOm8fX1NcuXL3d6TGZmpjHm8jE4YcIEs3XrVnP48GGzceNGc8cdd5iaNWuaCxcuFPtz9IQnfZk6dapZv369OXTokNmxY4fp27ev8ff3N/v27XPMsfrxYoxnvclz9913mz59+uQbvxWOmUmTJpmkpCRz+PBhs2fPHjNp0iRjs9nMhg0bjDHWe30hyN6AvFsjXf01ePBgY8zlW3K0adMm32OaNGlifH19TbVq1UxCQkK+7b711lumSpUqxtfX1zRv3txs27at6J9MIbvR3rRp0+aa8425fKuyqKgo4+vra2677TbTp08fc/DgweJ9YjfpRvvyyiuvmOrVqxt/f38TGhpq2rZta7744ot82/0jHjPGXL6lS0BAgHnvvfdcbvNWOGZc9USS02tHmzZtnH5WjDHmk08+MbVq1TK+vr6mfv365n/+53+c1tvtdvP888+biIgI4+fnZzp06GD2799fDM+ocHjSl9jYWJePmTJlijHGmN9//9107tzZhIeHmzJlypjY2Fjz6KOPWuqXQk/6Mm7cOMfrR0REhLn33nvNzp07nbZr9ePFGM9/ln766ScjyRHsrnQrHDNDhw41sbGxxtfX14SHh5sOHTo4PVervb7YjDGmkE7uAgAAAMWGa2QBAABgSQRZAAAAWBJBFgAAAJZEkAUAAIAlEWQBAABgSQRZAAAAWBJBFgAAAJZEkAUAAIAlEWQB4BZTtWpV/elPf/L48fPnz5fNZtORI0cKrygAKAIEWQAoBHnh7/vvvy/pUgDgD4MgCwAAAEsiyAIAAMCSCLIAUAwuXryoF154QU2bNlVwcLDKlSune+65R5s3b3aad+TIEdlsNs2aNUuzZ89WtWrVVLZsWXXu3FnHjx+XMUbTp09X5cqVFRAQoB49eui3335zuc8NGzaoSZMm8vf3V7169bRixYp8c/bt26f27dsrICBAlStX1ksvvSS73Z5v3urVq3XfffcpOjpafn5+ql69uqZPn67c3NzCaRAAeMBmjDElXQQAWN38+fM1ZMgQfffdd2rWrFm+9b/++qsaNWqkfv36qWbNmsrMzNTcuXP1888/69tvv1WTJk0kXQ6ycXFxatKkiS5evKhHHnlEv/32m1599VXdcccdat++vRITE9W3b18dPHhQb731lh5++GHNmzfPsa+qVavKz89PqampGjlypCpVqqSEhATt27dP69atU6dOnSRJKSkpatSokS5duqQnnnhC5cqV03vvvaeAgADt2bNHhw8fVtWqVSVJvXr1kq+vr+68804FBgbqiy++0LJlyzRhwgT99a9/LfL+AoBLBgBw0xISEowk891337lcf+nSJZOdne00dvbsWRMREWGGDh3qGDt8+LCRZMLDw01aWppjfPLkyUaSady4scnJyXGM9+vXz/j6+poLFy44xmJjY40k8+mnnzrG0tPTTVRUlLn99tsdY+PGjTOSzPbt2x1jqampJjg42Egyhw8fdoz//vvv+Z7TiBEjTNmyZZ32DQDFiUsLAKAYeHt7y9fXV5Jkt9v122+/6dKlS2rWrJl27tyZb/5f/vIXBQcHO5ZbtGghSXrooYfk4+PjNH7x4kX997//dXp8dHS0evXq5VgOCgrSoEGDtGvXLqWkpEiSPvvsM7Vs2VLNmzd3zAsPD9eAAQPy1RMQEOD4d2Zmpn799Vfdc889+v333/XTTz/dUC8AoLAQZAGgmCxYsECNGjWSv7+/wsLCFB4erv/5n/9Renp6vrlVqlRxWs4LtTExMS7Hz5496zReo0YN2Ww2p7FatWpJkuP+sEePHlXNmjXz7bt27dr5xvbt26devXopODhYQUFBCg8P10MPPSRJLusHgOLgc/0pAICb9dFHH+nhhx9Wz5499fTTT6tSpUry9vbWjBkzdOjQoXzzvb29XW7H3bgpwrc7pKWlqU2bNgoKCtK0adNUvXp1+fv7a+fOnXrmmWdcvjkMAIoDQRYAisHy5ctVrVo1rVixwulM6ZQpU4pkfwcPHpQxxmlf//nPfyTJ8Qau2NhYHThwIN9j9+/f77ScmJioM2fOaMWKFWrdurVj/PDhw0VQOQAUHJcWAEAxyDuTeuWZ0+3bt2vr1q1Fsr8TJ05o5cqVjuWMjAx9+OGHatKkiSIjIyVJ9957r7Zt26Zvv/3WMe/06dNatGjRdWu/ePGi3n777SKpHQAKijOyAFCI5s2bp3Xr1uUbb9u2rVasWKFevXrpvvvu0+HDh/XOO++oXr16OnfuXKHXUatWLQ0bNkzfffedIiIiNG/ePJ06dUoJCQmOORMnTtTChQvVtWtXp9tvxcbGas+ePY55rVq1UkhIiAYPHqyxY8fKZrNp4cKFRXo5AwAUBEEWAArRnDlzXI4fO3ZM586d07vvvqv169erXr16+uijj7Rs2TIlJiYWeh01a9bUW2+9paefflr79+9XXFycPv74Y3Xp0sUxJyoqSps3b9aYMWM0c+ZMhYWFaeTIkYqOjtawYcMc88LCwrR27Vo99dRTeu655xQSEqKHHnpIHTp0cNoeABQ3PhABAAAAlsQ1sgAAALAkgiwAAAAsiSALAAAASyLIAgAAwJIIsgAAALAkgiwAAAAsiSALAAAASyLIAgAAwJIIsgAAALAkgiwAAAAsiSALAAAASyLIAgAAwJL+H7PAGYfqJ5AHAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plotting lambda against access_count.\n", "\n", "plt.figure(figsize=(8, 6))\n", "plt.scatter(merged['lambda'], merged['access_count'], alpha=0.7, edgecolor='k')\n", "plt.title('Lambda vs Access Count', fontsize=14)\n", "plt.xlabel('Lambda', fontsize=12)\n", "plt.ylabel('Access Count', fontsize=12)\n", "plt.grid(alpha=0.3)\n", "\n", "plt.savefig(f\"{TEMP_BASE_DIR}/lambda_vs_access_count.pdf\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 16, "id": "00a12eea-c805-4209-9143-48fa65619873", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAArMAAAIjCAYAAAAQgZNYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABFkklEQVR4nO3deVyVZf7/8fdB5YALWwi4kAuY5pIYpoKjOA5pZiXlZDFNuFVWOuU4lVJNmpbYbovlWKkt49i41jSpmWsuWSrmWikDWgYqLuBSqHD9/ujH+XrioHA8nMNtr+fjcR4Pz3Vf931/7osbeHtz3fexGWOMAAAAAAvy83UBAAAAgLsIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswB+U7766islJiaqTp06stls2rJli69LctK0aVPdcMMNvi7DbTabTePGjavy/fTo0UM9evRwvF+5cqVsNpvmzp17Udt99tln1apVK5WUlFxkhb4xbtw42Ww2j27z12O9c+dO1axZU9u3b/fofgB3EWaBKrBjxw79+c9/VqNGjWS329WwYUPdcccd2rFjh69L+007c+aMbr31Vh05ckQvvfSS3nvvPTVp0sTXZaGaKCws1DPPPKPRo0fLz49fj+Vp3bq1+vbtqyeeeMLXpQCSpJq+LgC41MyfP1+pqakKCwvT0KFD1axZM+Xk5Ojtt9/W3LlzNXv2bN18882+LvM3KSsrS3v37tWbb76pu+66y9flXJJ++ukn1axpzV8t06dP19mzZ5WamurrUqq9e++9V9dff72ysrIUExPj63LwG2fNnzhANZWVlaU777xTzZs31+rVq1W/fn3HsgcffFDdunXTnXfeqa1bt6p58+Y+rLSsU6dOqXbt2r4uo0odPHhQkhQSEuLbQi5hAQEBvi7BbTNmzNBNN910wWM4e/asSkpK5O/v76XKqp/k5GSFhobqnXfe0fjx431dDn7j+DsK4EHPPfecTp06pWnTpjkFWUkKDw/XP/7xD508eVLPPvus07L9+/dr6NChatiwoex2u5o1a6b77rtPp0+fdvQ5duyY/vrXv6pp06ay2+1q3Lix0tLSlJ+fL0maOXOmbDabcnJynLZdOpdw5cqVjrYePXqobdu22rRpk7p3767atWvr0UcflSR9+OGH6tu3r6OWmJgYTZgwQcXFxU7bLd3Gzp079fvf/161a9dWo0aNyhybJP38888aN26crrjiCgUEBKhBgwa65ZZblJWV5ehTUlKiyZMnq02bNgoICFBkZKSGDRumo0ePVmjsly9frm7duqlOnToKCQlRv379tGvXLsfyQYMGKSkpSZJ06623ymazOc0DdOXYsWMaOXKkoqOjZbfbFRsbq2eeeabMfMrnn39eiYmJuuyyyxQYGKj4+Phy526+//776tSpk2rXrq3Q0FB1795dn376aZl+a9asUadOnRQQEKDmzZvr3XffveAY5OTkyGaz6fnnn9eUKVPUvHlz1a5dW7169dL3338vY4wmTJigxo0bKzAwUP369dORI0ectlHenNemTZtq0KBBF6zh1+uXzuHcs2ePBg0apJCQEAUHB2vw4ME6derUBbcnSdOmTVNMTIwCAwPVqVMnff755+X2LS4u1qOPPqqoqCjVqVNHN910k77//vsL7iM7O1tbt25VcnKyU/u5Yzp58mTFxMTIbrdr586dki583km/nHtNmzYts09X81ttNptGjBihhQsXqm3btrLb7WrTpo0WL15cZv01a9bommuuUUBAgGJiYvSPf/yj3ON7//33FR8fr8DAQIWFhen22293OS4VHetatWqpR48e+vDDD8vdJ+AtXJkFPOg///mPmjZtqm7durlc3r17dzVt2lT//e9/HW0//vijOnXqpGPHjumee+5Rq1attH//fs2dO1enTp2Sv7+/Tpw4oW7dumnXrl0aMmSIrr76auXn5+ujjz7SDz/8oPDw8ErXevjwYfXp00e33367/vznPysyMlLSL6G4bt26GjVqlOrWravly5friSeeUGFhoZ577jmnbRw9elTXXXedbrnlFg0YMEBz587V6NGj1a5dO/Xp00fSL+Hihhtu0LJly3T77bfrwQcf1PHjx7V06VJt377d8SfKYcOGaebMmRo8eLAeeOABZWdn67XXXlNmZqbWrl2rWrVqlXssn332mfr06aPmzZtr3Lhx+umnn/Tqq6+qa9eu2rx5s5o2baphw4apUaNGmjhxoh544AFdc801jmN25dSpU0pKStL+/fs1bNgwXX755Vq3bp3S09OVm5uryZMnO/q+/PLLuummm3THHXfo9OnTmj17tm699VZ9/PHH6tu3r6Pfk08+qXHjxikxMVHjx4+Xv7+/NmzYoOXLl6tXr16Ofnv27NEf//hHDR06VAMHDtT06dM1aNAgxcfHq02bNhf82v7zn//U6dOn9Ze//EVHjhzRs88+qwEDBqhnz55auXKlRo8erT179ujVV1/VQw89pOnTp19wmxdrwIABatasmTIyMrR582a99dZbioiI0DPPPHPe9d5++20NGzZMiYmJGjlypP73v//ppptuUlhYmKKjo8v0f/rpp2Wz2TR69GgdPHhQkydPVnJysrZs2aLAwMBy97Nu3TpJ0tVXX+1y+YwZM/Tzzz/rnnvukd1uV1hYWIXOO3esWbNG8+fP1/3336969erplVdeUf/+/bVv3z5ddtllkqRt27apV69eql+/vsaNG6ezZ89q7NixLs/pp59+Wn//+981YMAA3XXXXTp06JBeffVVde/eXZmZmY6/VFR2rOPj4/Xhhx+qsLBQQUFBbh0r4BEGgEccO3bMSDL9+vU7b7+bbrrJSDKFhYXGGGPS0tKMn5+f+eqrr8r0LSkpMcYY88QTTxhJZv78+eX2mTFjhpFksrOznZavWLHCSDIrVqxwtCUlJRlJZurUqWW2d+rUqTJtw4YNM7Vr1zY///xzmW28++67jraioiITFRVl+vfv72ibPn26kWRefPHFcmv//PPPjSTzz3/+02n54sWLXbb/WlxcnImIiDCHDx92tH399dfGz8/PpKWlOdpKx2LOnDnn3Z4xxkyYMMHUqVPHfPfdd07tY8aMMTVq1DD79u1ztP16zE6fPm3atm1revbs6WjbvXu38fPzMzfffLMpLi526l86DsYY06RJEyPJrF692tF28OBBY7fbzd/+9rfz1pydnW0kmfr165tjx4452tPT040k0759e3PmzBlHe2pqqvH393f6ukoyY8eOLbPtJk2amIEDB553/67WHzt2rJFkhgwZ4tTv5ptvNpdddtl5t3X69GkTERFh4uLiTFFRkaN92rRpRpJJSkpytJV+bRs1auT43jLGmH//+99Gknn55ZfPu6/HH3/cSDLHjx93ai8d06CgIHPw4EGnZRU97wYOHGiaNGlSZp+lY3MuScbf39/s2bPHaZuSzKuvvupoS0lJMQEBAWbv3r2Otp07d5oaNWo4bTMnJ8fUqFHDPP3000772bZtm6lZs6ajvTJjXWrWrFlGktmwYUOZZYA3Mc0A8JDjx49LkurVq3fefqXLCwsLVVJSooULF+rGG29Ux44dy/Qt/RPkvHnz1L59e5c3jrn7GB673a7BgweXaT/36tXx48eVn5+vbt266dSpU/rmm2+c+tatW1d//vOfHe/9/f3VqVMn/e9//3O0zZs3T+Hh4frLX/5Sbu1z5sxRcHCwrr32WuXn5zte8fHxqlu3rlasWFHuceTm5mrLli0aNGiQwsLCHO1XXXWVrr32Wn3yyScVGI2y5syZo27duik0NNSppuTkZBUXF2v16tWOvueO2dGjR1VQUKBu3bpp8+bNjvaFCxeqpKRETzzxRJk75X/9NWzdurXT1f369eurZcuWTuN6PrfeequCg4Md7zt37ixJ+vOf/+x0c1bnzp11+vRp7d+/v0LbvRj33nuv0/tu3brp8OHDKiwsLHedjRs36uDBg7r33nud5qcOGjTI6fjOlZaW5vQ9+Mc//lENGjS44Hlw+PBh1axZU3Xr1nW5vH///k5Th6rqvJN+mY967k1VV111lYKCghxf/+LiYi1ZskQpKSm6/PLLHf2uvPJK9e7d22lb8+fPV0lJiQYMGOB0HkdFRalFixaO7y13xjo0NFSSHFOdAF9hmgHgIaW/QEtDbXnODb2HDh1SYWGh2rZte951srKy1L9/f88U+v81atTI5Q0sO3bs0OOPP67ly5eXCRoFBQVO7xs3blwmiIWGhmrr1q2O91lZWWrZsuV573DfvXu3CgoKFBER4XJ56Y1bruzdu1eS1LJlyzLLrrzySi1ZskQnT55UnTp1yt1GeTVt3bq1zNxnVzV9/PHHeuqpp7RlyxYVFRU52s8dm6ysLPn5+al169YX3Pe5AaVUaGhohecP/3r90jDy6z8Vl7ZXdLsX49c1lQaho0ePlvsn6tKvbYsWLZzaa9WqVe4NlL/ua7PZFBsbW2YueWU1a9bMZW2ePu+kC3/9Dx06pJ9++qnMsZbWc26Q3r17t4wxLvtKckzfcWesjTGS3P8PNeAphFnAQ4KDg9WgQQOnIOfK1q1b1ahRIwUFBemnn37y2P7L+4Xy6xu3SrmaP3js2DElJSUpKChI48ePV0xMjAICArR582aNHj26zI1PNWrUcLnt0l9yFVVSUqKIiAj985//dLm8vEBZlUpKSnTttdfqkUcecbn8iiuukCR9/vnnuummm9S9e3e9/vrratCggWrVqqUZM2Zo1qxZbu37Yse1vPUvZrvlnUcV5alzpapcdtllOnv2rI4fP+7yryvnm297IZX93vTkWJWUlMhms2nRokUut1veleiKKA3X7szZBzyJMAt40A033KA333xTa9as0e9+97syyz///HPl5ORo2LBhkn4JaUFBQRf8JJ2YmJgL9im90nXs2DGn9tIrLhWxcuVKHT58WPPnz1f37t0d7dnZ2RXexq/FxMRow4YNOnPmTLk3ccXExOizzz5T165dKx0aSj/04Ntvvy2z7JtvvlF4eLhbV8diYmJ04sSJMne3/9q8efMUEBCgJUuWyG63O9pnzJhRZnslJSXauXOn4uLiKl2Pt4SGhpY5h06fPq3c3Fyv11L6td29e7d69uzpaD9z5oyys7PVvn37Muvs3r3b6b0xRnv27NFVV1113n21atVK0i/n+oX6nltbRc47V2MqVe5781z169dXYGBgmWN1VU9MTIyMMWrWrJnjP2CuuDPW2dnZ8vPzO+92AW9gzizgQQ8//LACAwM1bNgwHT582GnZkSNHdO+996p27dp6+OGHJUl+fn5KSUnRf/7zH23cuLHM9kqvxPTv319ff/21FixYUG6f0jl2587lLC4u1rRp0ypcf+mVm3OvAJ0+fVqvv/56hbfxa/3791d+fr5ee+21MstK9zNgwAAVFxdrwoQJZfqcPXvWZRAo1aBBA8XFxemdd95x6rd9+3Z9+umnuv76692qe8CAAVq/fr2WLFlSZtmxY8d09uxZSb+Mmc1mc7rKlpOTo4ULFzqtk5KSIj8/P40fP77MFe7qcnVS+uU8Ovcckn55XNPFXpl1R8eOHVW/fn1NnTrV6TF1M2fOLPecePfdd52m+sydO1e5ubmOp2uUJyEhQZJcfh+6UpnzLiYmRgUFBU5/tcnNzXX5/VwRNWrUUO/evbVw4ULt27fP0b5r164y5+stt9yiGjVq6MknnyxznhljHD+n3BnrTZs2qU2bNuXOqQW8hSuzgAe1aNFC77zzju644w61a9euzCeA5efn61//+pfTzR0TJ07Up59+qqSkJN1zzz268sorlZubqzlz5mjNmjUKCQnRww8/rLlz5+rWW2/VkCFDFB8fryNHjuijjz7S1KlT1b59e7Vp00ZdunRRenq6jhw5orCwMM2ePdsRuioiMTFRoaGhGjhwoB544AHZbDa99957FxW20tLS9O67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Ulpamho1aqSMjAxJ0oMPPqikpCS98MIL6tu3r2bPnq2NGzdq2rRpvjwMAAAA+IhPw+zBgweVlpam3NxcBQcH66qrrtKSJUt07bXXSpL27dsnP7//u3icmJioWbNm6fHHH9ejjz6qFi1aaOHChWrbtq2vDgEAAAA+VO2eM1vVfPGcWZ5mAAAArM6bTzOw5HNmAQAAgMoizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyCLMAAACwLMIsAAAALIswCwAAAMsizAIAAMCyfBpmMzIydM0116hevXqKiIhQSkqKvv322/OuM3PmTNlsNqdXQECAlyoGAABAdeLTMLtq1SoNHz5cX3zxhZYuXaozZ86oV69eOnny5HnXCwoKUm5uruO1d+9eL1UMAACA6qSmL3e+ePFip/czZ85URESENm3apO7du5e7ns1mU1RUVFWXBwAAgGquWs2ZLSgokCSFhYWdt9+JEyfUpEkTRUdHq1+/ftqxY0e5fYuKilRYWOj0AgAAwKWh2oTZkpISjRw5Ul27dlXbtm3L7deyZUtNnz5dH374od5//32VlJQoMTFRP/zwg8v+GRkZCg4Odryio6Or6hAAAADgZTZjjPF1EZJ03333adGiRVqzZo0aN25c4fXOnDmjK6+8UqmpqZowYUKZ5UVFRSoqKnK8LywsVHR0tAoKChQUFOSR2i9kUma+V/YDAABQVcZ0CPfavgoL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AFSEW2G2e/fuysjIcAquxcXFysjI0O9+9zuPFQcAAACcj1tPM3jmmWfUvXt3tWzZUt26dZMkff755yosLNTy5cs9WiAAAABQHreuzLZu3Vpbt27VgAEDdPDgQR0/flxpaWn65ptv1LZtW0/XCAAAALjk9sfZNmzYUBMnTvRkLQAAAECluHVldsaMGZozZ06Z9jlz5uidd9656KIAAACAinArzGZkZCg8vOzn80ZERHC1FgAAAF7jVpjdt2+fmjVrVqa9SZMm2rdv30UXBQAAAFSEW2E2IiJCW7duLdP+9ddf67LLLrvoogAAAICKcCvMpqam6oEHHtCKFStUXFys4uJiLV++XA8++KBuv/12T9cIAAAAuOTW0wwmTJignJwc/eEPf1DNmr9sori4WAMHDmTOLAAAALzGrTDr7++vDz74QA899JBycnIUGBiodu3aqUmTJp6uDwAAAChXpcPssWPH9Nhjj+mDDz7Q0aNHJUmhoaG6/fbb9dRTTykkJMTTNQIAAAAuVSrMHjlyRAkJCdq/f7/uuOMOXXnllZKknTt3aubMmVq2bJnWrVun0NDQKikWAAAAOFelwuz48ePl7++vrKwsRUZGllnWq1cvjR8/Xi+99JJHiwQAAABcqdTTDBYuXKjnn3++TJCVpKioKD377LNasGCBx4oDAAAAzqdSYTY3N1dt2rQpd3nbtm2Vl5d30UUBAAAAFVGpMBseHq6cnJxyl2dnZyssLOxiawIAAAAqpFJhtnfv3nrsscd0+vTpMsuKior097//Xdddd53HigMAAADOp9I3gHXs2FEtWrTQ8OHD1apVKxljtGvXLr3++usqKirSe++9V1W1AgAAAE4qFWYbN26s9evX6/7771d6erqMMZIkm82ma6+9Vq+99pqio6OrpFAAAADg1yr9oQnNmjXTokWLdPToUe3evVuSFBsby1xZAAAAeJ1bH2cr/fKpX506dfJkLQAAAEClVOoGMAAAAKA6IcwCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsgizAAAAsCzCLAAAACyLMAsAAADLIswCAADAsnwaZlevXq0bb7xRDRs2lM1m08KFCy+4zsqVK3X11VfLbrcrNjZWM2fOrPI6AQAAUD35NMyePHlS7du315QpUyrUPzs7W3379tXvf/97bdmyRSNHjtRdd92lJUuWVHGlAAAAqI5q+nLnffr0UZ8+fSrcf+rUqWrWrJleeOEFSdKVV16pNWvW6KWXXlLv3r2rqkwAAABUU5aaM7t+/XolJyc7tfXu3Vvr168vd52ioiIVFhY6vQAAAHBpsFSYzcvLU2RkpFNbZGSkCgsL9dNPP7lcJyMjQ8HBwY5XdHS0N0oFAACAF1gqzLojPT1dBQUFjtf333/v65IAAADgIT6dM1tZUVFROnDggFPbgQMHFBQUpMDAQJfr2O122e12b5QHAAAAL7PUldmEhAQtW7bMqW3p0qVKSEjwUUUAAADwJZ+G2RMnTmjLli3asmWLpF8evbVlyxbt27dP0i9TBNLS0hz97733Xv3vf//TI488om+++Uavv/66/v3vf+uvf/2rL8oHAACAj/k0zG7cuFEdOnRQhw4dJEmjRo1Shw4d9MQTT0iScnNzHcFWkpo1a6b//ve/Wrp0qdq3b68XXnhBb731Fo/lAgAA+I2yGWOMr4vwpsLCQgUHB6ugoEBBQUFe2eekzHyv7AcAAKCqjOkQ7rV9VSavWWrOLAAAAHAuwiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsq1qE2SlTpqhp06YKCAhQ586d9eWXX5bbd+bMmbLZbE6vgIAAL1YLAACA6sLnYfaDDz7QqFGjNHbsWG3evFnt27dX7969dfDgwXLXCQoKUm5uruO1d+9eL1YMAACA6sLnYfbFF1/U3XffrcGDB6t169aaOnWqateurenTp5e7js1mU1RUlOMVGRnpxYoBAABQXfg0zJ4+fVqbNm1ScnKyo83Pz0/Jyclav359ueudOHFCTZo0UXR0tPr166cdO3aU27eoqEiFhYVOLwAAAFwafBpm8/PzVVxcXObKamRkpPLy8lyu07JlS02fPl0ffvih3n//fZWUlCgxMVE//PCDy/4ZGRkKDg52vKKjoz1+HAAAAPANn08zqKyEhASlpaUpLi5OSUlJmj9/vurXr69//OMfLvunp6eroKDA8fr++++9XDEAAACqSk1f7jw8PFw1atTQgQMHnNoPHDigqKioCm2jVq1a6tChg/bs2eNyud1ul91uv+haAQAAUP349Mqsv7+/4uPjtWzZMkdbSUmJli1bpoSEhApto7i4WNu2bVODBg2qqkwAAABUUz69MitJo0aN0sCBA9WxY0d16tRJkydP1smTJzV48GBJUlpamho1aqSMjAxJ0vjx49WlSxfFxsbq2LFjeu6557R3717dddddvjwMAAAA+IDPw+xtt92mQ4cO6YknnlBeXp7i4uK0ePFix01h+/btk5/f/11APnr0qO6++27l5eUpNDRU8fHxWrdunVq3bu2rQwAAAICP2IwxxtdFeFNhYaGCg4NVUFCgoKAgr+xzUma+V/YDAABQVcZ0CPfaviqT1yz3NAMAAACgFGEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZhFkAAABYFmEWAAAAlkWYBQAAgGURZgEAAGBZ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/HzH8h49emjEiBEaOXKkwsPD1bt3b/cHAwA8jDALAFWsRo0amjhxol599VX98MMPbm9n+fLl+vHHH7V69Wq9+OKLGjt2rG644QaFhoZqw4YNuvfeezVs2LAy+3j44Yf1t7/9TZmZmUpISNCNN96ow4cPS5KOHTumnj17qkOHDtq4caMWL16sAwcOaMCAAU7beOedd+Tv76+1a9dq6tSpbh8DAHgaYRYAvODmm29WXFycxo4d6/Y2wsLC9Morr6hly5YaMmSIWrZsqVOnTunRRx9VixYtlJ6eLn9/f61Zs8ZpvREjRqh///668sor9cYbbyg4OFhvv/22JOm1115Thw4dNHHiRLVq1UodOnTQ9OnTtWLFCn333XeObbRo0ULPPvusWrZsqZYtW7p9DADgaYRZAPCSZ555Ru+884527drl1vpt2rSRn9///diOjIxUu3btHO9r1Kihyy67TAcPHnRaLyEhwfHvmjVrqmPHjo4avv76a61YsUJ169Z1vFq1aiVJysrKcqwXHx/vVs0AUNVq+roAAPit6N69u3r37q309HQNGjTI0e7n5ydjjFPfM2fOlFm/Vq1aTu9tNpvLtpKSkgrXdOLECd1444165plnyixr0KCB49916tSp8DYBwJsIswDgRZMmTVJcXJzTn+rr16+vvLw8GWMcj+vy5LNhv/jiC3Xv3l2SdPbsWW3atEkjRoyQJF199dWaN2+emjZtqpo1+ZUAwHqYZgAAXtSuXTvdcccdeuWVVxxtPXr00KFDh/Tss88qKytLU6ZM0aJFizy2zylTpmjBggX65ptvNHz4cB09elRDhgyRJA0fPlxHjhxRamqqvvrqK2VlZWnJkiUaPHiwiouLPVYDAFQVwiwAeNn48eOdpgJceeWVev311zVlyhS1b99eX375pR566CGP7W/SpEmaNGmS2rdvrzVr1uijjz5SeHi4JKlhw4Zau3atiouL1atXL7Vr104jR45USEiI0/xcAKiubObXE7UAAAAAi+C/3QAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAyyLMAgAAwLIIswAAALAswiwAAAAsizALAAAAy/p/TRFeN3wLz9UAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from collections import Counter\n", "# Count occurrences of each number\n", "count = Counter(np.array(list(db.mu_values.values())).round(0))\n", "\n", "# Separate the counts into two lists for plotting\n", "x = list(count.keys()) # List of unique numbers\n", "y = list(count.values()) # List of their respective counts\n", "\n", "# Plot the data\n", "plt.figure(figsize=(8, 6))\n", "plt.bar(x, y, color='skyblue')\n", "\n", "# Adding labels and title\n", "plt.xlabel('Number')\n", "plt.ylabel('Occurrences')\n", "plt.title('Occurance of each mu in db (rounded)')\n", "\n", "# Show the plot\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 17, "id": "adbfeb40-76bd-4224-ac45-65c7b2b2cb7b", "metadata": {}, "outputs": [], "source": [ "def plot_requests(object_id: int):\n", " mu = db.mu_values[object_id]\n", " lmb = db.lambda_values[object_id]\n", " rq_log = np.array(cache.request_log[object_id])\n", " df = rq_log[1:] - rq_log[:-1]\n", " pd.DataFrame(df, columns=[f\"{object_id}, mu:{mu:.2f}, lambda: {lmb:.2f}\"]).plot()" ] }, { "cell_type": "code", "execution_count": 18, "id": "1f550686-3463-4e50-be83-ceafb27512b0", "metadata": {}, "outputs": [], "source": [ "def print_rate(object_id: int):\n", " # Calculate time intervals between consecutive events\n", " intervals = np.diff(np.array(cache.request_log[object_id])) # Differences between each event time\n", " \n", " # Calculate the rate per second for each interval\n", " rates = 1 / intervals # Inverse of the time interval gives rate per second\n", " \n", " # Optional: Calculate the average event rate over all intervals\n", " average_rate = np.mean(rates)\n", " print(\"Average event rate per second:\", average_rate)\n", " print(\"The mu is: \", db.lambda_values[object_id])" ] }, { "cell_type": "code", "execution_count": 19, "id": "b47990b1-0231-43ac-8bc5-8340abe4a8b3", "metadata": {}, "outputs": [], "source": [ "# os.makedirs(EXPERIMENT_BASE_DIR, exist_ok=True)\n", "# folder_name = experiment_name.replace(\" \", \"_\").replace(\"(\", \"\").replace(\")\", \"\").replace(\".\", \"_\")\n", "# folder_path = os.path.join(EXPERIMENT_BASE_DIR, folder_name)\n", "# os.makedirs(folder_path, exist_ok=True)\n" ] }, { "cell_type": "code", "execution_count": 20, "id": "db83cad4-7cc6-4702-ae3a-d1af30a561d2", "metadata": {}, "outputs": [], "source": [ "# file_names = os.listdir(TEMP_BASE_DIR)\n", " \n", "# for file_name in file_names:\n", "# shutil.move(os.path.join(TEMP_BASE_DIR, file_name), folder_path)" ] } ], "metadata": { "kernelspec": { "display_name": "graphs", "language": "python", "name": "graphs" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.7" } }, "nbformat": 4, "nbformat_minor": 5 }