22c3e828b4
Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
1330 lines
185 KiB
Plaintext
1330 lines
185 KiB
Plaintext
{
|
||
"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",
|
||
"from dataclasses import dataclass, field\n",
|
||
"from typing import List, Union, Dict\n",
|
||
"\n",
|
||
"# Constants\n",
|
||
"SEED = 42\n",
|
||
"ACCESS_COUNT_LIMIT = 1000 # Total time to run the simulation\n",
|
||
"EXPERIMENT_BASE_DIR = \"./experiments/\"\n",
|
||
"TEMP_BASE_DIR = \"./.aoi_cache/\"\n",
|
||
"BASE_FILE = pd.read_csv(\"../calculated.csv\")\n",
|
||
"BASE_FILE.index += 1\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": "code",
|
||
"execution_count": 2,
|
||
"id": "d88effd8-d92b-47d1-9e15-527166073e81",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Types of cache\n",
|
||
"class EvictionStrategy(Enum):\n",
|
||
" LRU = 1\n",
|
||
" RANDOM_EVICTION = 2\n",
|
||
" TTL = 3"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "1d6a3c67-f9a5-4d9c-8ade-e1ca6944867c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"@dataclass\n",
|
||
"class DatabaseObject:\n",
|
||
" id: int\n",
|
||
" data: str\n",
|
||
" lambda_value: int\n",
|
||
" mu_value: Union[float, None]\n",
|
||
" ttl: Union[float, None]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "f40af914-a6c3-4e44-b7de-b3b40a743fb2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"@dataclass\n",
|
||
"class CacheObject:\n",
|
||
" id: int # id of object\n",
|
||
" data: DatabaseObject # body of object\n",
|
||
" initial_fetch_timer: float # time at which the object was initially pulled into the cache (object_start_time)\n",
|
||
" age_timer: float # time at which the object was last pulled into the cache (initial fetch)\n",
|
||
" next_refresh: Union[float, None] # scheduled time for the object to be requested (for refresh cache)\n",
|
||
" next_expiry: Union[float, None] # scheduled time for the object to be evicted (for ttl cache) (ttl)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "00a944e4-842b-49ba-bb36-587d9c12fdf4",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Base class for all cache types\n",
|
||
"@dataclass\n",
|
||
"class SimulationConfig:\n",
|
||
" db_objects: Union[int, List[DatabaseObject]]\n",
|
||
" cache_size: int\n",
|
||
" eviction_strategy: EvictionStrategy\n",
|
||
"\n",
|
||
" def __post_init__(self):\n",
|
||
" if not hasattr(self, 'eviction_strategy') or self.eviction_strategy is None:\n",
|
||
" raise ValueError(\"Eviction strategy must be defined in subclasses.\")\n",
|
||
" \n",
|
||
" def generate_objects(self):\n",
|
||
" if isinstance(self.db_objects, int):\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=np.random.zipf(ZIPF_CONSTANT), mu_value=None, ttl=None) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]\n",
|
||
"\n",
|
||
" def from_file(self, path: str, lambda_column_name: str):\n",
|
||
" df = pd.read_csv(path)\n",
|
||
" lambdas = df[lambda_column_name]\n",
|
||
"\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=lambdas[i], mu_value=None, ttl=None) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]\n",
|
||
" \n",
|
||
"# Specific cache type variants\n",
|
||
"@dataclass\n",
|
||
"class TTLSimulation(SimulationConfig):\n",
|
||
" eviction_strategy: EvictionStrategy = field(default=EvictionStrategy.TTL, init=False)\n",
|
||
" \n",
|
||
" def generate_objects(self, fixed_ttl):\n",
|
||
" if isinstance(self.db_objects, int):\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=np.random.zipf(ZIPF_CONSTANT), mu_value=None, ttl=fixed_ttl) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]\n",
|
||
" \n",
|
||
" def from_file(self, path: str, lambda_column_name: str, ttl_column_name: str):\n",
|
||
" df = pd.read_csv(path)\n",
|
||
" lambdas = df[lambda_column_name]\n",
|
||
" ttls = df[ttl_column_name]\n",
|
||
"\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=lambdas[i], mu_value=None, ttl=ttls[i]) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]\n",
|
||
" \n",
|
||
"@dataclass\n",
|
||
"class LRUSimulation(SimulationConfig):\n",
|
||
" eviction_strategy: EvictionStrategy = field(default=EvictionStrategy.LRU, init=False)\n",
|
||
"\n",
|
||
"@dataclass\n",
|
||
"class RandomEvictionSimulation(SimulationConfig):\n",
|
||
" eviction_strategy: EvictionStrategy = field(default=EvictionStrategy.RANDOM_EVICTION, init=False)\n",
|
||
"\n",
|
||
"@dataclass\n",
|
||
"class RefreshSimulation(TTLSimulation):\n",
|
||
" \n",
|
||
" def generate_objects(self, fixed_ttl, max_refresh_rate):\n",
|
||
" if isinstance(self.db_objects, int):\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=np.random.zipf(ZIPF_CONSTANT), mu_value=np.random.uniform(1, max_refresh_rate), ttl=fixed_ttl) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]\n",
|
||
" \n",
|
||
" def from_file(self, path: str, lambda_column_name: str, ttl_column_name: str, mu_column_name: str):\n",
|
||
" df = pd.read_csv(path)\n",
|
||
" lambdas = df[lambda_column_name]\n",
|
||
" ttls = df[ttl_column_name]\n",
|
||
" mus = df[mu_column_name]\n",
|
||
"\n",
|
||
" self.db_objects = [\n",
|
||
" DatabaseObject(id=i, data=f\"Generated Object {i}\", lambda_value=lambdas[i], mu_value=mus[i], ttl=ttls[i]) \n",
|
||
" for i in range(self.db_objects)\n",
|
||
" ]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "5cea042f-e9fc-4a1e-9750-de212ca70601",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"class Database:\n",
|
||
" data: Dict[int, DatabaseObject]\n",
|
||
" \n",
|
||
" def __init__(self, data: List[DatabaseObject]):\n",
|
||
" self.data = {i: data[i] for i in range(len(data))}\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": 7,
|
||
"id": "499bf543-b2c6-4e4d-afcc-0a6665ce3ae1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"class Cache:\n",
|
||
" capacity: int\n",
|
||
" eviction_strategy: EvictionStrategy\n",
|
||
" cache_size_over_time: List[int] # To record cache state at each interval\n",
|
||
" storage: Dict[int, CacheObject]\n",
|
||
" hits: Dict[int, int] # hit counter for each object\n",
|
||
" misses: Dict[int, int] # miss counter for each object\n",
|
||
" access_count: Dict[int, int] # access counter for each object (should be hit+miss)\n",
|
||
" next_request: Dict[int, float] # scheduled time for each object to be requested\n",
|
||
" cumulative_age: Dict[int, List[float]] # list of ages of each object at the time it was requested (current time - age_timer)\n",
|
||
" cumulative_cache_time: Dict[int, List[float]] # list of total time of each object spent in cache when it was evicted (current time - initial fetch time)\n",
|
||
" request_log: Dict[int, List[float]] # list of timestamps when each object was requested\n",
|
||
" \n",
|
||
" def __init__(self, env, db, simulation_config):\n",
|
||
" self.env = env\n",
|
||
" self.db = db\n",
|
||
" self.capacity = simulation_config.cache_size\n",
|
||
" self.eviction_strategy = simulation_config.eviction_strategy\n",
|
||
" self.cache_size_over_time = []\n",
|
||
" self.storage = {}\n",
|
||
"\n",
|
||
" db_object_count = len(self.db.data)\n",
|
||
" \n",
|
||
" self.hits = {i: 0 for i in range(db_object_count)}\n",
|
||
" self.misses = {i: 0 for i in range(db_object_count)}\n",
|
||
" self.access_count = {i: 0 for i in range(db_object_count)}\n",
|
||
" self.next_request = {i: np.random.exponential(1/self.db.data[i].lambda_value) for i in range(len(self.db.data))}\n",
|
||
" self.cumulative_age = {i: [] for i in range(db_object_count)}\n",
|
||
" self.cumulative_cache_time = {i: [] for i in range(db_object_count)}\n",
|
||
" self.request_log = {i: [] for i in range(db_object_count)}\n",
|
||
"\n",
|
||
" \n",
|
||
" def get(self, obj_id):\n",
|
||
" assert len(self.storage) <= self.capacity, f\"Too many objects in cache ({len(self.storage)}). \"\n",
|
||
"\n",
|
||
" # Schedule next request\n",
|
||
" next_request = self.env.now + np.random.exponential(1/self.db.data[obj_id].lambda_value)\n",
|
||
" self.request_log[obj_id].append(next_request)\n",
|
||
" self.next_request[obj_id] = next_request\n",
|
||
" # print(f\"[{self.env.now:.2f}] Client: Schedule next request for {obj_id}@{next_request:.2f}\")\n",
|
||
" \n",
|
||
" if obj_id in self.storage:\n",
|
||
" # Cache hit: Refresh TTL if TTL-Cache\n",
|
||
" if self.storage[obj_id].next_expiry:\n",
|
||
" assert self.env.now <= self.storage[obj_id].next_expiry, f\"[{self.env.now:.2f}] Cache should never hit on an expired cache entry.\"\n",
|
||
" self.storage[obj_id].next_expiry = self.env.now + self.db.data[obj_id].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",
|
||
" age = self.env.now - self.storage[obj_id].age_timer\n",
|
||
" self.cumulative_age[obj_id].append(age)\n",
|
||
"\n",
|
||
" assert len(self.cumulative_age[obj_id]) == self.access_count[obj_id], f\"[{self.env.now:.2f}] 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",
|
||
" else:\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 len(self.storage) == self.capacity:\n",
|
||
" if self.eviction_strategy == EvictionStrategy.LRU:\n",
|
||
" self.evict_oldest()\n",
|
||
" elif self.eviction_strategy == EvictionStrategy.RANDOM_EVICTION:\n",
|
||
" self.evict_random()\n",
|
||
" elif self.eviction_strategy == EvictionStrategy.TTL:\n",
|
||
" # print(f\"[{self.env.now:.2f}] Cache: Capacity reached. Not accepting new request.\")\n",
|
||
" return\n",
|
||
" \n",
|
||
" # Cache miss: increment miss count\n",
|
||
" self.misses[obj_id] += 1\n",
|
||
" self.access_count[obj_id] += 1\n",
|
||
" self.cumulative_age[obj_id].append(0)\n",
|
||
"\n",
|
||
" # Cache miss: Construct CacheObject from Database Object\n",
|
||
" db_object = self.db.get_object(obj_id)\n",
|
||
" initial_fetch_timer=self.env.now\n",
|
||
" age_timer=self.env.now\n",
|
||
" next_refresh = (self.env.now + np.random.exponential(1/db_object.mu_value)) if db_object.mu_value is not None else None\n",
|
||
" next_expiry = (self.env.now + db_object.ttl) if db_object.ttl is not None else None\n",
|
||
" cache_object = CacheObject(id=obj_id, data=db_object, \n",
|
||
" initial_fetch_timer=initial_fetch_timer, age_timer=age_timer, \n",
|
||
" next_refresh=next_refresh, next_expiry=next_expiry\n",
|
||
" )\n",
|
||
" self.storage[obj_id] = cache_object\n",
|
||
" \n",
|
||
" assert len(self.cumulative_age[obj_id]) == self.access_count[obj_id], f\"[{self.env.now:.2f}] 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",
|
||
" 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",
|
||
" assert obj_id in self.storage, f\"[{self.env.now:.2f}] Refreshed object has to be in cache\"\n",
|
||
" db_object = self.db.get_object(obj_id)\n",
|
||
" age_timer = self.env.now\n",
|
||
" next_refresh = self.env.now + np.random.exponential(1/db_object.mu_value)\n",
|
||
" # next_expiry = self.env.now + db_object.ttl if db_object.ttl is not None else None\n",
|
||
"\n",
|
||
" self.storage[obj_id].data = db_object\n",
|
||
" self.storage[obj_id].age_timer = age_timer\n",
|
||
" self.storage[obj_id].next_refresh = next_refresh\n",
|
||
"\n",
|
||
" # print(f\"[{self.env.now:.2f}] Cache: Refreshed object {obj_id}\")\n",
|
||
" \n",
|
||
" def evict_oldest(self):\n",
|
||
" \"\"\"Remove the oldest item from the cache to make space.\"\"\"\n",
|
||
" assert self.capacity == len(self.storage), f\"[{self.env.now:.2f}] Expecting cache to be at capacity\"\n",
|
||
" oldest_id = min(self.storage.items(), key=lambda item: item[1].initial_fetch_timer)[0]\n",
|
||
" \n",
|
||
" # print(f\"[{self.env.now:.2f}] Cache: Evicting oldest object {oldest_id}.\")\n",
|
||
" self.cumulative_cache_time[oldest_id].append(self.env.now - self.storage[oldest_id].initial_fetch_timer)\n",
|
||
" del self.storage[oldest_id]\n",
|
||
" \n",
|
||
" def evict_random(self):\n",
|
||
" \"\"\"Remove a random item from the cache to make space.\"\"\"\n",
|
||
" assert self.capacity == len(self.storage), f\"[{self.env.now:.2f}] Expecting cache to be at capacity\"\n",
|
||
" random_id = np.random.choice(list(self.storage.keys())) # Select a random key from the cache\n",
|
||
" \n",
|
||
" # print(f\"[{self.env.now:.2f}] Cache: Evicting random object {random_id}.\")\n",
|
||
" self.cumulative_cache_time[random_id].append(self.env.now - self.storage[random_id].initial_fetch_timer)\n",
|
||
" del self.storage[random_id]\n",
|
||
" \n",
|
||
" def check_expired(self, obj_id):\n",
|
||
" \"\"\"Remove object if its TTL expired.\"\"\"\n",
|
||
" assert self.storage, f\"[{self.env.now:.2f}] Expecting cache to be not empty\"\n",
|
||
" assert self.env.now >= self.storage[obj_id].next_expiry\n",
|
||
" \n",
|
||
" # print(f\"[{self.env.now:.2f}] Cache: Object {obj_id} expired\")\n",
|
||
" self.cumulative_cache_time[obj_id].append(self.env.now - self.storage[obj_id].initial_fetch_timer)\n",
|
||
" del self.storage[obj_id]\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((self.env.now, len(self.storage)))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"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",
|
||
" request_id, next_request = min(cache.next_request.items(), key=lambda x: x[1])\n",
|
||
" expiry_id = -1\n",
|
||
" next_expiry = float('inf')\n",
|
||
" refresh_id = -1\n",
|
||
" next_refresh = float('inf')\n",
|
||
"\n",
|
||
" if cache.storage:\n",
|
||
" expiry_id, next_expiry = min(cache.storage.items(), key=lambda x: x[1].next_expiry if x[1].next_expiry is not None else float('inf'))\n",
|
||
" next_expiry = cache.storage[expiry_id].next_expiry\n",
|
||
" refresh_id, next_refresh = min(cache.storage.items(), key=lambda x: x[1].next_refresh if x[1].next_refresh is not None else float('inf'))\n",
|
||
" next_refresh = cache.storage[refresh_id].next_refresh\n",
|
||
"\n",
|
||
" events = [\n",
|
||
" (request_id, next_request),\n",
|
||
" (expiry_id, next_expiry),\n",
|
||
" (refresh_id, next_refresh)\n",
|
||
" ]\n",
|
||
"\n",
|
||
" event_id, event_timestamp = min(events, key=lambda x: x[1] if x[1] is not None else float('inf'))\n",
|
||
" \n",
|
||
" # if event_id == request_id and event_timestamp == next_request:\n",
|
||
" # print(f\"[{env.now:.2f}] Waiting for request...\")\n",
|
||
" # elif event_id == expiry_id and event_timestamp == next_expiry:\n",
|
||
" # print(f\"[{env.now:.2f}] Waiting for expiry until...\")\n",
|
||
" # elif event_id == refresh_id and event_timestamp == next_refresh:\n",
|
||
" # print(f\"[{env.now:.2f}] Waiting for refresh...\")\n",
|
||
" \n",
|
||
" yield(env.timeout(event_timestamp - env.now))\n",
|
||
"\n",
|
||
" if event_id == request_id and event_timestamp == next_request:\n",
|
||
" assert env.now >= next_request, f\"[{env.now}] Time for request should've been reached for Object {request_id}\"\n",
|
||
" cache.get(request_id)\n",
|
||
" elif event_id == expiry_id and event_timestamp == next_expiry:\n",
|
||
" assert env.now >= next_expiry, f\"[{env.now}] Time for expiry should've been reached for Object {expiry_id}\"\n",
|
||
" cache.check_expired(expiry_id)\n",
|
||
" elif event_id == refresh_id and event_timestamp == next_refresh:\n",
|
||
" assert env.now >= next_refresh, f\"[{env.now}] Time for refresh should've been reached for Object {refresh_id}\"\n",
|
||
" cache.refresh_object(refresh_id)\n",
|
||
" else:\n",
|
||
" assert False, \"Unreachable\"\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",
|
||
" # 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].append(env.now - cache.storage[obj_id].initial_fetch_timer)\n",
|
||
" event.succeed()\n",
|
||
" \n",
|
||
" cache.record_cache_state()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "c8516830-9880-4d9e-a91b-000338baf9d6",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"class Simulation:\n",
|
||
" def __init__(self, simulation_config: Union[TTLSimulation, LRUSimulation, RandomEvictionSimulation, RefreshSimulation]):\n",
|
||
" # Initialize simulation environment\n",
|
||
" self.env = simpy.Environment()\n",
|
||
" \n",
|
||
" # Instantiate components\n",
|
||
" self.db = Database(simulation_config.db_objects)\n",
|
||
" self.cache = Cache(self.env, self.db, simulation_config)\n",
|
||
"\n",
|
||
" def run_simulation(self):\n",
|
||
" # Start processes\n",
|
||
" # env.process(age_cache_process(env, cache))\n",
|
||
" stop_event = self.env.event()\n",
|
||
" self.env.process(client_request_process(self.env, self.cache, stop_event))\n",
|
||
" \n",
|
||
" # Run the simulation\n",
|
||
" self.env.run(until=stop_event)\n",
|
||
" self.end_time = self.env.now"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"id": "e269b607-16b9-46d0-8a97-7324f2002c72",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Simulate with a Cache that does random evictions, We'll have 100 Database Objects and a Cache Size of 10\n",
|
||
"# We'll generate lambdas from a zipf distribution\n",
|
||
"# config = RandomEvictionSimulation(100, 10)\n",
|
||
"# config.generate_objects()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"id": "33fdc5fd-1f39-4b51-b2c7-6ea6acf2b753",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Simulate with a Cache that does lru, We'll have 100 Database Objects and a Cache Size of 10\n",
|
||
"# We'll generate lambdas from a zipf distribution\n",
|
||
"config = LRUSimulation(100, 10)\n",
|
||
"config.from_file('../test.csv', 'Lambda')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"id": "6c391bfd-b294-4ff7-8b22-51777368a6b9",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Simulate with a Cache that does Refreshes with TTL based eviction, We'll have 100 Database Objects and a Cache Size of 10\n",
|
||
"# We'll generate lambdas from a zipf distribution. Each object will have a fixed ttl of 1 when its pulled into the cache. Mu for the refresh rate is 10\n",
|
||
"# config = RefreshSimulation(100, 10)\n",
|
||
"# config.from_file('../test.csv', 'Lambda', 'h_opt_2', 'u_opt_2')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"id": "0a444c9d-53dd-4cab-b8f1-100ad3ab213a",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Simulate with a Cache that does TTL based eviction, We'll have 100 Database Objects and a Cache Size of 10\n",
|
||
"# We'll take lambdas from the \"lambda\" column of the file \"../calculated.csv\" and the TTLs for each object from the \"optimal_TTL\" column of the same file.\n",
|
||
"# config = TTLSimulation(100, 10)\n",
|
||
"# config.from_file(\"../calculated.csv\", \"lambda\", \"optimal_TTL\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"id": "66f65699-a3c9-48c4-8f1f-b9d7834c026a",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"IOPub message rate exceeded.██████████████████████████████████████▏ | 318/1000 [00:08<00:18, 36.80it/s]\n",
|
||
"The Jupyter server will temporarily stop sending output\n",
|
||
"to the client in order to avoid crashing it.\n",
|
||
"To change this limit, set the config variable\n",
|
||
"`--ServerApp.iopub_msg_rate_limit`.\n",
|
||
"\n",
|
||
"Current values:\n",
|
||
"ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
|
||
"ServerApp.rate_limit_window=3.0 (secs)\n",
|
||
"\n",
|
||
"IOPub message rate exceeded.████████████████████████████████████████████████████████████████████▊ | 508/1000 [00:11<00:11, 42.68it/s]\n",
|
||
"The Jupyter server will temporarily stop sending output\n",
|
||
"to the client in order to avoid crashing it.\n",
|
||
"To change this limit, set the config variable\n",
|
||
"`--ServerApp.iopub_msg_rate_limit`.\n",
|
||
"\n",
|
||
"Current values:\n",
|
||
"ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
|
||
"ServerApp.rate_limit_window=3.0 (secs)\n",
|
||
"\n",
|
||
"IOPub message rate exceeded.█████████████████████████████████████████████████████████████████████████████████████████████████████▋ | 712/1000 [00:15<00:06, 45.55it/s]\n",
|
||
"The Jupyter server will temporarily stop sending output\n",
|
||
"to the client in order to avoid crashing it.\n",
|
||
"To change this limit, set the config variable\n",
|
||
"`--ServerApp.iopub_msg_rate_limit`.\n",
|
||
"\n",
|
||
"Current values:\n",
|
||
"ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
|
||
"ServerApp.rate_limit_window=3.0 (secs)\n",
|
||
"\n",
|
||
"IOPub message rate exceeded.██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▎ | 890/1000 [00:18<00:02, 47.26it/s]\n",
|
||
"The Jupyter server will temporarily stop sending output\n",
|
||
"to the client in order to avoid crashing it.\n",
|
||
"To change this limit, set the config variable\n",
|
||
"`--ServerApp.iopub_msg_rate_limit`.\n",
|
||
"\n",
|
||
"Current values:\n",
|
||
"ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
|
||
"ServerApp.rate_limit_window=3.0 (secs)\n",
|
||
"\n",
|
||
"Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▊| 999/1000 [00:20<00:00, 48.26it/s]"
|
||
]
|
||
},
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Simulation ended after 19747.84052390687 seconds.\n",
|
||
"CPU times: user 19.6 s, sys: 3.65 s, total: 23.2 s\n",
|
||
"Wall time: 20.7 s\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"simulation = Simulation(config)\n",
|
||
"simulation.run_simulation()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"id": "6f900c68-1f34-48d1-b346-ef6ea6911fa5",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"cache = simulation.cache\n",
|
||
"db = simulation.db\n",
|
||
"simulation_end_time = simulation.end_time\n",
|
||
"database_object_count = len(db.data)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"id": "3b6f7c1f-ea54-4496-bb9a-370cee2d2751",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Object 0: Hit Rate = 0.05, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 1.02\n",
|
||
"Object 1: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.80\n",
|
||
"Object 2: Hit Rate = 0.03, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.01, Expected Age = 0.64\n",
|
||
"Object 3: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.83\n",
|
||
"Object 4: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.01, Expected Age = 0.68\n",
|
||
"Object 5: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.80\n",
|
||
"Object 6: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.76\n",
|
||
"Object 7: Hit Rate = 0.03, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.01, Expected Age = 0.56\n",
|
||
"Object 8: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.73\n",
|
||
"Object 9: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.80\n",
|
||
"Object 10: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.76\n",
|
||
"Object 11: Hit Rate = 0.05, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.88\n",
|
||
"Object 12: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.73\n",
|
||
"Object 13: Hit Rate = 0.04, Expected Hit Rate = 0.05, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.77\n",
|
||
"Object 14: Hit Rate = 0.03, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.01, Expected Age = 0.60\n",
|
||
"Object 15: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.81\n",
|
||
"Object 16: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.84\n",
|
||
"Object 17: Hit Rate = 0.04, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.73\n",
|
||
"Object 18: Hit Rate = 0.03, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.55\n",
|
||
"Object 19: Hit Rate = 0.04, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.01, Expected Age = 0.63\n",
|
||
"Object 20: Hit Rate = 0.04, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.73\n",
|
||
"Object 21: Hit Rate = 0.06, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.03, Expected Age = 0.91\n",
|
||
"Object 22: Hit Rate = 0.06, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.03, Expected Age = 0.90\n",
|
||
"Object 23: Hit Rate = 0.04, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.69\n",
|
||
"Object 24: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.04, Average Age = 0.02, Expected Age = 0.76\n",
|
||
"Object 25: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.75\n",
|
||
"Object 26: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.72\n",
|
||
"Object 27: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.70\n",
|
||
"Object 28: Hit Rate = 0.06, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.86\n",
|
||
"Object 29: Hit Rate = 0.04, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.01, Expected Age = 0.57\n",
|
||
"Object 30: Hit Rate = 0.05, Expected Hit Rate = 0.06, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.72\n",
|
||
"Object 31: Hit Rate = 0.05, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.78\n",
|
||
"Object 32: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.03, Expected Age = 0.83\n",
|
||
"Object 33: Hit Rate = 0.05, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.03, Expected Age = 0.78\n",
|
||
"Object 34: Hit Rate = 0.05, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.73\n",
|
||
"Object 35: Hit Rate = 0.05, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.74\n",
|
||
"Object 36: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.84\n",
|
||
"Object 37: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.78\n",
|
||
"Object 38: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.02, Expected Age = 0.75\n",
|
||
"Object 39: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.06, Average Age = 0.02, Expected Age = 0.80\n",
|
||
"Object 40: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.05, Average Age = 0.03, Expected Age = 0.83\n",
|
||
"Object 41: Hit Rate = 0.07, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.88\n",
|
||
"Object 42: Hit Rate = 0.06, Expected Hit Rate = 0.07, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.77\n",
|
||
"Object 43: Hit Rate = 0.06, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.81\n",
|
||
"Object 44: Hit Rate = 0.07, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.87\n",
|
||
"Object 45: Hit Rate = 0.06, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.72\n",
|
||
"Object 46: Hit Rate = 0.07, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.81\n",
|
||
"Object 47: Hit Rate = 0.07, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.02, Expected Age = 0.79\n",
|
||
"Object 48: Hit Rate = 0.07, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.06, Average Age = 0.03, Expected Age = 0.79\n",
|
||
"Object 49: Hit Rate = 0.06, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.76\n",
|
||
"Object 50: Hit Rate = 0.06, Expected Hit Rate = 0.08, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.72\n",
|
||
"Object 51: Hit Rate = 0.06, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.72\n",
|
||
"Object 52: Hit Rate = 0.07, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.75\n",
|
||
"Object 53: Hit Rate = 0.06, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.69\n",
|
||
"Object 54: Hit Rate = 0.07, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.78\n",
|
||
"Object 55: Hit Rate = 0.08, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.04, Expected Age = 0.82\n",
|
||
"Object 56: Hit Rate = 0.08, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.80\n",
|
||
"Object 57: Hit Rate = 0.06, Expected Hit Rate = 0.09, Average Time spend in Cache: 0.07, Average Age = 0.03, Expected Age = 0.62\n",
|
||
"Object 58: Hit Rate = 0.08, Expected Hit Rate = 0.10, Average Time spend in Cache: 0.07, Average Age = 0.04, Expected Age = 0.83\n",
|
||
"Object 59: Hit Rate = 0.07, Expected Hit Rate = 0.10, Average Time spend in Cache: 0.08, Average Age = 0.03, Expected Age = 0.68\n",
|
||
"Object 60: Hit Rate = 0.08, Expected Hit Rate = 0.10, Average Time spend in Cache: 0.08, Average Age = 0.04, Expected Age = 0.74\n",
|
||
"Object 61: Hit Rate = 0.07, Expected Hit Rate = 0.10, Average Time spend in Cache: 0.08, Average Age = 0.03, Expected Age = 0.66\n",
|
||
"Object 62: Hit Rate = 0.09, Expected Hit Rate = 0.10, Average Time spend in Cache: 0.08, Average Age = 0.04, Expected Age = 0.87\n",
|
||
"Object 63: Hit Rate = 0.08, Expected Hit Rate = 0.11, Average Time spend in Cache: 0.08, Average Age = 0.04, Expected Age = 0.74\n",
|
||
"Object 64: Hit Rate = 0.08, Expected Hit Rate = 0.11, Average Time spend in Cache: 0.09, Average Age = 0.04, Expected Age = 0.74\n",
|
||
"Object 65: Hit Rate = 0.08, Expected Hit Rate = 0.11, Average Time spend in Cache: 0.09, Average Age = 0.04, Expected Age = 0.74\n",
|
||
"Object 66: Hit Rate = 0.08, Expected Hit Rate = 0.11, Average Time spend in Cache: 0.09, Average Age = 0.03, Expected Age = 0.68\n",
|
||
"Object 67: Hit Rate = 0.09, Expected Hit Rate = 0.11, Average Time spend in Cache: 0.09, Average Age = 0.04, Expected Age = 0.73\n",
|
||
"Object 68: Hit Rate = 0.09, Expected Hit Rate = 0.12, Average Time spend in Cache: 0.10, Average Age = 0.04, Expected Age = 0.69\n",
|
||
"Object 69: Hit Rate = 0.09, Expected Hit Rate = 0.12, Average Time spend in Cache: 0.09, Average Age = 0.04, Expected Age = 0.67\n",
|
||
"Object 70: Hit Rate = 0.10, Expected Hit Rate = 0.12, Average Time spend in Cache: 0.09, Average Age = 0.04, Expected Age = 0.73\n",
|
||
"Object 71: Hit Rate = 0.09, Expected Hit Rate = 0.13, Average Time spend in Cache: 0.10, Average Age = 0.04, Expected Age = 0.69\n",
|
||
"Object 72: Hit Rate = 0.10, Expected Hit Rate = 0.13, Average Time spend in Cache: 0.10, Average Age = 0.04, Expected Age = 0.73\n",
|
||
"Object 73: Hit Rate = 0.09, Expected Hit Rate = 0.13, Average Time spend in Cache: 0.10, Average Age = 0.04, Expected Age = 0.64\n",
|
||
"Object 74: Hit Rate = 0.11, Expected Hit Rate = 0.14, Average Time spend in Cache: 0.10, Average Age = 0.05, Expected Age = 0.72\n",
|
||
"Object 75: Hit Rate = 0.11, Expected Hit Rate = 0.14, Average Time spend in Cache: 0.11, Average Age = 0.05, Expected Age = 0.74\n",
|
||
"Object 76: Hit Rate = 0.11, Expected Hit Rate = 0.15, Average Time spend in Cache: 0.12, Average Age = 0.05, Expected Age = 0.72\n",
|
||
"Object 77: Hit Rate = 0.13, Expected Hit Rate = 0.15, Average Time spend in Cache: 0.12, Average Age = 0.06, Expected Age = 0.80\n",
|
||
"Object 78: Hit Rate = 0.12, Expected Hit Rate = 0.16, Average Time spend in Cache: 0.12, Average Age = 0.05, Expected Age = 0.73\n",
|
||
"Object 79: Hit Rate = 0.12, Expected Hit Rate = 0.16, Average Time spend in Cache: 0.12, Average Age = 0.05, Expected Age = 0.68\n",
|
||
"Object 80: Hit Rate = 0.13, Expected Hit Rate = 0.17, Average Time spend in Cache: 0.13, Average Age = 0.06, Expected Age = 0.73\n",
|
||
"Object 81: Hit Rate = 0.12, Expected Hit Rate = 0.17, Average Time spend in Cache: 0.13, Average Age = 0.05, Expected Age = 0.67\n",
|
||
"Object 82: Hit Rate = 0.14, Expected Hit Rate = 0.18, Average Time spend in Cache: 0.14, Average Age = 0.06, Expected Age = 0.72\n",
|
||
"Object 83: Hit Rate = 0.15, Expected Hit Rate = 0.19, Average Time spend in Cache: 0.14, Average Age = 0.07, Expected Age = 0.72\n",
|
||
"Object 84: Hit Rate = 0.15, Expected Hit Rate = 0.20, Average Time spend in Cache: 0.15, Average Age = 0.07, Expected Age = 0.69\n",
|
||
"Object 85: Hit Rate = 0.15, Expected Hit Rate = 0.20, Average Time spend in Cache: 0.15, Average Age = 0.06, Expected Age = 0.65\n",
|
||
"Object 86: Hit Rate = 0.16, Expected Hit Rate = 0.22, Average Time spend in Cache: 0.16, Average Age = 0.07, Expected Age = 0.68\n",
|
||
"Object 87: Hit Rate = 0.17, Expected Hit Rate = 0.23, Average Time spend in Cache: 0.17, Average Age = 0.07, Expected Age = 0.67\n",
|
||
"Object 88: Hit Rate = 0.18, Expected Hit Rate = 0.24, Average Time spend in Cache: 0.18, Average Age = 0.08, Expected Age = 0.70\n",
|
||
"Object 89: Hit Rate = 0.20, Expected Hit Rate = 0.25, Average Time spend in Cache: 0.20, Average Age = 0.09, Expected Age = 0.69\n",
|
||
"Object 90: Hit Rate = 0.20, Expected Hit Rate = 0.27, Average Time spend in Cache: 0.20, Average Age = 0.09, Expected Age = 0.65\n",
|
||
"Object 91: Hit Rate = 0.22, Expected Hit Rate = 0.29, Average Time spend in Cache: 0.22, Average Age = 0.09, Expected Age = 0.67\n",
|
||
"Object 92: Hit Rate = 0.24, Expected Hit Rate = 0.32, Average Time spend in Cache: 0.23, Average Age = 0.10, Expected Age = 0.66\n",
|
||
"Object 93: Hit Rate = 0.26, Expected Hit Rate = 0.34, Average Time spend in Cache: 0.26, Average Age = 0.12, Expected Age = 0.66\n",
|
||
"Object 94: Hit Rate = 0.28, Expected Hit Rate = 0.38, Average Time spend in Cache: 0.28, Average Age = 0.13, Expected Age = 0.64\n",
|
||
"Object 95: Hit Rate = 0.31, Expected Hit Rate = 0.42, Average Time spend in Cache: 0.31, Average Age = 0.14, Expected Age = 0.62\n",
|
||
"Object 96: Hit Rate = 0.36, Expected Hit Rate = 0.48, Average Time spend in Cache: 0.35, Average Age = 0.16, Expected Age = 0.62\n",
|
||
"Object 97: Hit Rate = 0.40, Expected Hit Rate = 0.56, Average Time spend in Cache: 0.41, Average Age = 0.19, Expected Age = 0.58\n",
|
||
"Object 98: Hit Rate = 0.49, Expected Hit Rate = 0.68, Average Time spend in Cache: 0.49, Average Age = 0.22, Expected Age = 0.57\n",
|
||
"Object 99: Hit Rate = 0.63, Expected Hit Rate = 0.86, Average Time spend in Cache: 0.63, Average Age = 0.29, Expected Age = 0.52\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"statistics = []\n",
|
||
"# Calculate and print hit rate and average age for each object\n",
|
||
"for obj_id in range(database_object_count):\n",
|
||
" if cache.access_count[obj_id] != 0:\n",
|
||
" hit_rate = cache.hits[obj_id] / max(1, cache.access_count[obj_id])\n",
|
||
" expected_hit_rate = 1-math.exp(-db.data[obj_id].lambda_value*(db.data[obj_id].ttl if db.data[obj_id].ttl is not None else 1))\n",
|
||
" avg_cache_time = sum(cache.cumulative_cache_time[obj_id]) / max(1, simulation_end_time) \n",
|
||
" avg_age = sum(cache.cumulative_age[obj_id]) / max(len(cache.cumulative_age[obj_id]), 1)\n",
|
||
" expected_age = hit_rate / (db.data[obj_id].lambda_value * (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": 17,
|
||
"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": 18,
|
||
"id": "80971714-44f1-47db-9e89-85be7c885bde",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<div>\n",
|
||
"<style scoped>\n",
|
||
" .dataframe tbody tr th:only-of-type {\n",
|
||
" vertical-align: middle;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe tbody tr th {\n",
|
||
" vertical-align: top;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe thead th {\n",
|
||
" text-align: right;\n",
|
||
" }\n",
|
||
"</style>\n",
|
||
"<table border=\"1\" class=\"dataframe\">\n",
|
||
" <thead>\n",
|
||
" <tr style=\"text-align: right;\">\n",
|
||
" <th></th>\n",
|
||
" <th>access_count</th>\n",
|
||
" <th>hits</th>\n",
|
||
" <th>misses</th>\n",
|
||
" <th>mu</th>\n",
|
||
" <th>lambda</th>\n",
|
||
" <th>hit_rate</th>\n",
|
||
" <th>optimal_hitrates</th>\n",
|
||
" <th>expected_hit_rate</th>\n",
|
||
" <th>expected_hit_rate_delta</th>\n",
|
||
" <th>avg_cache_time</th>\n",
|
||
" <th>cache_time_delta</th>\n",
|
||
" <th>avg_age</th>\n",
|
||
" <th>expected_age</th>\n",
|
||
" <th>age_delta</th>\n",
|
||
" <th>age_delta in %</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>1022</td>\n",
|
||
" <td>52</td>\n",
|
||
" <td>970</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.0502</td>\n",
|
||
" <td>0.050881</td>\n",
|
||
" <td>0.0513</td>\n",
|
||
" <td>0.048961</td>\n",
|
||
" <td>0.001920</td>\n",
|
||
" <td>0.038411</td>\n",
|
||
" <td>0.012470</td>\n",
|
||
" <td>0.023130</td>\n",
|
||
" <td>1.016189</td>\n",
|
||
" <td>-0.993059</td>\n",
|
||
" <td>-0.977238</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>1045</td>\n",
|
||
" <td>42</td>\n",
|
||
" <td>1003</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.0506</td>\n",
|
||
" <td>0.040191</td>\n",
|
||
" <td>0.0513</td>\n",
|
||
" <td>0.049341</td>\n",
|
||
" <td>-0.009150</td>\n",
|
||
" <td>0.040332</td>\n",
|
||
" <td>-0.000141</td>\n",
|
||
" <td>0.016009</td>\n",
|
||
" <td>0.795581</td>\n",
|
||
" <td>-0.779572</td>\n",
|
||
" <td>-0.979877</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>1009</td>\n",
|
||
" <td>33</td>\n",
|
||
" <td>976</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.0511</td>\n",
|
||
" <td>0.032706</td>\n",
|
||
" <td>0.4000</td>\n",
|
||
" <td>0.049816</td>\n",
|
||
" <td>-0.017111</td>\n",
|
||
" <td>0.039100</td>\n",
|
||
" <td>-0.006394</td>\n",
|
||
" <td>0.013227</td>\n",
|
||
" <td>0.640718</td>\n",
|
||
" <td>-0.627490</td>\n",
|
||
" <td>-0.979355</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>1059</td>\n",
|
||
" <td>45</td>\n",
|
||
" <td>1014</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.0515</td>\n",
|
||
" <td>0.042493</td>\n",
|
||
" <td>0.2254</td>\n",
|
||
" <td>0.050196</td>\n",
|
||
" <td>-0.007703</td>\n",
|
||
" <td>0.041095</td>\n",
|
||
" <td>0.001398</td>\n",
|
||
" <td>0.015914</td>\n",
|
||
" <td>0.826598</td>\n",
|
||
" <td>-0.810683</td>\n",
|
||
" <td>-0.980747</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>1045</td>\n",
|
||
" <td>37</td>\n",
|
||
" <td>1008</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.0519</td>\n",
|
||
" <td>0.035407</td>\n",
|
||
" <td>0.0000</td>\n",
|
||
" <td>0.050576</td>\n",
|
||
" <td>-0.015169</td>\n",
|
||
" <td>0.041100</td>\n",
|
||
" <td>-0.005693</td>\n",
|
||
" <td>0.011848</td>\n",
|
||
" <td>0.683066</td>\n",
|
||
" <td>-0.671218</td>\n",
|
||
" <td>-0.982655</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>95</th>\n",
|
||
" <td>10811</td>\n",
|
||
" <td>3365</td>\n",
|
||
" <td>7446</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.5519</td>\n",
|
||
" <td>0.311257</td>\n",
|
||
" <td>0.0000</td>\n",
|
||
" <td>0.424145</td>\n",
|
||
" <td>-0.112888</td>\n",
|
||
" <td>0.308356</td>\n",
|
||
" <td>0.002901</td>\n",
|
||
" <td>0.137645</td>\n",
|
||
" <td>0.624473</td>\n",
|
||
" <td>-0.486829</td>\n",
|
||
" <td>-0.779583</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>96</th>\n",
|
||
" <td>13157</td>\n",
|
||
" <td>4684</td>\n",
|
||
" <td>8473</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.6598</td>\n",
|
||
" <td>0.356008</td>\n",
|
||
" <td>0.0000</td>\n",
|
||
" <td>0.483045</td>\n",
|
||
" <td>-0.127037</td>\n",
|
||
" <td>0.353400</td>\n",
|
||
" <td>0.002608</td>\n",
|
||
" <td>0.160020</td>\n",
|
||
" <td>0.617881</td>\n",
|
||
" <td>-0.457862</td>\n",
|
||
" <td>-0.741019</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>97</th>\n",
|
||
" <td>16227</td>\n",
|
||
" <td>6542</td>\n",
|
||
" <td>9685</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>0.8305</td>\n",
|
||
" <td>0.403155</td>\n",
|
||
" <td>0.0000</td>\n",
|
||
" <td>0.564169</td>\n",
|
||
" <td>-0.161013</td>\n",
|
||
" <td>0.407435</td>\n",
|
||
" <td>-0.004280</td>\n",
|
||
" <td>0.185865</td>\n",
|
||
" <td>0.579650</td>\n",
|
||
" <td>-0.393785</td>\n",
|
||
" <td>-0.679350</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>98</th>\n",
|
||
" <td>22767</td>\n",
|
||
" <td>11201</td>\n",
|
||
" <td>11566</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>1.1487</td>\n",
|
||
" <td>0.491984</td>\n",
|
||
" <td>0.5528</td>\n",
|
||
" <td>0.682951</td>\n",
|
||
" <td>-0.190967</td>\n",
|
||
" <td>0.489995</td>\n",
|
||
" <td>0.001989</td>\n",
|
||
" <td>0.224034</td>\n",
|
||
" <td>0.565071</td>\n",
|
||
" <td>-0.341037</td>\n",
|
||
" <td>-0.603530</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>99</th>\n",
|
||
" <td>39079</td>\n",
|
||
" <td>24517</td>\n",
|
||
" <td>14562</td>\n",
|
||
" <td>None</td>\n",
|
||
" <td>2.0000</td>\n",
|
||
" <td>0.627370</td>\n",
|
||
" <td>0.0000</td>\n",
|
||
" <td>0.864665</td>\n",
|
||
" <td>-0.237295</td>\n",
|
||
" <td>0.627601</td>\n",
|
||
" <td>-0.000231</td>\n",
|
||
" <td>0.293713</td>\n",
|
||
" <td>0.517285</td>\n",
|
||
" <td>-0.223572</td>\n",
|
||
" <td>-0.432202</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>100 rows × 15 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" access_count hits misses mu lambda hit_rate optimal_hitrates \\\n",
|
||
"0 1022 52 970 None 0.0502 0.050881 0.0513 \n",
|
||
"1 1045 42 1003 None 0.0506 0.040191 0.0513 \n",
|
||
"2 1009 33 976 None 0.0511 0.032706 0.4000 \n",
|
||
"3 1059 45 1014 None 0.0515 0.042493 0.2254 \n",
|
||
"4 1045 37 1008 None 0.0519 0.035407 0.0000 \n",
|
||
".. ... ... ... ... ... ... ... \n",
|
||
"95 10811 3365 7446 None 0.5519 0.311257 0.0000 \n",
|
||
"96 13157 4684 8473 None 0.6598 0.356008 0.0000 \n",
|
||
"97 16227 6542 9685 None 0.8305 0.403155 0.0000 \n",
|
||
"98 22767 11201 11566 None 1.1487 0.491984 0.5528 \n",
|
||
"99 39079 24517 14562 None 2.0000 0.627370 0.0000 \n",
|
||
"\n",
|
||
" expected_hit_rate expected_hit_rate_delta avg_cache_time \\\n",
|
||
"0 0.048961 0.001920 0.038411 \n",
|
||
"1 0.049341 -0.009150 0.040332 \n",
|
||
"2 0.049816 -0.017111 0.039100 \n",
|
||
"3 0.050196 -0.007703 0.041095 \n",
|
||
"4 0.050576 -0.015169 0.041100 \n",
|
||
".. ... ... ... \n",
|
||
"95 0.424145 -0.112888 0.308356 \n",
|
||
"96 0.483045 -0.127037 0.353400 \n",
|
||
"97 0.564169 -0.161013 0.407435 \n",
|
||
"98 0.682951 -0.190967 0.489995 \n",
|
||
"99 0.864665 -0.237295 0.627601 \n",
|
||
"\n",
|
||
" cache_time_delta avg_age expected_age age_delta age_delta in % \n",
|
||
"0 0.012470 0.023130 1.016189 -0.993059 -0.977238 \n",
|
||
"1 -0.000141 0.016009 0.795581 -0.779572 -0.979877 \n",
|
||
"2 -0.006394 0.013227 0.640718 -0.627490 -0.979355 \n",
|
||
"3 0.001398 0.015914 0.826598 -0.810683 -0.980747 \n",
|
||
"4 -0.005693 0.011848 0.683066 -0.671218 -0.982655 \n",
|
||
".. ... ... ... ... ... \n",
|
||
"95 0.002901 0.137645 0.624473 -0.486829 -0.779583 \n",
|
||
"96 0.002608 0.160020 0.617881 -0.457862 -0.741019 \n",
|
||
"97 -0.004280 0.185865 0.579650 -0.393785 -0.679350 \n",
|
||
"98 0.001989 0.224034 0.565071 -0.341037 -0.603530 \n",
|
||
"99 -0.000231 0.293713 0.517285 -0.223572 -0.432202 \n",
|
||
"\n",
|
||
"[100 rows x 15 columns]"
|
||
]
|
||
},
|
||
"execution_count": 18,
|
||
"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({l: db.data[l].mu_value for l in range(database_object_count)}, orient='index', columns=['mu'])\n",
|
||
"lmbda = pd.DataFrame.from_dict({l: db.data[l].lambda_value for l in range(database_object_count)}, orient='index', columns=['lambda'])\n",
|
||
"\n",
|
||
"hit_rate = pd.DataFrame(stats['hit_rate'])\n",
|
||
"hit_rate.index = range(database_object_count)\n",
|
||
"optimal_hitrate = pd.DataFrame(BASE_FILE['optimal_hitrates'])\n",
|
||
"optimal_hitrate.index = range(database_object_count)\n",
|
||
"expected_hit_rate = pd.DataFrame(stats['expected_hit_rate'])\n",
|
||
"expected_hit_rate.index = range(database_object_count)\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(database_object_count)\n",
|
||
"avg_cache_time = pd.DataFrame(stats['avg_cache_time'])\n",
|
||
"avg_cache_time.index = range(database_object_count)\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(database_object_count)\n",
|
||
"\n",
|
||
"avg_age = pd.DataFrame(stats['avg_age'])\n",
|
||
"avg_age.index = range(database_object_count)\n",
|
||
"expected_age = pd.DataFrame(stats['expected_age'])\n",
|
||
"expected_age.index = range(database_object_count)\n",
|
||
"age_delta = pd.DataFrame((avg_age.to_numpy()-expected_age.to_numpy()), columns=['age_delta'])\n",
|
||
"age_delta.index = range(database_object_count)\n",
|
||
"age_delta_p = pd.DataFrame(np.where(expected_age.to_numpy().T[0] != 0, age_delta.to_numpy().T[0] / expected_age.to_numpy().T[0], 0), columns=['age_delta in %'])\n",
|
||
"age_delta_p.index = range(database_object_count)\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(optimal_hitrate, 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": 19,
|
||
"id": "01f8f9ee-c278-4a22-8562-ba02e77f5ddd",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAACVcAAAHWCAYAAAB5HisgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABpjUlEQVR4nOzdd5hV5dk+7GvTi1QVAUVEwIaiUaNRY0fRGHtij71EMYpGY0ksGI1dUV/rm9hiiwX1Z6IitmDvNUEFxRJrFBEVhYFZ3x/5mNdxNrAHBzaR8zwODmc/61lr3WvNnvvYMJfPKhVFUQQAAAAAAAAAAIB6mlW7AAAAAAAAAAAAgPmRcBUAAAAAAAAAAEAZwlUAAAAAAAAAAABlCFcBAAAAAAAAAACUIVwFAAAAAAAAAABQhnAVAAAAAAAAAABAGcJVAAAAAAAAAAAAZQhXAQAAAAAAAAAAlCFcBQAAAAAAAAAAUIZwFQAAAECSBx98MKVSKTfffHO1S6nIhx9+mJ/97GdZeOGFUyqVMnz48CY79ptvvplSqZSzzjprtnNPPPHElEqlJjv3vFAqlXLiiSdWu4wmUSqVcvDBB1e7jP9qSy21VPbcc89qlwEAAADMp4SrAAAAgHnmyiuvTKlUSps2bfLuu+822L7BBhtkxRVXrEJl/30OO+ywjBw5Msccc0z+/Oc/Z7PNNpvl/C+//DK///3vM3DgwLRr1y6dOnXKuuuum6uvvjpFUcyjqhvvzjvv/K8JQj344IPZbrvt0r1797Rq1SrdunXLlltumREjRlS7tCZRU1OT888/Pz/84Q/ToUOHLLTQQvnhD3+Y888/PzU1NdUur86MoGQlfwAAAABmp0W1CwAAAAAWPFOmTMlpp52WCy64oNql/Ne6//77s/XWW+eII46Y7dwPP/wwG2+8ccaMGZOddtopBx98cL7++uvccsst2WOPPXLnnXfm2muvTfPmzRtdx+9+97scffTRc3IJFbnzzjtz4YUXNmnA6quvvkqLFk37z2InnHBCTjrppPTv3z8HHHBAevfunU8++SR33nlntt9++1x77bXZZZddmvSc89KXX36ZLbbYIn//+9/z05/+NHvuuWeaNWuWu+++O4ceemhGjBiRv/3tb2nfvn21S83yyy+fP//5z/XGjjnmmCy00EL57W9/22D+q6++mmbN/D+oAAAAQHnCVQAAAMA8t8oqq+R///d/c8wxx6Rnz57VLmee+vLLL5skgPLRRx+lc+fOFc3dY489MmbMmNx6663Zaqut6sYPOeSQHHnkkTnrrLPygx/8IEcddVSj62jRokWTB5XmtjZt2jTp8W6++eacdNJJ+dnPfpbrrrsuLVu2rNt25JFHZuTIkfPVyk5z4vDDD8/f//73XHDBBfUeQ3jggQfmwgsvzMEHH5wjjjgiF1988TyrqSiKfP3112nbtm298cUWWyy77bZbvbHTTjstiyyySIPxJGnduvVcrRMAAAD47+Z/yQIAAADmuWOPPTbTp0/PaaedNst5b775ZkqlUq688soG20qlUr3VjE488cSUSqW89tpr2W233dKpU6csuuiiOe6441IURd55551svfXW6dixY7p3756zzz677DmnT5+eY489Nt27d0/79u2z1VZb5Z133mkw74knnshmm22WTp06pV27dll//fXzyCOP1Jszo6Z//vOf2WWXXdKlS5f8+Mc/nuU1v/HGG/n5z3+erl27pl27dvnRj36Uv/3tb3XbZzxasSiKXHjhhbN9vNnjjz+ekSNHZs8996wXrJrh1FNPTf/+/XP66afnq6++arD93HPPTe/evdO2bdusv/76efnll8te47ddc801WW211dK2bdt07do1O+2000zv409+8pN06dIl7du3z8CBA3PeeeclSfbcc89ceOGFSVL2UW433HBDVltttXTo0CEdO3bMSiutVLfvrMzsvTNu3Ljsueee6dy5czp16pS99torkydPnu3xjjvuuHTt2jWXX355vWDVDIMHD85Pf/rTJMnUqVNz/PHHZ7XVVkunTp3Svn37rLvuunnggQca7FdbW5vzzjsvK620Utq0aZNFF100m222WZ5++ukGc2+77basuOKKad26dQYMGJC77767wZx33303e++9dxZbbLG6eZdffvlsr+9f//pX/vSnP2WjjTaqF6yaYciQIdlwww3zxz/+Mf/617+SJCuuuGI23HDDste0+OKL52c/+1m9seHDh2fAgAFp06ZNFltssRxwwAH59NNP6+271FJL5ac//WlGjhyZ1VdfPW3bts2ll1462/pnZ6mllsqee+5Z93rGz9jDDz+cQw45JIsuumg6d+6cAw44IFOnTs3EiROz++67p0uXLunSpUt+85vfNHi0ZqXXBAAAAMz/hKsAAACAea5Pnz7Zfffd87//+7957733mvTYO+64Y2pra3PaaadlzTXXzMknn5zhw4dnk002yeKLL57TTz89/fr1yxFHHJHRo0c32P+UU07J3/72txx11FE55JBDMmrUqAwaNKhe8Oj+++/Peuutl0mTJuWEE07IH/7wh0ycODEbbbRRnnzyyQbH/PnPf57JkyfnD3/4Q/bbb7+Z1v7hhx9m7bXXzsiRI3PQQQfllFNOyddff52tttoqt956a5JkvfXWq3vk2SabbJI///nPDR6B9k133HFHkmT33Xcvu71FixbZZZdd8umnnzYIh1199dU5//zzM2TIkBxzzDF5+eWXs9FGG+XDDz+c6fmS/9zD3XffPf37988555yToUOH5r777st6662XiRMn1s0bNWpU1ltvvfzzn//MoYcemrPPPjsbbrhh/vrXvyZJDjjggGyyySZJUnedM6511KhR2XnnndOlS5ecfvrpOe2007LBBhs0uIbG2GGHHfL555/n1FNPzQ477JArr7wyw4YNm+U+Y8eOzSuvvJJtttkmHTp0mO05Jk2alD/+8Y/ZYIMNcvrpp+fEE0/Mv//97wwePDjPP/98vbn77LNPhg4dml69euX000/P0UcfnTZt2uTxxx+vN+/hhx/OQQcdlJ122ilnnHFGvv7662y//fb55JNP6uZ8+OGH+dGPfpR77703Bx98cM4777z069cv++yzT4YPHz7Lmu+6665Mnz59pu+h5D/vr2nTptWFunbccceMHj06H3zwQYNa33vvvey00051YwcccECOPPLIrLPOOjnvvPOy11575dprr83gwYMbrPj16quvZuedd84mm2yS8847L6usssosa/8ufvWrX2Xs2LEZNmxYttpqq1x22WU57rjjsuWWW2b69On5wx/+kB//+Mc588wzG/wMNuaaAAAAgPlcAQAAADCPXHHFFUWS4qmnnipef/31okWLFsUhhxxSt3399dcvBgwYUPd6/PjxRZLiiiuuaHCsJMUJJ5xQ9/qEE04okhT7779/3di0adOKJZZYoiiVSsVpp51WN/7pp58Wbdu2LfbYY4+6sQceeKBIUiy++OLFpEmT6sZvvPHGIklx3nnnFUVRFLW1tUX//v2LwYMHF7W1tXXzJk+eXPTp06fYZJNNGtS08847V3R/hg4dWiQpHnroobqxzz//vOjTp0+x1FJLFdOnT693/UOGDJntMbfZZpsiSfHpp5/OdM6IESOKJMX5559fFMX/3fe2bdsW//rXv+rmPfHEE0WS4rDDDmtwjTO8+eabRfPmzYtTTjml3jleeumlokWLFnXj06ZNK/r06VP07t27QW3fvK9Dhgwpyv0T1qGHHlp07NixmDZt2mzvwbfN7L2z995715u37bbbFgsvvPAsj3X77bcXSYpzzz23onNPmzatmDJlSr2xTz/9tFhsscXqnf/+++8vktT7+Zjhm/cnSdGqVati3LhxdWMvvPBCkaS44IIL6sb22WefokePHsXHH39c71g77bRT0alTp2Ly5MkzrXnG+/K5556b6Zxnn322SFIcfvjhRVEUxauvvtqghqIoioMOOqhYaKGF6s730EMPFUmKa6+9tt68u+++u8F47969iyTF3XffPdM6ZmbAgAHF+uuvX3Zb79696/WCGX3q2z/ja621VlEqlYpf/vKXdWMzesw3j92YawIAAADmf1auAgAAAKpi6aWXzi9+8Ytcdtllef/995vsuPvuu2/d182bN8/qq6+eoiiyzz771I137tw5yy67bN54440G++++++71ViD62c9+lh49euTOO+9Mkjz//PMZO3Zsdtlll3zyySf5+OOP8/HHH+fLL7/MxhtvnNGjR6e2trbeMX/5y19WVPudd96ZNdZYo96jAxdaaKHsv//+efPNN/PPf/6zspvwDZ9//nmSzHJVpRnbJk2aVG98m222yeKLL173eo011siaa65Zdy/KGTFiRGpra7PDDjvU3ZuPP/443bt3T//+/esef/fcc89l/PjxGTp0aDp37lzvGLN6zOEMnTt3zpdffplRo0bNdm6lvv19WnfddfPJJ580uC/fNGNbJatWJf95T7Zq1SrJfx4dN2HChEybNi2rr756nn322bp5t9xyS0qlUk444YQGx/j2/Rk0aFD69u1b93rgwIHp2LFj3fu7KIrccsst2XLLLVMURb3vy+DBg/PZZ5/VO/e3zcl7aJlllskqq6ySv/zlL3Vzpk+fnptvvjlbbrll2rZtmyS56aab0qlTp2yyySb16lpttdWy0EILNXhcYp8+fTJ48OCZ1tGU9tlnn3r3es0112zQS2b0mG/2ksZeEwAAADB/a1HtAgAAAIAF1+9+97v8+c9/zmmnnZbzzjuvSY655JJL1nvdqVOntGnTJossskiD8W8+Nm2G/v3713tdKpXSr1+/vPnmm0n+8xi4JNljjz1mWsNnn32WLl261L3u06dPRbW/9dZbWXPNNRuML7/88nXbV1xxxYqONcOM0Mvnn3/eIMQ0w8zCM9++F8l/QjM33njjTM83duzYFEVRdt8kadmyZZLk9ddfT5JGX88MBx10UG688cZsvvnmWXzxxbPppptmhx12yGabbTZHx0savndmfA8//fTTdOzYsew+M8Zn3MNKXHXVVTn77LPzyiuv1HtE3DffJ6+//np69uyZrl27NrruGbV/+umnSZJ///vfmThxYi677LJcdtllZY/x0UcfzfT433wPzUy599COO+6YY489Nu+++24WX3zxPPjgg/noo4+y44471s0ZO3ZsPvvss3Tr1q2iuir9WWoK5XpJkvTq1avB+Ix7nTT+mgAAAID5m3AVAAAAUDVLL710dtttt1x22WU5+uijG2yf2QpG06dPn+kxmzdvXtFY8p8VfRprxqpUZ555ZlZZZZWycxZaaKF6r2es0lMNyy+/fG677ba8+OKLWW+99crOefHFF5MkK6ywwnc+X21tbUqlUu66666y9/3b92ZOdevWLc8//3xGjhyZu+66K3fddVeuuOKK7L777rnqqqvm6Jhz8j5ZbrnlkiQvvfRSRee45pprsueee2abbbbJkUcemW7duqV58+Y59dRT6wJnjTW7ume8Z3fbbbeZhgIHDhw40+PPCPe9+OKLM33Pl3sP7bjjjjnmmGNy0003ZejQobnxxhvTqVOnegG42tradOvWLddee23Z4y666KL1Xs/Ln6WZ3ddy4998jzT2mgAAAID5m3AVAAAAUFW/+93vcs011+T0009vsG3GykETJ06sN/7WW2/NtXpmrEw1Q1EUGTduXF34ZMbj1zp27JhBgwY16bl79+6dV199tcH4K6+8Ure9sX7605/m1FNPzdVXX102XDV9+vRcd9116dKlS9ZZZ5162759L5Lktddey1JLLTXT8/Xt2zdFUaRPnz5ZZpllZjkvSV5++eVZ3sdZPSKwVatW2XLLLbPlllumtrY2Bx10UC699NIcd9xx6dev30z3a0rLLLNMll122dx+++0577zzZhseu/nmm7P00ktnxIgR9a7t24//69u3b0aOHJkJEyZUtHrVrCy66KLp0KFDpk+fPkfv2c033zzNmzfPn//85+y+++5l51x99dVp0aJFveBUnz59ssYaa+Qvf/lLDj744IwYMSLbbLNNWrduXTenb9++uffee7POOutUNYTYlL6P1wQAAAALsmbVLgAAAABYsPXt2ze77bZbLr300nzwwQf1tnXs2DGLLLJIRo8eXW/8oosummv1XH311fUef3bzzTfn/fffz+abb54kWW211dK3b9+cddZZ+eKLLxrs/+9//3uOz/2Tn/wkTz75ZB577LG6sS+//DKXXXZZllpqqTlaWWrttdfOoEGDcsUVV+Svf/1rg+2//e1v89prr+U3v/lNgyDIbbfdlnfffbfu9ZNPPpknnnii7l6Us91226V58+YZNmxYgxWfiqKoexTjqquumj59+mT48OENwnPf3K99+/ZJGgbsvv1Ix2bNmtUF4KZMmTLT+uaGYcOG5ZNPPsm+++6badOmNdh+zz331N37GaseffMan3jiiXrf8yTZfvvtUxRFhg0b1uB4jV1xrXnz5tl+++1zyy235OWXX26wfXbv2V69emWvvfbKvffem4svvrjB9ksuuST3339/9tlnnyyxxBL1tu244455/PHHc/nll+fjjz+u90jAJNlhhx0yffr0/P73v29w3GnTpjX4vv83+D5eEwAAACzIrFwFAAAAVN1vf/vb/PnPf86rr76aAQMG1Nu277775rTTTsu+++6b1VdfPaNHj85rr70212rp2rVrfvzjH2evvfbKhx9+mOHDh6dfv37Zb7/9kvwnxPPHP/4xm2++eQYMGJC99toriy++eN5999088MAD6dixY+644445OvfRRx+d66+/PptvvnkOOeSQdO3aNVdddVXGjx+fW265Jc2azdn/J3f11Vdn4403ztZbb51ddtkl6667bqZMmZIRI0bkwQcfzI477pgjjzyywX79+vXLj3/84xx44IGZMmVKhg8fnoUXXji/+c1vZnquvn375uSTT84xxxyTN998M9tss006dOiQ8ePH59Zbb83++++fI444Is2aNcvFF1+cLbfcMqusskr22muv9OjRI6+88kr+8Y9/ZOTIkUn+E2ZLkkMOOSSDBw9O8+bNs9NOO2XffffNhAkTstFGG2WJJZbIW2+9lQsuuCCrrLJK3WPs5pUdd9wxL730Uk455ZQ899xz2XnnndO7d+988sknufvuu3PffffluuuuS/KflcRGjBiRbbfdNltssUXGjx+fSy65JCussEK9sN6GG26YX/ziFzn//PMzduzYbLbZZqmtrc1DDz2UDTfcMAcffHCjajzttNPywAMPZM0118x+++2XFVZYIRMmTMizzz6be++9NxMmTJjl/ueee25eeeWVHHTQQbn77rvrVqgaOXJkbr/99qy//vo5++yzG+y3ww475IgjjsgRRxyRrl27Nlg5a/31188BBxyQU089Nc8//3w23XTTtGzZMmPHjs1NN92U8847Lz/72c8ada3V9n28JgAAAFiQCVcBAAAAVdevX7/stttuueqqqxpsO/744/Pvf/87N998c2688cZsvvnmueuuu9KtW7e5Usuxxx6bF198Maeeemo+//zzbLzxxrnooovSrl27ujkbbLBBHnvssfz+97/P//zP/+SLL75I9+7ds+aaa+aAAw6Y43MvtthiefTRR3PUUUflggsuyNdff52BAwfmjjvuyBZbbDHHx+3Ro0eefPLJnH322bnppptyyy23pEWLFhk4cGCuvPLK7L777mUfv7f77runWbNmGT58eD766KOsscYa+Z//+Z/06NFjluc7+uijs8wyy+Tcc8+tW3mpV69e2XTTTbPVVlvVzRs8eHAeeOCBDBs2LGeffXZqa2vTt2/fuiBb8p+VsH71q1/lhhtuyDXXXJOiKLLTTjtlt912y2WXXZaLLrooEydOTPfu3bPjjjvmxBNPnOMQ2ndx8sknZ6ONNsr555+fiy++OBMmTEiXLl3yox/9KLfffnvdde+555754IMPcumll2bkyJFZYYUVcs011+Smm27Kgw8+WO+YV1xxRQYOHJg//elPOfLII9OpU6esvvrqWXvttRtd32KLLZYnn3wyJ510UkaMGJGLLrooCy+8cAYMGFD2kZzfttBCC+W+++7LRRddlGuuuSZHHnlkiqLIcsstl+HDh+eggw5Ky5YtG+y3xBJLZO21184jjzySfffdt+ycSy65JKuttlouvfTSHHvssWnRokWWWmqp7Lbbbg0eVfnf4vt4TQAAALCgKhWNXUccAAAAAP5/xx13XE499dSyj8MDAAAAgP928/5/4wMAAADge+P999/PIossUu0yAAAAAGCu8FhAAAAAABrtjTfeyK233pqbbropP/3pT6tdDgAAAADMFVauAgAAAKDRRo8enWHDhmX99dfPOeec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ZPnll8/CCy+cs846a27UCAAAAAAAAAAAMM+1aOwOnTp1yqOPPppRo0blhRdeSNu2bTNw4MCst956c6M+AAAAAAAAAACAqmh0uCpJSqVSNt1006y33npp3bp1SqVSU9fFAsi7CAAAAAAAAACA+UmjHwtYW1ub3//+91l88cWz0EILZfz48UmS4447Ln/605+avEAAAAAAAAAAAIBqaHS46uSTT86VV16ZM844I61ataobX3HFFfPHP/6xSYtjwVBUuwAAAAAAAAAAACij0eGqq6++Opdddll23XXXNG/evG585ZVXziuvvNKkxQEAAAAAAAAAAFRLo8NV7777bvr169dgvLa2NjU1NU1SFAAAAAAAAAAAQLU1Oly1wgor5KGHHmowfvPNN+cHP/hBkxQFAAAAAAAAAABQbS0au8Pxxx+fPfbYI++++25qa2szYsSIvPrqq7n66qvz17/+dW7UCAAAAAAAAAAAMM81euWqrbfeOnfccUfuvffetG/fPscff3zGjBmTO+64I5tsssncqBEAAAAAAAAAAGCea/TKVUmy7rrrZtSoUU1dCwAAAAAAAAAAwHyj0StXAQAAAAAAAAAALAgqWrmqa9euee2117LIIoukS5cuKZVKM5270EILZcCAATn99NMzcODAJisUAAAAAAAAAABgXqooXHXuueemQ4cOSZLhw4fPcu6UKVNy5513Zq+99sozzzzznQsEAAAAAAAAAACohorCVXvssUfZr2dm8803z2qrrTbnVQEAAAAAAAAAAFRZReGqcp5++umMGTMmSbL88stn9dVXr9vWq1evfPTRR9+9OgAAAAAAAAAAgCppdLjqX//6V3beeec88sgj6dy5c5Jk4sSJWXvttXPDDTdkiSWWaOoa+b4rql0AAAAAAAAAAAA01KyxO+y7776pqanJmDFjMmHChEyYMCFjxoxJbW1t9t1337lRIwAAAAAAAAAAwDzX6JWr/v73v+fRRx/NsssuWze27LLL5oILLsi6667bpMUBAAAAAAAAAABUS6NXrurVq1dqamoajE+fPj09e/ZskqIAAAAAAAAAAACqrdHhqjPPPDO/+tWv8vTTT9eNPf300zn00ENz1llnNWlxAAAAAAAAAAAA1VLRYwG7dOmSUqlU9/rLL7/MmmuumRYt/rP7tGnT0qJFi+y9997ZZptt5kqhAAAAAAAAAAAA81JF4arhw4fP5TIAAAAAAAAAAADmLxWFq/bYY4+5XQcAAAAAAAAAAMB8paJw1Te9++67ueWWW/Laa68lSZZddtlst912WXzxxZu8OAAAAAAAAAAAgGppVLjqoosuyuGHH56pU6emY8eOSZJJkyblyCOPzDnnnJODDjporhTJgqFUqnYFAAAAAAAAAADwf5pVOvFvf/tbDjnkkBx88MF59913M3HixEycODHvvvtuDjrooBx66KG5884752atAAAAAAAAAAAA80zFK1edeeaZOfroo3PyySfXG+/Ro0fOOeectGvXLmeccUZ+8pOfNHmRfL8VKapdAgAAAAAAAAAANFDxylXPPvtsfvGLX8x0+y9+8Ys8++yzTVIUAAAAAAAAAABAtVUcrpo+fXpatmw50+0tW7bM9OnTm6QoAAAAAAAAAACAaqs4XDVgwIDcfvvtM91+2223ZcCAAU1SFAAAAAAAAAAAQLW1qHTikCFDcuCBB6Z169bZf//906LFf3adNm1aLr300vzud7/LRRddNNcKBQAAAAAAAAAAmJcqDlftscceeemll3LwwQfnmGOOSd++fVMURd5444188cUXOeSQQ7LnnnvOxVIBAAAAAAAAAADmnYrDVUly1lln5Wc/+1muv/76jB07Nkmy/vrrZ6eddsqPfvSjuVIgAAAAAAAAAABANTQqXJUkP/rRjwSpAAAAAAAAAACA771m1S4AAAAAAAAAAABgfiRcxXyjVO0CAAAAAAAAAADgG4SrAAAAAAAAAAAAyhCuAgAAAAAAAAAAKEO4iqorimpXAAAAAAAAAAAADbWoZNIPfvCDlEqlig747LPPfqeCAAAAAAAAAAAA5gcVhau22Wabuq+//vrrXHTRRVlhhRWy1lprJUkef/zx/OMf/8hBBx00V4oEAAAAAAAAAACY1yoKV51wwgl1X++777455JBD8vvf/77BnHfeeadpqwMAAAAAAAAAAKiSZo3d4aabbsruu+/eYHy33XbLLbfc0iRFAQAAAAAAAAAAVFujw1Vt27bNI4880mD8kUceSZs2bZqkKAAAAAAAAAAAgGqr6LGA3zR06NAceOCBefbZZ7PGGmskSZ544olcfvnlOe6445q8QAAAAAAAAAAAgGpodLjq6KOPztJLL53zzjsv11xzTZJk+eWXzxVXXJEddtihyQsEAAAAAAAAAACohkaHq5Jkhx12EKQCAAAAAAAAAAC+15rNyU4TJ07MH//4xxx77LGZMGFCkuTZZ5/Nu+++26TFAQAAAAAAAAAAVEujV6568cUXM2jQoHTq1Clvvvlm9t1333Tt2jUjRozI22+/nauvvnpu1AkAAAAAAAAAADBPNXrlqsMPPzx77rlnxo4dmzZt2tSN/+QnP8no0aObtDgAAAAAAAAAAIBqaXS46qmnnsoBBxzQYHzxxRfPBx980CRFfdO7776b3XbbLQsvvHDatm2blVZaKU8//XSTn4fqKapdAAAAAAAAAAAAlNHoxwK2bt06kyZNajD+2muvZdFFF22Somb49NNPs84662TDDTfMXXfdlUUXXTRjx45Nly5dmvQ8AAAAAAAAAAAA39bocNVWW22Vk046KTfeeGOSpFQq5e23385RRx2V7bffvkmLO/3009OrV69cccUVdWN9+vRp0nMAAAAAAAAAAACU0+hw1dlnn52f/exn6datW7766qusv/76+eCDD7LWWmvllFNOadLi/t//+38ZPHhwfv7zn+fvf/97Fl988Rx00EHZb7/9ZrrPlClTMmXKlLrXM1bZqqmpSU1NTZPWR9OYPn163de+R8CszOgRegUwO/oFUAm9AqiUfgFUQq8AKqVfAJXSL4BK6BVzrtJ7ViqKopiTEzz88MN58cUX88UXX2TVVVfNoEGD5uQws9SmTZskyeGHH56f//zneeqpp3LooYfmkksuyR577FF2nxNPPDHDhg1rMH7dddelXbt2TV4j392jH5bylzeaZ8UutdlvudpqlwMAAAAAAAAAwPfc5MmTs8suu+Szzz5Lx44dZzpvjsNV80KrVq2y+uqr59FHH60bO+SQQ/LUU0/lscceK7tPuZWrevXqlY8//niWN4Lq+cvT/8rvbv9nVuxSmxt/tXFatmxZ7ZKA+VRNTU1GjRqVTTbZRK8AZkm/ACqhVwCV0i+ASugVQKX0C6BS+gVQCb1izk2aNCmLLLLIbMNVjX4sYJLcd999ue+++/LRRx+ltrb+SkOXX375nByyrB49emSFFVaoN7b88svnlltumek+rVu3TuvWrRuMt2zZ0ptoPtW8efO6r32fgEroFUCl9AugEnoFUCn9AqiEXgFUSr8AKqVfAJXQKxqv0vvV6HDVsGHDctJJJ2X11VdPjx49UiqVGl1cpdZZZ528+uqr9cZee+219O7de66dEwAAAAAAAAAAIJmDcNUll1ySK6+8Mr/4xS/mRj31HHbYYVl77bXzhz/8ITvssEOefPLJXHbZZbnsssvm+rmZ9+ZeTA8AAAAAAAAAABqvWWN3mDp1atZee+25UUsDP/zhD3Prrbfm+uuvz4orrpjf//73GT58eHbdddd5cn4AAAAAAAAAAGDB1ehw1b777pvrrrtubtRS1k9/+tO89NJL+frrrzNmzJjst99+8+zcAAAAAAAAAADAgquixwIefvjhdV/X1tbmsssuy7333puBAwemZcuW9eaec845TVshAAAAAAAAAABAFVQUrnruuefqvV5llVWSJC+//HK98VKp1DRVsUApimpXAAAAAAAAAAAADVUUrnrggQfmdh0AAAAAAAAAAADzlWaN3eGzzz7LhAkTGoxPmDAhkyZNapKiAAAAAAAAAAAAqq3R4aqddtopN9xwQ4PxG2+8MTvttFOTFAUAAAAAAAAAAFBtjQ5XPfHEE9lwww0bjG+wwQZ54oknmqQoAAAAAAAAAACAamt0uGrKlCmZNm1ag/Gampp89dVXTVIUAAAAAAAAAABAtTU6XLXGGmvksssuazB+ySWXZLXVVmuSogAAAAAAAAAAAKqtRWN3OPnkkzNo0KC88MIL2XjjjZMk9913X5566qncc889TV4gAAAAAAAAAABANTR65ap11lknjz32WHr16pUbb7wxd9xxR/r165cXX3wx66677tyoEQAAAAAAAAAAYJ5r9MpVSbLKKqvk2muvbepaAAAAAAAAAAAA5htzFK6a4euvv87UqVPrjXXs2PE7FQQAAAAAAAAAADA/aPRjASdPnpyDDz443bp1S/v27dOlS5d6f6CxihTVLgEAAAAAAAAAABpodLjqyCOPzP3335+LL744rVu3zh//+McMGzYsPXv2zNVXXz03agQAAAAAAAAAAJjnGv1YwDvuuCNXX311Nthgg+y1115Zd911069fv/Tu3TvXXnttdt1117lRJwAAAAAAAAAAwDzV6JWrJkyYkKWXXjpJ0rFjx0yYMCFJ8uMf/zijR49u2uoAAAAAAAAAAACqpNHhqqWXXjrjx49Pkiy33HK58cYbk/xnRavOnTs3aXEAAAAAAAAAAADV0uhw1V577ZUXXnghSXL00UfnwgsvTJs2bXLYYYflyCOPbPICAQAAAAAAAAAAqqFFY3c47LDD6r4eNGhQXnnllTzzzDPp169fBg4c2KTFAQAAAAAAAAAAVEujw1Xf1rt37/Tu3bspamEBVypVuwIAAAAAAAAAAPg/FT8W8P77788KK6yQSZMmNdj22WefZcCAAXnooYeatDgAAAAAAAAAAIBqqThcNXz48Oy3337p2LFjg22dOnXKAQcckHPOOadJiwMAAAAAAAAAAKiWisNVL7zwQjbbbLOZbt90003zzDPPNElRAAAAAAAAAAAA1VZxuOrDDz9My5YtZ7q9RYsW+fe//90kRQEAAAAAAAAAAFRbxeGqxRdfPC+//PJMt7/44ovp0aNHkxTFgqUoql0BAAAAAAAAAAA0VHG46ic/+UmOO+64fP311w22ffXVVznhhBPy05/+tEmLAwAAAAAAAAAAqJYWlU783e9+lxEjRmSZZZbJwQcfnGWXXTZJ8sorr+TCCy/M9OnT89vf/nauFQoAAAAAAAAAADAvVRyuWmyxxfLoo4/mwAMPzDHHHJPi/3+WW6lUyuDBg3PhhRdmscUWm2uFAgAAAAAAAAAAzEsVh6uSpHfv3rnzzjvz6aefZty4cSmKIv3790+XLl3mVn0AAAAAAAAAAABV0ahw1QxdunTJD3/4w6auBQAAAAAAAAAAYL7RrNoFAAAAAAAAAAAAzI+EqwAAAAAAAAAAAMoQrgIAAAAAAAAAACijonDVqquumk8//TRJctJJJ2Xy5MlztSgAAAAAAAAAAIBqqyhcNWbMmHz55ZdJkmHDhuWLL76Yq0UBAAAAAAAAAABUW4tKJq2yyirZa6+98uMf/zhFUeSss87KQgstVHbu8ccf36QFAgAAAAAAAAAAVENF4aorr7wyJ5xwQv7617+mVCrlrrvuSosWDXctlUrCVTRaUe0CAAAAAAAAAACgjIrCVcsuu2xuuOGGJEmzZs1y3333pVu3bnO1MAAAAAAAAAAAgGqqKFz1TbW1tXOjDgAAAAAAAAAAgPlKo8NVSfL6669n+PDhGTNmTJJkhRVWyKGHHpq+ffs2aXEAAAAAAAAAAADV0qyxO4wcOTIrrLBCnnzyyQwcODADBw7ME088kQEDBmTUqFFzo0YAAAAAAAAAAIB5rtErVx199NE57LDDctpppzUYP+qoo7LJJps0WXEAAAAAAAAAAADV0uiVq8aMGZN99tmnwfjee++df/7zn01SFAumUrULAAAAAAAAAACAb2h0uGrRRRfN888/32D8+eefT7du3ZqiJgAAAAAAAAAAgKpr9GMB99tvv+y///554403svbaaydJHnnkkZx++uk5/PDDm7xAAAAAAAAAAACAamh0uOq4445Lhw4dcvbZZ+eYY45JkvTs2TMnnnhiDjnkkCYvEAAAAAAAAAAAoBoaHa4qlUo57LDDcthhh+Xzzz9PknTo0KHJCwMAAAAAAAAAAKimRoervkmoiiZRFNWuAAAAAAAAAAAAGmhW7QIAAAAAAAAAAADmR8JVAAAAAAAAAAAAZQhXAQAAAAAAAAAAlNGocFVNTU023njjjB07dm7VAwAAAAAAAAAAMF9oVLiqZcuWefHFF+dWLQAAAAAAAAAAAPONRj8WcLfddsuf/vSnuVELC7hStQsAAAAAAAAAAIBvaNHYHaZNm5bLL7889957b1ZbbbW0b9++3vZzzjmnyYoDAAAAAAAAAAColkaHq15++eWsuuqqSZLXXnut3rZSydpDAAAAAAAAAADA90Ojw1UPPPDA3KgDAAAAAAAAAABgvtJsTnccN25cRo4cma+++ipJUhRFkxUFAAAAAAAAAABQbY0OV33yySfZeOONs8wyy+QnP/lJ3n///STJPvvsk1//+tdNXiAAAAAAAAAAAEA1NDpcddhhh6Vly5Z5++23065du7rxHXfcMXfffXeTFseCwZpnAAAAAAAAAADMj1o0dod77rknI0eOzBJLLFFvvH///nnrrbearDAAAAAAAAAAAIBqavTKVV9++WW9FatmmDBhQlq3bt0kRQEAAAAAAAAAAFRbo8NV6667bq6++uq616VSKbW1tTnjjDOy4YYbNmlxAAAAAAAAAAAA1dLoxwKeccYZ2XjjjfP0009n6tSp+c1vfpN//OMfmTBhQh555JG5USMAAAAAAAAAAMA81+iVq1ZcccW89tpr+fGPf5ytt946X375Zbbbbrs899xz6du379yoEQAAAAAAAAAAYJ5r9MpVSdKpU6f89re/bepaWNCVql0AAAAAAAAAAAD8nzkKV3366af505/+lDFjxiRJVlhhhey1117p2rVrkxYHAAAAAAAAAABQLY1+LODo0aOz1FJL5fzzz8+nn36aTz/9NOeff3769OmT0aNHz40a65x22mkplUoZOnToXD0PAAAAAAAAAABAo1euGjJkSHbcccdcfPHFad68eZJk+vTpOeiggzJkyJC89NJLTV5kkjz11FO59NJLM3DgwLlyfAAAAAAAAAAAgG9q9MpV48aNy69//eu6YFWSNG/ePIcffnjGjRvXpMXN8MUXX2TXXXfN//7v/6ZLly5z5RwAAAAAAAAAAADf1OiVq1ZdddWMGTMmyy67bL3xMWPGZOWVV26ywr5pyJAh2WKLLTJo0KCcfPLJs5w7ZcqUTJkype71pEmTkiQ1NTWpqamZK/Xx3UyfPr3ua98jYFZm9Ai9Apgd/QKohF4BVEq/ACqhVwCV0i+ASukXQCX0ijlX6T2rKFz14osv1n19yCGH5NBDD824cePyox/9KEny+OOP58ILL8xpp502B6XO2g033JBnn302Tz31VEXzTz311AwbNqzB+D333JN27do1dXk0gZffLyX5z0poo0aNqm4xwH8FvQKolH4BVEKvACqlXwCV0CuASukXQKX0C6ASekXjTZ48uaJ5paIoitlNatasWUqlUmY3tVQq1VuF6Lt65513svrqq2fUqFEZOHBgkmSDDTbIKquskuHDh5fdp9zKVb169crHH3+cjh07NlltNJ0/P/52TvrbK1ll4dpcN2TjtGzZstolAfOpmpqajBo1KptssoleAcySfgFUQq8AKqVfAJXQK4BK6RdApfQLoBJ6xZybNGlSFllkkXz22WezzBRVtHLV+PHjm6ywxnjmmWfy0UcfZdVVV60bmz59ekaPHp3/+Z//yZQpU9K8efN6+7Ru3TqtW7ducKyWLVt6E82nvvk99H0CKqFXAJXSL4BK6BVApfQLoBJ6BVAp/QKolH4BVEKvaLxK71dF4arevXt/p2Lm1MYbb5yXXnqp3thee+2V5ZZbLkcddVSDYBUAAAAAAAAAAEBTqShc9W3vvfdeHn744Xz00Uepra2tt+2QQw5pksKSpEOHDllxxRXrjbVv3z4LL7xwg3EAAAAAAAAAAICm1Ohw1ZVXXpkDDjggrVq1ysILL5xSqVS3rVQqNWm4igVLafZTAAAAAAAAAABgnml0uOq4447L8ccfn2OOOSbNmjWbGzXN0oMPPjjPzwkAAAAAAAAAACx4Gp2Omjx5cnbaaaeqBKsAAAAAAAAAAADmlUYnpPbZZ5/cdNNNc6MWAAAAAAAAAACA+UajHwt46qmn5qc//WnuvvvurLTSSmnZsmW97eecc06TFQcAAAAAAAAAAFAtcxSuGjlyZJZddtkkSalUqtv2za8BAAAAAAAAAAD+mzU6XHX22Wfn8ssvz5577jkXymFBVBRFtUsAAAAAAAAAAIAGmjV2h9atW2edddaZG7UAAAAAAAAAAADMNxodrjr00ENzwQUXzI1aAAAAAAAAAAAA5huNfizgk08+mfvvvz9//etfM2DAgLRs2bLe9hEjRjRZcQAAAAAAAAAAANXS6HBV586ds912282NWgAAAAAAAAAAAOYbjQ5XXXHFFXOjDgAAAAAAAAAAgPlKs2oXAAAAAAAAAAAAMD9q9MpVffr0SalUmun2N9544zsVBAAAAAAAAAAAMD9odLhq6NCh9V7X1NTkueeey913350jjzyyqeoCAAAAAAAAAACoqkaHqw499NCy4xdeeGGefvrp71wQAAAAAAAAAADA/KBZUx1o8803zy233NJUhwMAAAAAAAAAAKiqJgtX3XzzzenatWtTHQ4AAAAAAAAAAKCqGv1YwB/84AcplUp1r4uiyAcffJB///vfueiii5q0OBYMRbULAAAAAAAAAACAMhodrtpmm23qvW7WrFkWXXTRbLDBBlluueWaqi4AAAAAAAAAAICqanS46oQTTpgbdQAAAAAAAAAAAMxXmlW7AAAAAAAAAAAAgPlRxStXNWvWLKVSaZZzSqVSpk2b9p2LYsE063cXAAAAAAAAAADMWxWHq2699daZbnvsscdy/vnnp7a2tkmKAgAAAAAAAAAAqLaKw1Vbb711g7FXX301Rx99dO64447suuuuOemkk5q0OAAAAAAAAAAAgGppNic7vffee9lvv/2y0korZdq0aXn++edz1VVXpXfv3k1dHwAAAAAAAAAAQFU0Klz12Wef5aijjkq/fv3yj3/8I/fdd1/uuOOOrLjiinOrPgAAAAAAAAAAgKqo+LGAZ5xxRk4//fR07949119/fdnHBAIAAAAAAAAAAHxfVByuOvroo9O2bdv069cvV111Va666qqy80aMGNFkxQEAAAAAAAAAAFRLxeGq3XffPaVSaW7WAgAAAAAAAAAAMN+oOFx15ZVXzsUyWJAVRbUrAAAAAAAAAACAhppVuwAAAAAAAAAAAID5kXAVAAAAAAAAAABAGcJVAAAAAAAAAAAAZQhXAQAAAAAAAAAAlCFcBQAAAAAAAAAAUIZwFQAAAAAAAAAAQBnCVQAAAAAAAAAAAGUIVwEAAAAAAAAAAJQhXAUAAAAAAAAAAFCGcBUAAAAAAAAAAEAZwlUAAAAAAAAAAABlCFdRdUW1CwAAAAAAAAAAgDKEqwAAAAAAAAAAAMoQrgIAAAAAAAAAAChDuIr5RqlU7QoAAAAAAAAAAOD/CFcBAAAAAAAAAACUIVwFAAAAAAAAAABQhnAVAAAAAAAAAABAGcJVAAAAAAAAAAAAZQhXAQAAAAAAAAAAlCFcBQAAAAAAAAAAUIZwFQAAAAAAAAAAQBnCVVRdURTVLgEAAAAAAAAAABoQrgIAAAAAAAAAAChDuAoAAAAAAAAAAKAM4SoAAAAAAAAAAIAyhKsAAAAAAAAAAADKEK4CAAAAAAAAAAAoQ7gKAAAAAAAAAACgDOEqAAAAAAAAAACAMoSrAAAAAAAAAAAAyhCuAgAAAAAAAAAAKEO4CgAAAAAAAAAAoAzhKgAAAAAAAAAAgDKEqwAAAAAAAAAAAMoQrgIAAAAAAAAAAChDuAoAAAAAAAAAAKCM+Tpcdeqpp+aHP/xhOnTokG7dumWbbbbJq6++Wu2ymEtK1S4AAAAAAAAAAAC+Yb4OV/3973/PkCFD8vjjj2fUqFGpqanJpptumi+//LLapQEAAAAAAAAAAN9zLapdwKzcfffd9V5feeWV6datW5555pmst956VaoKAAAAAAAAAABYEMzX4apv++yzz5IkXbt2nemcKVOmZMqUKXWvJ02alCSpqalJTU3N3C2QOTJ9+vS6r32PgFmZ0SP0CmB29AugEnoFUCn9AqiEXgFUSr8AKqVfAJXQK+ZcpfesVBRFMZdraRK1tbXZaqutMnHixDz88MMznXfiiSdm2LBhDcavu+66tGvXbm6WyBx64L1SbnureVZfpDa/6F9b7XIAAAAAAAAAAPiemzx5cnbZZZd89tln6dix40zn/deEqw488MDcddddefjhh7PEEkvMdF65lat69eqVjz/+eJY3guq5/JE3c+rdr2X1RWpz9UEbp2XLltUuCZhP1dTUZNSoUdlkk030CmCW9AugEnoFUCn9AqiEXgFUSr8AKqVfAJXQK+bcpEmTssgii8w2XPVf8VjAgw8+OH/9618zevToWQarkqR169Zp3bp1g/GWLVt6E82nmjdvXve17xNQCb0CqJR+AVRCrwAqpV8AldArgErpF0Cl9AugEnpF41V6v+brcFVRFPnVr36VW2+9NQ8++GD69OlT7ZIAAAAAAAAAAIAFxHwdrhoyZEiuu+663H777enQoUM++OCDJEmnTp3Stm3bKlcHAAAAAAAAAAB8nzWrdgGzcvHFF+ezzz7LBhtskB49etT9+ctf/lLt0mhCRVHtCgAAAAAAAAAAoKH5euWqQuoGAAAAAAAAAACokvl65SoWLKVqFwAAAAAAAAAAAN8gXAUAAAAAAAAAAFCGcBUAAAAAAAAAAEAZwlUAAAAAAAAAAABlCFcBAAAAAAAAAACUIVwFAAAAAAAAAABQhnAVAAAAAAAAAABAGcJVAAAAAAAAAAAAZQhXAQAAAAAAAAAAlCFcRdUVKapdAgAAAAAAAAAANCBcBQAAAAAAAAAAUIZwFfOPUrULAAAAAAAAAACA/yNcBQAAAAAAAAAAUIZwFQAAAAAAAAAAQBnCVQAAAAAAAAAAAGUIVwEAAAAAAAAAAJQhXAUAAAAAAAAAAFBGi2oXAAAAAAAAAADAf7+iKDJt2rRMnz692qUsMGpqatKiRYt8/fXX7vu3NG/ePC1atEipVPpOxxGuAgAAAAAAAADgO5k6dWref//9TJ48udqlLFCKokj37t3zzjvvfOcQ0fdRu3bt0qNHj7Rq1WqOjyFcBQAAAAAAAADAHKutrc348ePTvHnz9OzZM61atRL0mUdqa2vzxRdfZKGFFkqzZs2qXc58oyiKTJ06Nf/+978zfvz49O/ff47vj3AVAAAAAAAAAABzbOrUqamtrU2vXr3Srl27apezQKmtrc3UqVPTpk0b4apvadu2bVq2bJm33nqr7h7NCXeVqiuKalcAAAAAAAAAAHxXwj3Mb5riPeldzXzDgoAAAAAAAAAAAMxPhKsAAAAAAAAAAADKEK4CAAAAAAAAAIBZWGqppTJ8+PDvPGdemx9rmpn5tVbhKgAAAAAAAAAAFkjvvPNO9t577/Ts2TOtWrVK7969c+ihh+aTTz5p9LGeeuqp7L///k1WW1OEjZqqpnHjxmWvvfbKEksskdatW6dPnz7Zeeed8/TTT3/nY8/vhKsAAAAAAAAAAFjgvPHGG1l99dUzduzYXH/99Rk3blwuueSS3HfffVlrrbUyYcKERh1v0UUXTbt27eZStXOmKWp6+umns9pqq+W1117LpZdemn/+85+59dZbs9xyy+XXv/51E1U6/xKuAgAAAAAAAACgyRRFkclTp1XlT1EUFdc5ZMiQtGrVKvfcc0/WX3/9LLnkktl8881z77335t13381vf/vbevM///zz7Lzzzmnfvn0WX3zxXHjhhfW2f3ulqYkTJ2bffffNoosumo4dO2ajjTbKCy+8UG+fO+64Iz/84Q/Tpk2bLLLIItl2222TJBtssEHeeuutHHbYYSmVSimVSkmSt956K1tuuWW6dOmS9u3bZ6WVVso999wz02v8dk2lUil//OMfs+2226Zdu3bp379//t//+38z3b8oiuy5557p379/HnrooWyxxRbp27dvVllllZxwwgm5/fbb6+YeddRRWWaZZdKuXbssvfTSOe6441JTU1PR9c4wefLk7L333unQoUOWXHLJXHbZZfW2v/POO9lhhx3SuXPndO3aNVtvvXXefPPNmdbfFFrM1aMDAAAAAAAAALBA+apmelY4fmRVzv3PkwanXavZx2EmTJiQkSNH5pRTTknbtm3rbevevXt23XXX/OUvf8lFF11UF2w688wzc+yxx2bYsGEZOXJkDj300CyzzDLZZJNNyp7j5z//edq2bZu77rornTp1yqWXXpqNN944r732Wrp27Zq//e1v2XbbbfPb3/42V199daZOnZo777wzSTJixIisvPLK2X///bPffvvVHXPIkCGZOnVqRo8enfbt2+fll19O8+bNG3WPhg0bljPOOCNnnnlmLrjgguy6665566230rVr1wZzn3/++fzjH//Iddddl2bNGq7h1Llz57qvO3TokCuvvDI9e/bMSy+9lP322y8dOnTIb37zmySZ5fXOcPbZZ+f3v/99jj322Nx888058MADs/7662fZZZdNTU1NBg8enLXWWisPPfRQWrRokZNPPjmbbbZZXnzxxbRq1apR96FSwlUAAAAAAAAAACxQxo4dm6Iosvzyy5fdvvzyy+fTTz/Nv//973Tr1i1Jss466+Too49OkiyzzDJ55JFHcu6555YNVz388MN58skn89FHH6V169ZJkrPOOiu33XZbbr755uy///455ZRTstNOO2XYsGF1+6288spJkq5du6Z58+bp0KFDunfvXrf97bffzvbbb5+VVlopyX9Wppo0aVKjrn3PPffMzjvvnCT5wx/+kPPPPz9PPvlkNttss7L3KUmWW2652R73d7/7Xd3XSy21VI444ojccMMNdeGqWV3vDD/5yU9y0EEHJfnPSljnnntuHnjggSy77LL5y1/+ktra2vzxj3+sC7xdccUV6dy5cx588MFsuummjbkNFROuAgAAAAAAAACgybRt2Tz/PGlw1c7dGI15jOBaa63V4PU3H7n3TS+88EK++OKLLLzwwvXGv/rqq7z++utJ/rMq1DdXparEIYcckgMPPDD33HNPBg0alG233TZLLbVUo44xcODAuq/bt2+fjh075qOPPio7tzH35y9/+UvOP//8vP766/niiy8ybdq0dOzYsW57Jdf7zdpKpVK6d+9eV9sLL7yQcePGpUOHDvX2+frrr+vu6dwgXAUAAAAAAAAAQJMplUoVPZqvmvr165dSqZQxY8Zk2223bbB9zJgx6dKlSxZddNE5Ov4XX3yRHj165MEHH2ywbcaj9L79OMJK7Lvvvhk8eHD+9re/5Z577smpp56ak08+OUcccUTFx2jZsmW916VSKbW1tWXnLrPMMkmSV155JT/4wQ9meszHHnssu+66a4YNG5bBgwenU6dOueGGG3L22WfXzankemdV2xdffJHVVlst1157bYP95vT7VImGD0MEAAAAAAAAAIDvsYUXXjibbLJJLrroonz11Vf1tn3wwQe59tprs+OOO9Y9fi5JHn/88XrzHn/88Zk+VnDVVVfNBx98kBYtWqRfv371/iyyyCJJ/rNK03333TfTGlu1apXp06c3GO/Vq1d++ctfZsSIETn88MNz1VVXVXzdjbXKKqtkhRVWyNlnn102gDVx4sQkyaOPPprevXvnt7/9bVZfffX0798/b731Vr25s7ve2Vl11VUzduzYdOvWrcE97dSp0xwfd3aEq6i6LQb2yFV7rpaNepZPQQIAAAAAAAAANLX/+Z//yZQpUzJ48OCMHj0677zzTu6+++5ssskmWXzxxXPKKafUm//II4/kjDPOyGuvvZYLL7wwN910Uw499NCyxx40aFDWWmutbLPNNrnnnnvy5ptv5tFHH81vf/vbPP3000mSE044Iddff31OOOGEjBkzJi+99FJOP/30umMstdRSGT16dN599918/PHHSZKhQ4dm5MiRGT9+fJ599tk8+OCDWXbZZefSHfrPylFXXHFFXnvttay77rq5884788Ybb+TFF1/MKaeckq233jpJ0r9//7z99tu54YYb8vrrr+f888/PrbfeWu9Ys7ve2dl1112zyCKLZOutt85DDz2U8ePH58EHH8whhxySf/3rX0163d8kXEXVLdGlXdbuu3B6tKt2JQAAAAAAAADAgqJ///55+umns/TSS2eHHXZI3759s//++2fDDTfMY489lq5du9ab/+tf/zpPP/10fvCDH+Tkk0/OOeeck8GDB5c9dqlUyp133pn11lsve+21V5ZZZpnstNNOeeutt7LYYoslSTbYYIPcdNNN+X//7/9llVVWyUYbbZQnn3yy7hgnnXRS3nzzzfTt27fusXfTp0/PkCFDsvzyy2ezzTZL//79c9ZZZ82lO/Qfa6yxRp5++un069cv++23X5ZffvlstdVW+cc//pHhw4cnSbbaaqscdthhOfjgg7PKKqvk0UcfzXHHHVfvOLO73tlp165dRo8enSWXXDLbbbddll9++eyzzz75+uuv07Fjx6a85Hrm7wdcAgAAAAAAAADAXNK7d+9ceeWVs5335ptvznbOlClTstBCC9W97tChQ84///ycf/75M91nu+22y3bbbVd2249+9KO88MIL9cYuuOCCeq9ra2szadKkiusuiqLBnBmP9puVZZZZZraPHzzjjDNyxhln1BsbOnRovdezut5y9/j555+v97p79+5z9TGI5QhXAQAAAAAAAADAHJo8eXIeeeSRfPjhhxkwYEC1y6GJeSwgAAAAAAAAAADMocsuuyw77bRThg4dmrXWWqva5dDErFwFAAAAAAAAAABzaOjQoQ0ef8f3h5WrAAAAAAAAAAAAyhCuAgAAAAAAAADgOyuKotolQD1N8Z4UrgIAAAAAAAAAYI61bNkySTJ58uQqVwL1zXhPzniPzokWTVUMAAAAAAAAAAALnubNm6dz58756KOPkiTt2rVLqVSqclULhtra2kydOjVff/11mjWzxtIMRVFk8uTJ+eijj9K5c+c0b958jo8lXAUAAAAAAAAAwHfSvXv3JKkLWDFvFEWRr776Km3bthVoK6Nz58517805JVwFAAAAAAAAAMB3UiqV0qNHj3Tr1i01NTXVLmeBUVNTk9GjR2e99db7To+++z5q2bLld1qxagbhKgAAAAAAAAAAmkTz5s2bJNBCZZo3b55p06alTZs2wlVziYctAgAAAAAAAAAAlCFcBQAAAAAAAAAAUIZwFQAAAAAAAAAAQBktql3A3FYURZJk0qRJVa6EWampqcnkyZMzadIkzwAFZkqvACqlXwCV0CuASukXQCX0CqBS+gVQKf0CqIReMedmZIlmZItm5nsfrvr888+TJL169apyJQAAAAAAAAAAwPzk888/T6dOnWa6vVTMLn71X662tjbvvfdeOnTokFKpVO1ymIlJkyalV69eeeedd9KxY8dqlwPMp/QKoFL6BVAJvQKolH4BVEKvACqlXwCV0i+ASugVc64oinz++efp2bNnmjVrNtN53/uVq5o1a5Ylllii2mVQoY4dO/phB2ZLrwAqpV8AldArgErpF0Al9AqgUvoFUCn9AqiEXjFnZrVi1Qwzj10BAAAAAAAAAAAswISrAAAAAAAAAAAAyhCuYr7QunXrnHDCCWndunW1SwHmY3oFUCn9AqiEXgFUSr8AKqFXAJXSL4BK6RdAJfSKua9UFEVR7SIAAAAAAAAAAADmN1auAgAAAAAAAAAAKEO4CgAAAAAAAAAAoAzhKgAAAAAAAAAAgDKEqwAAAAAAAAAAAMoQrqLqLrzwwiy11FJp06ZN1lxzzTz55JPVLgmYi0499dT88Ic/TIcOHdKtW7dss802efXVV+vN2WCDDVIqler9+eUvf1lvzttvv50tttgi7dq1S7du3XLkkUdm2rRp9eY8+OCDWXXVVdO6dev069cvV1555dy+PKCJnHjiiQ36wHLLLVe3/euvv86QIUOy8MILZ6GFFsr222+fDz/8sN4x9AlYMCy11FIN+kWpVMqQIUOS+FwBC7LRo0dnyy23TM+ePVMqlXLbbbfV214URY4//vj06NEjbdu2zaBBgzJ27Nh6cyZMmJBdd901HTt2TOfOnbPPPvvkiy++qDfnxRdfzLrrrps2bdqkV69eOeOMMxrUctNNN2W55ZZLmzZtstJKK+XOO+9s8usF5sysekVNTU2OOuqorLTSSmnfvn169uyZ3XffPe+99169Y5T7PHLaaafVm6NXwH+/2X222HPPPRv0gs0226zeHJ8t4Ptvdr2i3L9hlEqlnHnmmXVzfLaA779Kfl86L38PIrMxe8JVVNVf/vKXHH744TnhhBPy7LPPZuWVV87gwYPz0UcfVbs0YC75+9//niFDhuTxxx/PqFGjUlNTk0033TRffvllvXn77bdf3n///bo/3/yLwfTp07PFFltk6tSpefTRR3PVVVflyiuvzPHHH183Z/z48dliiy2y4YYb5vnnn8/QoUOz7777ZuTIkfPsWoHvZsCAAfX6wMMPP1y37bDDDssdd9yRm266KX//+9/z3nvvZbvttqvbrk/AguOpp56q1ytGjRqVJPn5z39eN8fnClgwffnll1l55ZVz4YUXlt1+xhln5Pzzz88ll1ySJ554Iu3bt8/gwYPz9ddf183Zdddd849//COjRo3KX//614wePTr7779/3fZJkyZl0003Te/evfPMM8/kzDPPzIknnpjLLrusbs6jjz6anXfeOfvss0+ee+65bLPNNtlmm23y8ssvz72LByo2q14xefLkPPvssznuuOPy7LPPZsSIEXn11Vez1VZbNZh70kkn1fu88atf/apum14B3w+z+2yRJJtttlm9XnD99dfX2+6zBXz/za5XfLNHvP/++7n88stTKpWy/fbb15vnswV8v1Xy+9J59XsQmY0KFVBFa6yxRjFkyJC619OnTy969uxZnHrqqVWsCpiXPvrooyJJ8fe//71ubP311y8OPfTQme5z5513Fs2aNSs++OCDurGLL7646NixYzFlypSiKIriN7/5TTFgwIB6++24447F4MGDm/YCgLnihBNOKFZeeeWy2yZOnFi0bNmyuOmmm+rGxowZUyQpHnvssaIo9AlYkB166KFF3759i9ra2qIofK4A/iNJceutt9a9rq2tLbp3716ceeaZdWMTJ04sWrduXVx//fVFURTFP//5zyJJ8dRTT9XNueuuu4pSqVS8++67RVEUxUUXXVR06dKlrl8URVEcddRRxbLLLlv3eocddii22GKLevWsueaaxQEHHNCk1wh8d9/uFeU8+eSTRZLirbfeqhvr3bt3ce655850H70Cvn/K9Ys99tij2HrrrWe6j88WsOCp5LPF1ltvXWy00Ub1xny2gAXPt39fOi9/DyKzURkrV1E1U6dOzTPPPJNBgwbVjTVr1iyDBg3KY489VsXKgHnps88+S5J07dq13vi1116bRRZZJCuuuGKOOeaYTJ48uW7bY489lpVWWimLLbZY3djgwYMzadKk/OMf/6ib883+MmOO/gL/PcaOHZuePXtm6aWXzq677pq33347SfLMM8+kpqam3s/4csstlyWXXLLuZ1yfgAXT1KlTc80112TvvfdOqVSqG/e5Avi28ePH54MPPqj3s92pU6esueaa9T5PdO7cOauvvnrdnEGDBqVZs2Z54okn6uast956adWqVd2cwYMH59VXX82nn35aN0cPge+Pzz77LKVSKZ07d643ftppp2XhhRfOD37wg5x55pn1HsWhV8CC48EHH0y3bt2y7LLL5sADD8wnn3xSt81nC+DbPvzww/ztb3/LPvvs02CbzxawYPn270vn1e9BZDYq16LaBbDg+vjjjzN9+vR6P+xJsthii+WVV16pUlXAvFRbW5uhQ4dmnXXWyYorrlg3vssuu6R3797p2bNnXnzxxRx11FF59dVXM2LEiCTJBx98ULZ3zNg2qzmTJk3KV199lbZt287NSwO+ozXXXDNXXnllll122bz//vsZNmxY1l133bz88sv54IMP0qpVqwa/zFhsscVm2wNmbJvVHH0C/nvddtttmThxYvbcc8+6MZ8rgHJm/HyX+9n+5s9+t27d6m1v0aJFunbtWm9Onz59GhxjxrYuXbrMtIfMOAbw3+Prr7/OUUcdlZ133jkdO3asGz/kkEOy6qqrpmvXrnn00UdzzDHH5P33388555yTRK+ABcVmm22W7bbbLn369Mnrr7+eY489Nptvvnkee+yxNG/e3GcLoIGrrroqHTp0qPeYr8RnC1jQlPt96bz6Pcinn34qs1Eh4SoAqmbIkCF5+eWX8/DDD9cb33///eu+XmmlldKjR49svPHGef3119O3b995XSZQBZtvvnnd1wMHDsyaa66Z3r1758YbbxRiAGbqT3/6UzbffPP07NmzbsznCgCgKdTU1GSHHXZIURS5+OKL6207/PDD674eOHBgWrVqlQMOOCCnnnpqWrduPa9LBapkp512qvt6pZVWysCBA9O3b988+OCD2XjjjatYGTC/uvzyy7PrrrumTZs29cZ9toAFy8x+X8r8xWMBqZpFFlkkzZs3z4cfflhv/MMPP0z37t2rVBUwrxx88MH561//mgceeCBLLLHELOeuueaaSZJx48YlSbp37162d8zYNqs5HTt2FMyA/0KdO3fOMsssk3HjxqV79+6ZOnVqJk6cWG/ONz9D6BOw4Hnrrbdy7733Zt99953lPJ8rgOT/fr5n9W8S3bt3z0cffVRv+7Rp0zJhwoQm+czh3z7gv8eMYNVbb72VUaNG1Vu1qpw111wz06ZNy5tvvplEr4AF1dJLL51FFlmk3t89fLYAZnjooYfy6quvzvbfMRKfLeD7bGa/L51XvweR2aiccBVV06pVq6y22mq577776sZqa2tz3333Za211qpiZcDcVBRFDj744Nx66625//77GyxdW87zzz+fJOnRo0eSZK211spLL71U7x8jZvzj5gorrFA355v9ZcYc/QX+O33xxRd5/fXX06NHj6y22mpp2bJlvZ/xV199NW+//Xbdz7g+AQueK664It26dcsWW2wxy3k+VwBJ0qdPn3Tv3r3ez/akSZPyxBNP1Ps8MXHixDzzzDN1c+6///7U1tbWBTXXWmutjB49OjU1NXVzRo0alWWXXTZdunSpm6OHwH+vGcGqsWPH5t57783CCy88232ef/75NGvWrO7xX3oFLJj+9a9/5ZNPPqn3dw+fLYAZ/vSnP2W11VbLyiuvPNu5PlvA98/sfl86r34PIrPRCAVU0Q033FC0bt26uPLKK4t//vOfxf7771907ty5+OCDD6pdGjCXHHjggUWnTp2KBx98sHj//ffr/kyePLkoiqIYN25ccdJJJxVPP/10MX78+OL2228vll566WK99darO8a0adOKFVdcsdh0002L559/vrj77ruLRRddtDjmmGPq5rzxxhtFu3btiiOPPLIYM2ZMceGFFxbNmzcv7r777nl+zUDj/frXvy4efPDBYvz48cUjjzxSDBo0qFhkkUWKjz76qCiKovjlL39ZLLnkksX9999fPP3008Vaa61VrLXWWnX76xOwYJk+fXqx5JJLFkcddVS9cZ8rYMH2+eefF88991zx3HPPFUmKc845p3juueeKt956qyiKojjttNOKzp07F7fffnvx4osvFltvvXXRp0+f4quvvqo7xmabbVb84Ac/KJ544oni4YcfLvr371/svPPOddsnTpxYLLbYYsUvfvGL4uWXXy5uuOGGol27dsWll15aN+eRRx4pWrRoUZx11lnFmDFjihNOOKFo2bJl8dJLL827mwHM1Kx6xdSpU4utttqqWGKJJYrnn3++3r9jTJkypSiKonj00UeLc889t3j++eeL119/vbjmmmuKRRddtNh9993rzqFXwPfDrPrF559/XhxxxBHFY489VowfP7649957i1VXXbXo379/8fXXX9cdw2cL+P6b3d9DiqIoPvvss6Jdu3bFxRdf3GB/ny1gwTC735cWxbz7PYjMRmWEq6i6Cy64oFhyySWLVq1aFWussUbx+OOPV7skYC5KUvbPFVdcURRFUbz99tvFeuutV3Tt2rVo3bp10a9fv+LII48sPvvss3rHefPNN4vNN9+8aNu2bbHIIosUv/71r4uampp6cx544IFilVVWKVq1alUsvfTSdecA5n877rhj0aNHj6JVq1bF4osvXuy4447FuHHj6rZ/9dVXxUEHHVR06dKlaNeuXbHtttsW77//fr1j6BOw4Bg5cmSRpHj11VfrjftcAQu2Bx54oOzfPfbYY4+iKIqi9v9r735C4yrXOAD/xjYmoVMTMXG0ChFpbEupNcU/KFIkakAw4ELFLgINNAspLXUpaAQXQQQ3KloRBAulVkRdKFYXZqFuai1NiEKVUuNKpS0RNdVC8t2Vww2Z2l7uTWJ6nwcOzLzn+zjvN4vDzJwf58zOlqeffrrUarXS3Nxc7r333nnnkdOnT5dt27aVarVarrjiijI4OFh+/fXXOWPGxsbK3XffXZqbm8t1111XnnvuuXm9vP322+Wmm24ql19+edm4cWP58MMPF2zdwH/m784VJ0+ePO//GKOjo6WUUr766qtyxx13lLa2ttLS0lI2bNhQRkZG5oQpSnGugEvB350vpqenS19fX+ns7CxNTU2lq6urDA0Nzbso6bsFXPou9DuklFJee+210traWqampubN990C/j9c6HppKYt7HURm48IqpZSyQDfFAgAAAAAAAAAAWLYuW+oGAAAAAAAAAAAA/omEqwAAAAAAAAAAABoQrgIAAAAAAAAAAGhAuAoAAAAAAAAAAKAB4SoAAAAAAAAAAIAGhKsAAAAAAAAAAAAaEK4CAAAAAAAAAABoQLgKAAAAAAAAAACgAeEqAAAAAP7Rtm/fnoceemjJjj8wMJCRkZGLGvvYY4/lhRdeWOCOAAAAAFgslVJKWeomAAAAAPj/VKlU/nb/M888kyeeeCKllLS3ty9OU/9mbGwsvb29mZycTLVaveD4iYmJbN26NSdPnkxbW9sidAgAAADAQhKuAgAAAGDJ/Pjjj/XXBw8ezPDwcI4fP16vVavViwo1LZQdO3Zk5cqV2bt370XPue2227J9+/bs3LlzATsDAAAAYDF4LCAAAAAAS+aaa66pb21tbalUKnNq1Wp13mMB77nnnuzatSt79uzJlVdemVqtltdffz2///57BgcHs3r16qxduzYfffTRnGNNTEzkgQceSLVaTa1Wy8DAQE6dOnXe3mZmZvLOO++kv79/Tv2VV15Jd3d3WlpaUqvV8vDDD8/Z39/fn7feeuu//3AAAAAAWHLCVQAAAAAsO2+++WY6Ojpy+PDh7Nq1K48//ngeeeSR3HXXXTl69Gj6+voyMDCQ6enpJMnU1FR6e3vT09OTI0eO5NChQ/npp5/y6KOPnvcY4+Pj+eWXX3LrrbfWa0eOHMnu3bvz7LPP5vjx4zl06FC2bt06Z97tt9+ew4cP588//1yYxQMAAACwaISrAAAAAFh2Nm/enKeeeird3d158skn09LSko6OjgwNDaW7uzvDw8M5ffp0xsfHkyQvv/xyenp6MjIykvXr16enpydvvPFGRkdH8+233zY8xuTkZFasWJGrr766Xvvhhx+yatWqPPjgg+nq6kpPT0927949Z96aNWty7ty5OY88BAAAAGB5Eq4CAAAAYNm5+eab669XrFiRq666Kps2barXarVakuTnn39OkoyNjWV0dDTVarW+rV+/Pkly4sSJhsc4e/ZsmpubU6lU6rX7778/XV1dufHGGzMwMJD9+/fX7471l9bW1iSZVwcAAABg+RGuAgAAAGDZaWpqmvO+UqnMqf0ViJqdnU2S/Pbbb+nv78+xY8fmbN999928x/r9paOjI9PT0zl37ly9tnr16hw9ejQHDhzItddem+Hh4WzevDlTU1P1MWfOnEmSdHZ2/k/WCgAAAMDSEa4CAAAA4JK3ZcuWfP3117nhhhuydu3aOduqVasazrnllluSJN98882c+sqVK3Pffffl+eefz/j4eL7//vt8+umn9f0TExO5/vrr09HRsWDrAQAAAGBxCFcBAAAAcMnbuXNnzpw5k23btuXLL7/MiRMn8vHHH2dwcDAzMzMN53R2dmbLli35/PPP67UPPvggL774Yo4dO5bJycns27cvs7OzWbduXX3MZ599lr6+vgVfEwAAAAALT7gKAAAAgEvemjVr8sUXX2RmZiZ9fX3ZtGlT9uzZk/b29lx22fn/ItuxY0f2799ff9/e3p533303vb292bBhQ/bu3ZsDBw5k48aNSZI//vgj77//foaGhhZ8TQAAAAAsvEoppSx1EwAAAADwT3T27NmsW7cuBw8ezJ133nnB8a+++mree++9fPLJJ4vQHQAAAAALzZ2rAAAAAOA8Wltbs2/fvpw6deqixjc1NeWll15a4K4AAAAAWCzuXAUAAAAAAAAAANCAO1cBAAAAAAAAAAA0IFwFAAAAAAAAAADQgHAVAAAAAAAAAABAA8JVAAAAAAAAAAAADQhXAQAAAAAAAAAANCBcBQAAAAAAAAAA0IBwFQAAAAAAAAAAQAPCVQAAAAAAAAAAAA0IVwEAAAAAAAAAADTwL9XEiSkAGT4pAAAAAElFTkSuQmCC",
|
||
"text/plain": [
|
||
"<Figure size 3000x500 with 1 Axes>"
|
||
]
|
||
},
|
||
"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": 20,
|
||
"id": "f30a0497-9b2e-4ea9-8ebf-6687de19aaa9",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArYAAAIjCAYAAAD2qFgcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA+EklEQVR4nO3de1yUZf7/8feAMqAGqCgnSTzlOTFdDc1DLUZmlh3VXEGyMtNNY9Okg5S2YplmB8vVTa12+2UesnYzTVErlbQ85DmNRMsExQOgFijcvz/6MtsIKIzA4OXr+XjM4+Fc93Xf92fua8Z5e3vd99gsy7IEAAAAXOY83F0AAAAAUB4ItgAAADACwRYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMQLAFAACAEQi2AFABvvnmG3Xp0kU1a9aUzWbT1q1b3V2Sk/DwcN12220ur2+z2fTcc8+VX0GllJaWJpvNppdfftnlbQwZMkTh4eHlVlN5b68k8+bNk81mU1pamqPtUscRMA3BFriM7dy5U3/5y18UGhoqu92ukJAQDRo0SDt37nR3aVe0s2fP6t5779Xx48f1yiuv6L333lPDhg3dXRYAGK+auwsA4JrFixdr4MCBqlOnjoYOHapGjRopLS1Nb7/9thYuXKgPPvhAd955p7vLvCKlpqbqwIEDmj17th588EF3l4MKNnv2bBUUFLi7DAAi2AKXpdTUVA0ePFiNGzfWl19+qXr16jmWjRo1St26ddPgwYO1bds2NW7c2I2VFnXmzBnVqFHD3WVUqCNHjkiS/P393VsIKkX16tXdXQKA/8NUBOAyNGXKFJ05c0azZs1yCrWSFBAQoH/84x86ffq0XnrpJadlhw4d0tChQxUSEiK73a5GjRpp+PDhysvLc/Q5efKkHn/8cYWHh8tut6tBgwaKiYlRZmampOLn+UnSmjVrZLPZtGbNGkdbz5491aZNG23atEndu3dXjRo19NRTT0mSPv74Y/Xp08dRS5MmTTRx4kTl5+c7bbdwG7t27dKNN96oGjVqKDQ0tMhrk6TffvtNzz33nK655hp5e3srODhYd911l1JTUx19CgoKNH36dLVu3Vre3t4KDAzUsGHDdOLEiVId+1WrVqlbt26qWbOm/P39dccdd2j37t2O5UOGDFGPHj0kSffee69sNpt69ux5wW2ePHlSo0ePVlhYmOx2u5o2baoXX3yxyFnAl19+WV26dFHdunXl4+OjDh06aOHChcVu81//+pc6deqkGjVqqHbt2urevbs+//zzIv3Wrl2rTp06ydvbW40bN9a7775bquNwvgMHDujRRx9V8+bN5ePjo7p16+ree+8t8j4pfP+sXbtWjz32mOrVqyd/f38NGzZMeXl5OnnypGJiYlS7dm3Vrl1bY8eOlWVZxe7zlVdeUcOGDeXj46MePXpox44dRfosWbJEbdq0kbe3t9q0aaOPPvqo2G2V5die7/w5tn+cBzxr1iw1adJEdrtdf/rTn/TNN9+Uaps7d+7UTTfdJB8fHzVo0EAvvPDCBc8Kf/7554qIiJC3t7datWqlxYsXl2o/gGk4Ywtchv7zn/8oPDxc3bp1K3Z59+7dFR4erk8//dTR9ssvv6hTp046efKkHn74YbVo0UKHDh3SwoULdebMGXl5eenUqVPq1q2bdu/erQceeEDXXXedMjMz9cknn+jnn39WQEBAmWs9duyYevfurQEDBugvf/mLAgMDJf0ecGrVqqX4+HjVqlVLq1at0vjx45Wdna0pU6Y4bePEiRO65ZZbdNddd+m+++7TwoUL9eSTT6pt27bq3bu3JCk/P1+33XabkpOTNWDAAI0aNUo5OTlasWKFduzYoSZNmkiShg0bpnnz5ikuLk6PPfaY9u/frzfeeENbtmzRunXrLnj2beXKlerdu7caN26s5557Tr/++qtef/11de3aVZs3b1Z4eLiGDRum0NBQTZo0SY899pj+9Kc/OV5zcc6cOaMePXro0KFDGjZsmK6++mqtX79eCQkJOnz4sKZPn+7o++qrr+r222/XoEGDlJeXpw8++ED33nuv/vvf/6pPnz6Ofs8//7yee+45denSRRMmTJCXl5c2bNigVatW6eabb3b0++GHH3TPPfdo6NChio2N1Zw5czRkyBB16NBBrVu3Lv0g6/eL5davX68BAwaoQYMGSktL01tvvaWePXtq165dRc7S//Wvf1VQUJCef/55ff3115o1a5b8/f21fv16XX311Zo0aZKWLl2qKVOmqE2bNoqJiXFa/91331VOTo5GjBih3377Ta+++qpuuukmbd++3XG8P//8c919991q1aqVkpKSdOzYMcXFxalBgwZF6i/tsS2L999/Xzk5ORo2bJhsNpte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e4VnkO6++2599913xd4SqbBP4d0F/jj3Mz8/X7NmzSp1/YVnsv545iovL09vvvlmqbdxvrvvvluZmZl64403iiwr3M99992n/Px8TZw4sUifc+fOXTCEBQcHKyIiQu+8845Tvx07dujzzz/Xrbfe6lLd9913n1JSUrR8+fIiy06ePKlz585J+v2Y2Ww2pzPjaWlpWrJkidM6/fr1k4eHhyZMmFDkTGlFnin09PQssv3XX3+9xDP5l2rJkiU6dOiQ4/nGjRu1YcMGx10y/jhef5wKsWLFCu3atatI7aU5tpXl1ltv1ddff62NGzc62o4ePVri/zT88ssvTp/Z7Oxsvfvuu4qIiGAaAq44nLEFLkPNmjXTO++8o0GDBqlt27ZFfnksMzNT/+///T9HCJWkSZMm6fPPP1ePHj308MMPq2XLljp8+LAWLFigtWvXyt/fX2PGjNHChQt177336oEHHlCHDh10/PhxffLJJ5o5c6batWun1q1b6/rrr1dCQoKOHz+uOnXq6IMPPnAEsNLo0qWLateurdjYWD322GOy2Wx67733Lil4xcTE6N1331V8fLw2btyobt266fTp01q5cqUeffRR3XHHHerRo4eGDRumpKQkbd26VTfffLOqV6+uffv2acGCBXr11Vd1zz33lLiPKVOmqHfv3oqMjNTQoUMdt/vy8/PTc88951LdY8aM0SeffKLbbrvNcaut06dPa/v27Vq4cKHS0tIUEBCgPn36aNq0abrlllt0//3368iRI5oxY4aaNm3qNC2ladOmevrppzVx4kR169ZNd911l+x2u7755huFhIQoKSnJpTov5rbbbtN7770nPz8/tWrVSikpKVq5cqXq1q1bIftr2rSpbrjhBg0fPly5ubmaPn266tat6zSlIykpSX369NENN9ygBx54QMePH9frr7+u1q1b69SpU45+pT22lWXs2LF67733dMstt2jUqFGO2301bNiw2HquueYaDR06VN98840CAwM1Z84cZWRkuO2MM+BW7rgVA4DysW3bNmvgwIFWcHCwVb16dSsoKMgaOHCgtX379mL7HzhwwIqJibHq1atn2e12q3HjxtaIESOs3NxcR59jx45ZI0eOtEJDQy0vLy+rQYMGVmxsrJWZmenok5qaakVFRVl2u90KDAy0nnrqKWvFihXF3u6rdevWxdaybt066/rrr7d8fHyskJAQa+zYsdby5ctLvY3zb7FkWb/fsunpp5+2GjVq5Dge99xzj5WamurUb9asWVaHDh0sHx8f66qrrrLatm1rjR071vrll19KOtQOK1eutLp27Wr5+PhYvr6+Vt++fa1du3Y59SnL7b4sy7JycnKshIQEq2nTppaXl5cVEBBgdenSxXr55ZetvLw8R7+3337batasmWW3260WLVpYc+fOtRITE63i/iqfM2eO1b59e8tut1u1a9e2evToYa1YscKxvGHDhlafPn2KrNejRw+n22uVROfd7uvEiRNWXFycFRAQYNWqVcuKjo629uzZYzVs2NCKjY119Cu83df5t50rfB1Hjx51ao+NjbVq1qzpeF54K60pU6ZYU6dOtcLCwiy73W5169bN+u6774rUuWjRIqtly5aW3W63WrVqZS1evLjY905Zju35Srrd15QpUy563Eqybds2q0ePHpa3t7cVGhpqTZw40Xr77beLvd1Xnz59rOXLl1vXXnuto/7SvvcA09gsi1nsAAAAuPwxxxYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMcMX9QENBQYF++eUXXXXVVSX+5j0AAADcx7Is5eTkKCQkRB4epT8Pe8UF219++UVhYWHuLgMAAAAX8dNPP6lBgwal7n/FBdurrrpK0u8HytfX183VAAAA4HzZ2dkKCwtz5LbSuuKCbeH0A19fX4ItAABAFVbWaaNcPAYAAAAjEGwBAABgBIItAAAAjECwBQAAgBEItgAAADACwRYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMQLAFAACAEQi2AAAAMALBFgAAAEYg2AIAAMAIbg22X375pfr27auQkBDZbDYtWbLkouusWbNG1113nex2u5o2bap58+ZVeJ0AAACo+twabE+fPq127dppxowZpeq/f/9+9enTRzfeeKO2bt2q0aNH68EHH9Ty5csruFIAAABUddXcufPevXurd+/epe4/c+ZMNWrUSFOnTpUktWzZUmvXrtUrr7yi6OjoiioTAAAAl4HLao5tSkqKoqKinNqio6OVkpJS4jq5ubnKzs52egAAAMA8bj1jW1bp6ekKDAx0agsMDFR2drZ+/fVX+fj4FFknKSlJzz//fGWVWKzJWzLdun8AQNUyrn1Aqfrx/YGqpLTvW3e6rM7YuiIhIUFZWVmOx08//eTukgAAAFABLqsztkFBQcrIyHBqy8jIkK+vb7FnayXJbrfLbrdXRnkAAABwo8vqjG1kZKSSk5Od2lasWKHIyEg3VQQAAICqwq3B9tSpU9q6dau2bt0q6ffbeW3dulUHDx6U9Ps0gpiYGEf/Rx55RD/++KPGjh2rPXv26M0339SHH36oxx9/3B3lAwAAoApxa7D99ttv1b59e7Vv316SFB8fr/bt22v8+PGSpMOHDztCriQ1atRIn376qVasWKF27dpp6tSp+uc//8mtvgAAAODeObY9e/aUZVklLi/uV8V69uypLVu2VGBVAAAAuBxdVnNsAQAAgJIQbAEAAGAEgi0AAACMQLAFAACAEQi2AAAAMALBFgAAAEYg2AIAAMAIBFsAAAAYgWALAAAAIxBsAQAAYASCLQAAAIxAsAUAAIARCLYAAAAwAsEWAAAARiDYAgAAwAgEWwAAABiBYAsAAAAjEGwBAABgBIItAAAAjECwBQAAgBEItgAAADACwRYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMQLAFAACAEQi2AAAAMALBFgAAAEYg2AIAAMAIBFsAAAAYgWALAAAAIxBsAQAAYASCLQAAAIxAsAUAAIARCLYAAAAwAsEWAAAARiDYAgAAwAgEWwAAABiBYAsAAAAjEGwBAABgBIItAAAAjECwBQAAgBEItgAAADACwRYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMQLAFAACAEQi2AAAAMALBFgAAAEYg2AIAAMAIBFsAAAAYgWALAAAAIxBsAQAAYASCLQAAAIxAsAUAAIARCLYAAAAwAsEWAAAARiDYAgAAwAgEWwAAABiBYAsAAAAjEGwBAABgBIItAAAAjECwBQAAgBEItgAAADACwRYAAABGINgCAADACARbAAAAGIFgCwAAACMQbAEAAGAEgi0AAACMQLAFAACAEQi2AAAAMILbg+2MGTMUHh4ub29vde7cWRs3brxg/+nTp6t58+by8fFRWFiYHn/8cf3222+VVC0AAACqKrcG2/nz5ys+Pl6JiYnavHmz2rVrp+joaB05cqTY/u+//77GjRunxMRE7d69W2+//bbmz5+vp556qpIrBwAAQFXj1mA7bdo0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uukmtW/fXt9++62WLVumjIwM3XfffU7beOedd+Tl5aV169Zp5syZLr8GAKhIBFsAqAR33nmnIiIilJiY6PI26tSpo9dee03NmzfXAw88oObNm+vMmTN66qmn1KxZMyUkJMjLy0tr1651Wm/kyJG6++671bJlS7311lvy8/PT22+/LUl644031L59e02aNEktWrRQ+/btNWfOHK1evVp79+51bKNZs2Z66aWX1Lx5czVv3tzl1wAAFYlgCwCV5MUXX9Q777yj3bt3u7R+69at5eHxv7+2AwMD1bZtW8dzT09P1a1bV0eOHHFaLzIy0vHnatWqqWPHjo4avvvuO61evVq1atVyPFq0aCFJSk1NdazXoUMHl2oGgMpUzd0FAMCVonv37oqOjlZCQoKGDBniaPfw8JBlWU59z549W2T96tWrOz232WzFthUUFJS6plOnTqlv37568cUXiywLDg52/LlmzZql3iYAuAvBFgAq0eTJkxUREeH03/n16tVTenq6LMty3AKsPO89+/XXX6t79+6SpHPnzmnTpk0aOXKkJOm6667TokWLFB4ermrV+EoAcHljKgIAVKK2bdtq0KBBeu211xxtPXv21NGjR/XSSy8pNTVVM2bM0GeffVZu+5wxY4Y++ugj7dmzRyNGjNCJEyf0wAMPSJJGjBih48ePa+DAgfrmm2+Umpqq5cuXKy4uTvn5+eVWAwBUBoItAFSyCRMmOE0XaNmypd58803NmDFD7dq108aNG/XEE0+U2/4mT56syZMnq127dlq7dq0++eQTBQQESJJCQkK0bt065efn6+abb1bbtm01evRo+fv7O83nBYDLgc06f2IXAAAAcBnin+MAAAAwAsEWAAAARiDYAgAAwAgEWwAAABiBYAsAAAAjEGwBAABgBIItAAAAjECwBQAAgBEItgAAADACwRYAAABGINgCAADACP8fokuEr7WVXOQAAAAASUVORK5CYII=",
|
||
"text/plain": [
|
||
"<Figure size 800x600 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"from collections import Counter\n",
|
||
"# Count occurrences of each number\n",
|
||
"count = Counter([l.lambda_value for l in db.data.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": 21,
|
||
"id": "c192564b-d3c6-40e1-a614-f7a5ee787c4e",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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hEaNGmH58uWIjIxUagYNGoRr165h1qxZMBqNaN++PXbu3Fnqw4FEREREVD9IQghR04Ooi7KysuDo6IjMzMwKfxAwLS0N7u7uvNepDOyPZeyPOvbIMvbHMvbHMvZHHXtkWXX3pyJ5jd8tIiIiIiIVDM1ERERERCoYmomIiIiIVDA0ExERERGpYGgmIiIiIlLB0ExEREREpIKhmYiIiIhIBUMzEREREZEKhmYiIiIiIhUMzUREREREKhiaiYiIiIhUMDQTEREREalgaCYiIiIiUsHQTERERESkgqGZiIiIiEgFQzMRERERkQqGZiIiIiIiFQzNREREREQqGJqJiIiIiFQwNBMRERERqWBoJiIiIiJSwdBMRERERKSCoZmIiIiISAVDMxERERGRCoZmIiIiIiIVDM1ERERERCoYmomIiIiIVDA0ExERERGpYGgmIiIiIlLB0ExEREREpIKhmYiIiIhIBUMzEREREZEKhmYiIiIiIhUMzUREREREKhiaiYiIiIhUMDQTEREREalgaCYiIiIiUsHQTERERESkgqGZiIiIiEgFQzMRERERkQqGZiIiIiIiFQzNREREREQqGJqJiIiIiFQwNBMRERERqahVoXnBggV4+OGH0aBBA7i7u6N///5ITk42q+natSskSTL7Gj9+vFnNxYsX0adPH9ja2sLd3R3Tpk1DcXGxWU1cXBw6duwIvV6PZs2aISYmptR4Fi9eDD8/PxgMBoSEhODIkSNVfsxEREREVPvVqtC8f/9+REVF4dChQ9izZw+KiorQs2dP5ObmmtWNGTMGV69eVb4WLlyorDOZTOjTpw8KCwsRHx+PVatWISYmBrNmzVJqUlJS0KdPH3Tr1g3Hjx/HlClT8MILL2DXrl1Kzfr16xEdHY3Zs2fj6NGjaNeuHSIjI5GWlnb/G0FEREREtYpVTQ/gTjt37jR7HRMTA3d3dyQmJqJLly7KcltbW3h6epa5jd27d+O3337D3r174eHhgfbt22P+/Pl49dVXMWfOHOh0OixduhT+/v547733AACtW7fGwYMH8cEHHyAyMhIA8P7772PMmDEYOXIkAGDp0qXYvn07VqxYgddee+1+HD4RERER1VK1KjT/VWZmJgDAxcXFbPnq1avx9ddfw9PTE3379sUbb7wBW1tbAEBCQgKCgoLg4eGh1EdGRmLChAlISkpChw4d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ElFdVSX3NOfl5SEvL68qNkVERFQmjUaDqPFjYcg4jxPbViDj6nkUF+Yj4+rt14aM85g4bgznayai+6LSP1kuXryIkSNHwsPDA/b29rC3t4eHhwdGjRqFCxcuVOUYiYiIAADh4eFYOH8WWtrl48IPy3AsZjYu/LAMrewLsHD+LM7TTET3TaVuzzh9+jQeffRRZGRkoEePHmjdurWy/Msvv8T333+PgwcPomXLllU6WCIiovDwcISGhvKJgERUrSoVml977TVoNBocO3YMQUFBZutOnTqF7t2747XXXsPmzZurZJBERER30mg0pf7/Q0R0P1Xq1/L9+/dj8uTJZf7AatOmDSZNmoS4uLh7HRsRERERUa1QqdBcVFQEGxubu663tbVFUVFRpQdFRERERFSbVCo0d+jQAcuXL0dmZmapdVlZWfjiiy/QsWPHex4cEREREVFtUKl7mufOnYtevXqhVatWGDlypPLI7OTkZKxatQo3btzA4sWLq3SgREREREQ1pVKh+YknnsCOHTswbdo0vP3222br2rdvj6+++grdunWrkgESEREREdW0SoVmAIiIiMCxY8dgNBqVeZl9fX3h6elZZYMjIiIiIqoNKh2aS3h6ejIoExEREVGdVu4PAp45cwYGgwHTp0+3WDdt2jTY2NggJSXlngdHRERERFQblDs0f/TRR/D09MRbb71lse6tt96Cp6cnPvroo3seHBERERFRbVDu0Lx7924MHjwY1tbWFut0Oh0GDx6MH3744Z4HR0RERERUG5Q7NF+8eBEtW7YsV23z5s2VDwcSERERET3oyh2a9Xo9cnJyylWbm5sLnU5X6UEREREREdUm5Q7NrVq1wt69e8tVGxsbi9atW1d6UEREREREtUm5Q/OgQYOwbds2bNmyxWLd1q1bsW3bNgwaNOhex0ZEREREVCuUOzRPnDgRHTp0wDPPPIMJEybg559/RlZWFoQQyMrKws8//4wJEybg6aefRrt27TBx4sT7OW4iIiIiompT7oeb6PV67Nq1CyNGjMBnn32GZcuWlaoRQqBXr1748ssvodfrq3SgREREREQ1pUJPBHR1dcW2bdtw5MgRfPfdd/j999+RlZUFBwcHtGrVCn379kVoaOj9GisRERERUY2o1GO0O3fujM6dO1f1WIiIiIiIaqVy39NMRERERFRf1arQvGDBAjz88MNo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",
|
||
"text/plain": [
|
||
"<Figure size 800x600 with 1 Axes>"
|
||
]
|
||
},
|
||
"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": 22,
|
||
"id": "00a12eea-c805-4209-9143-48fa65619873",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArcAAAIjCAYAAAAZajMiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABEDElEQVR4nO3dfXzO9f////sxsxMnO3OyGYuZ5TxENHLy0aJSUStv3sppUZGkE1ahkCHvEpG33oV6V4qik/cbCRFJYs6iYm0RNiezE/Y2bM/vH/12/Drapu3YseOYV7fr5XJcLh3P19njeHiNe689X6/DZowxAgAAACzAy9MFAAAAAK5CuAUAAIBlEG4BAABgGYRbAAAAWAbhFgAAAJZBuAUAAIBlEG4BAABgGYRbAAAAWAbhFgAAAJZBuAXwl7Z9+3Z17NhRVatWlc1m065duzxdkoMGDRrotttu83QZTrPZbHruuefK/TjdunVTt27d7O+//PJL2Ww2LV++vEz7nTlzppo0aaL8/PwyVugZzz33nGw2m0v3+cde79+/X97e3tq3b59LjwM4i3ALuMH333+ve++9V3Xr1pWvr6/Cw8M1YMAAff/9954u7S/t4sWLuueee5Senq6XX35Zb7/9turXr+/pslBBZGVlacaMGRo3bpy8vPjnsjjNmjVTr169NHHiRE+XAkiSvD1dAGB1H330kfr376+QkBANGzZMkZGRSklJ0RtvvKHly5dr6dKluvPOOz1d5l9SUlKSfvnlF73++uu6//77PV2OJf3vf/+Tt/eV+U/Nm2++qUuXLql///6eLqXCe/DBB3XrrbcqKSlJUVFRni4Hf3FX5t84wBUiKSlJ9913nxo2bKhNmzapVq1a9mWPPvqoOnfurPvuu0979uxRw4YNPVhpYTk5OapSpYqnyyhXJ06ckCQFBQV5thAL8/Pz83QJTlu0aJHuuOOOP/0Mly5dUn5+vnx8fNxUWcUTGxur4OBgLVmyRJMnT/Z0OfiL4/csQDl68cUXlZOTo4ULFzoEW0mqWbOm/vnPf+rcuXOaOXOmw7KjR49q2LBhCg8Pl6+vryIjI/XQQw/pwoUL9nUyMjL02GOPqUGDBvL19VW9evU0cOBAnTp1SpK0ePFi2Ww2paSkOOy7YC7il19+aR/r1q2bWrRooR07dqhLly6qUqWKnn76aUnSxx9/rF69etlriYqK0pQpU5SXl+ew34J97N+/X//3f/+nKlWqqG7duoU+mySdP39ezz33nK6++mr5+fmpTp06uuuuu5SUlGRfJz8/X7Nnz1bz5s3l5+en0NBQjRgxQmfOnClR79evX6/OnTuratWqCgoKUu/evXXgwAH78sGDB6tr166SpHvuuUc2m81hHmFRMjIyNGbMGEVERMjX11eNGjXSjBkzCs3HnDVrljp27KgaNWrI399fbdu2LXbu57///W+1b99eVapUUXBwsLp06aLPP/+80HqbN29W+/bt5efnp4YNG+qtt9760x6kpKTIZrNp1qxZmjdvnho2bKgqVaqoR48eOnLkiIwxmjJliurVqyd/f3/17t1b6enpDvsobs5sgwYNNHjw4D+t4Y/bF8wBPXTokAYPHqygoCAFBgZqyJAhysnJ+dP9SdLChQsVFRUlf39/tW/fXl999VWx6+bl5enpp59WWFiYqlatqjvuuENHjhz502MkJydrz549io2NdRj/fU9nz56tqKgo+fr6av/+/ZL+/LyTfjv3GjRoUOiYRc2PtdlsGjVqlFauXKkWLVrI19dXzZs31+rVqwttv3nzZl133XXy8/NTVFSU/vnPfxb7+f7973+rbdu28vf3V0hIiPr161dkX0ra68qVK6tbt276+OOPiz0m4C5cuQXK0aeffqoGDRqoc+fORS7v0qWLGjRooP/85z/2sWPHjql9+/bKyMjQ8OHD1aRJEx09elTLly9XTk6OfHx8dPbsWXXu3FkHDhzQ0KFDde211+rUqVP65JNP9Ouvv6pmzZqlrvX06dO65ZZb1K9fP917770KDQ2V9FtIrlatmsaOHatq1app/fr1mjhxorKysvTiiy867OPMmTO6+eabddddd6lv375avny5xo0bp5YtW+qWW26R9FvYuO2227Ru3Tr169dPjz76qLKzs7V27Vrt27fP/ivNESNGaPHixRoyZIhGjx6t5ORkvfrqq0pMTNSWLVtUuXLlYj/LF198oVtuuUUNGzbUc889p//973+aO3euOnXqpJ07d6pBgwYaMWKE6tatq2nTpmn06NG67rrr7J+5KDk5OeratauOHj2qESNG6KqrrtLXX3+t+Ph4HT9+XLNnz7av+8orr+iOO+7QgAEDdOHCBS1dulT33HOPPvvsM/Xq1cu+3vPPP6/nnntOHTt21OTJ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3XffderYZe1rcduXZb/FnUcl5apzpbzUqFFDly5dUnZ2dpG/fbncfN0/U9qfTVf2Kj8/XzabTatWrSpyv8VdqS6JgrDtzJx/wJUIt0A5uu222/T6669r8+bNuuGGGwot/+qrr5SSkqIRI0ZI+i20BQQE/Ok3/URFRf3pOgVXwjIyMhzGC67IlMSXX36p06dP66OPPlKXLl3s48nJySXexx9FRUVp27ZtunjxYrE3hUVFRemLL75Qp06dSh0iCr6E4ccffyy07IcfflDNmjWdunoWFRWls2fPFrp7/o8+/PBD+fn5ac2aNfL19bWPL1q0qND+8vPztX//frVu3brU9bhLcHBwoXPowoULOn78uNtrKfizPXjwoLp3724fv3jxopKTk9WqVatC2xw8eNDhvTFGhw4d0jXXXHPZYzVp0kTSb+f6n637+9pKct4V1VOpdD+bv1erVi35+/sX+qxF1RMVFSVjjCIjI+3/Q1YUZ3qdnJwsLy+vy+4XcAfm3ALl6Mknn5S/v79GjBih06dPOyxLT0/Xgw8+qCpVqujJJ5+UJHl5ealPnz769NNP9d133xXaX8GVmri4OO3evVsrVqwodp2COXq/nwual5enhQsXlrj+gis7v79CdOHCBc2fP7/E+/ijuLg4nTp1Sq+++mqhZQXH6du3r/Ly8jRlypRC61y6dKnIYFCgTp06at26tZYsWeKw3r59+/T555/r1ltvdaruvn37auvWrVqzZk2hZRkZGbp06ZKk33pms9kcrsKlpKRo5cqVDtv06dNHXl5emjx5cqEr4BXl6qX023n0+3NI+u3xUGW9cuuMdu3aqVatWlqwYIHDY/EWL15c7Dnx1ltvOUwNWr58uY4fP25/ekdxYmJiJKnIn8OilOa8i4qKUmZmpsNvdY4fP17kz3NJVKpUST179tTKlSt1+PBh+/iBAwcKna933XWXKlWqpOeff77QeWaMsf895Uyvd+zYoebNmxc7JxdwF67cAuUoOjpaS5Ys0YABA9SyZctC31B26tQpvffeew43i0ybNk2ff/65unbtquHDh6tp06Y6fvy4li1bps2bNysoKEhPPvmkli9frnvuuUdDhw5V27ZtlZ6erk8++UQLFixQq1at1Lx5c11//fWKj49Xenq6QkJCtHTpUnsIK4mOHTsqODhYgwYN0ujRo2Wz2fT222+XKXwN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hx/UtGlTbd26Vddff32J9puVlaXAwEBlZmYqICCgPD+C3fTEU245DgAAQHkY36amW49X0rxWoa/c/lFmZqYkKSQkRJK0Y8cOXbx4UbGxsfZ1mjRpoquuukpbt24tdj+5ubnKyspyeAEAAODKd8WE2/z8fI0ZM0adOnVSixYtJEmpqany8fFRUFCQw7qhoaFKTU0tdl8JCQkKDAy0vyIiIsqzdAAAALjJFRNuR44cqX379mnp0qVl3ld8fLwyMzPtryNHjrigQgAAAHiat6cLKIlRo0bps88+06ZNm1SvXj37eFhYmC5cuKCMjAyHq7dpaWkKCwsrdn++vr7y9fUtz5IBAADgARX6yq0xRqNGjdKKFSu0fv16RUZGOixv27atKleurHXr1tnHfvzxRx0+fFgxMTHuLhcAAAAeVqGv3I4cOVLvvvuuPv74Y1WvXt0+jzYwMFD+/v4KDAzUsGHDNHbsWIWEhCggIECPPPKIYmJiSvykBAAAAFhHhQ63r732miSpW7duDuOLFi3S4MGDJUkvv/yyvLy8FBcXp9zcXPXs2VPz5893c6UAAACoCCp0uC3JI3j9/Pw0b948zZs3zw0VAQAAoCKr0HNuAQAAgNIg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIAAMAyCLcAAACwDMItAAAALINwCwAAAMsg3AIA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yb5d27ZtnaoZAMqbt6cLAIC/qi5duqhnz56Kj4/X4MGD7eNeXl4yxjise/HixULbV65c2eG9zWYrciw/P7/ENZ09e1a33367ZsyYUWhZnTp17P9dtWrVEu8TANyJcAsAHjR9+nS1bt3a4Vf7tWrVUmpqqowx9seDufLZtN988426dOkiSbp06ZJ27NihUaNGSZKuvfZaffjhh2rQoIG8vfknAsCVh2kJAOBBLVu21IABAzRnzhz7WLdu3XTy5EnNnDlTSUlJmjdvnlatWuWyY86bN08rVqzQDz/8oJEjR+rMmTMaOnSoJGnkyJFKT09X//79tX37diUlJWnNmjUaMmSI8vLyXFYDAJQXwi0AeNjkyZMdpg40bdpU8+fP17x589SqVSt9++23euKJJ1x2vOnTp2v69Olq1aqVNm/erE8++UQ1a9aUJIWHh2vLli3Ky8tTjx491LJlS40ZM0ZBQUEO83sBoKKymT9O7AIAAACuUPxvOAAAACyDcAsAAADLINwCAADAMgi3AAAAsAzCLQAAACyDcAsAAADLINwCAADAMgi3AAAAsAzCLQAAACyDcAsAAADLINwCAADAMv4fVvQCaHUDfkEAAAAASUVORK5CYII=",
|
||
"text/plain": [
|
||
"<Figure size 800x600 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"from collections import Counter\n",
|
||
"# Count occurrences of each number\n",
|
||
"count = Counter(np.array([l.mu_value if l.mu_value is not None else 0.0 for l in db.data.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": 23,
|
||
"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": 24,
|
||
"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": 25,
|
||
"id": "5b6dac2e-8596-4e7c-97d8-aaf9632e4154",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"count 0.0\n",
|
||
"mean NaN\n",
|
||
"std NaN\n",
|
||
"min NaN\n",
|
||
"25% NaN\n",
|
||
"50% NaN\n",
|
||
"75% NaN\n",
|
||
"max NaN\n",
|
||
"Name: lambda, dtype: float64"
|
||
]
|
||
},
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"merged[merged['hits']==0]['lambda'].describe()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"id": "29393374-e379-42c8-8333-abfecc18e828",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"count 100.000000\n",
|
||
"mean 0.162692\n",
|
||
"std 0.247757\n",
|
||
"min 0.050200\n",
|
||
"25% 0.063050\n",
|
||
"50% 0.086800\n",
|
||
"75% 0.148775\n",
|
||
"max 2.000000\n",
|
||
"Name: lambda, dtype: float64"
|
||
]
|
||
},
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"merged[merged['hits']>0]['lambda'].describe()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"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": 28,
|
||
"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
|
||
}
|