{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "ab5cd7d1-1a57-46fc-8282-dae0a6cc2944", "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import random" ] }, { "cell_type": "code", "execution_count": 2, "id": "3d1ad0b9-f6a8-4e98-84aa-6e02e4279954", "metadata": {}, "outputs": [], "source": [ "DATABASE_OBJECT_COUNT = 100\n", "CACHE_SIZE = DATABASE_OBJECT_COUNT/2\n", "ZIPF_CONSTANT = 2\n", "\n", "CACHE_MISS_COST = 1\n", "CACHE_REFRESH_COST = 1\n", "\n", "SEED = 42\n", "np.random.seed(SEED)\n", "random.seed(SEED)\n", "\n", "LAMBDA_VALUES = np.array([np.random.zipf(ZIPF_CONSTANT) for i in np.arange(1, DATABASE_OBJECT_COUNT + 1,1)])" ] }, { "cell_type": "code", "execution_count": 3, "id": "9cc83cf6-5c78-4f0d-b7cb-08cdb80c362e", "metadata": {}, "outputs": [], "source": [ "# LAMBDA_VALUES = np.array([0.03, 0.04,0.05,0.06,0.07,1,1.1,1.2,1.3,1.4,1.5])\n", "# DATABASE_OBJECT_COUNT = len(LAMBDA_VALUES)\n", "# CACHE_SIZE = 4.4\n", "# CACHE_MISS_COST = 7\n", "# CACHE_REFRESH_COST = 1" ] }, { "cell_type": "code", "execution_count": 4, "id": "3dc07233-0b56-4fee-a93b-212836c18b42", "metadata": {}, "outputs": [], "source": [ "db_object_count = DATABASE_OBJECT_COUNT\n", "cache_sz = CACHE_SIZE\n", "\n", "lambda_vals = LAMBDA_VALUES\n", "c_f = CACHE_MISS_COST\n", "c_delta = CACHE_REFRESH_COST" ] }, { "cell_type": "code", "execution_count": 5, "id": "5a27d416-8f98-4814-af9e-6c6bef95f4ef", "metadata": {}, "outputs": [], "source": [ "def eta_star(db_object_count, c_f, cache_sz, c_delta, lambda_vals):\n", " num = (db_object_count * c_f - cache_sz * c_delta)\n", " denom = np.sum(1.0/lambda_vals)\n", " return max(0, num/denom)" ] }, { "cell_type": "code", "execution_count": 6, "id": "6276a9ce-f839-4fe6-90f2-2195cf065fc8", "metadata": {}, "outputs": [], "source": [ "def h_i_star(c_f, eta, lambda_vals, c_delta):\n", " optimized_hitrate = (c_f - (eta/lambda_vals)) / c_delta\n", " return optimized_hitrate" ] }, { "cell_type": "code", "execution_count": 7, "id": "dcd31a8c-6864-4b9a-8bb3-998f0c32baf6", "metadata": {}, "outputs": [], "source": [ "def get_index_of_furthest_hitrate_from_boundary(hitrates):\n", " local_hitrates = hitrates[(hitrates < 0) | (hitrates > 1)]\n", " smallest_delta = np.abs(np.min(local_hitrates))\n", " biggest_delta = np.max(local_hitrates) - 1\n", " if smallest_delta > biggest_delta:\n", " index = np.where(hitrates == np.min(local_hitrates))[0][0]\n", " return index\n", " else:\n", " index = np.where(hitrates == np.max(local_hitrates))[0][0]\n", " return index" ] }, { "cell_type": "code", "execution_count": 14, "id": "ccd4b95d-1cdd-4c99-a22e-4b31338993cf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.30256805, 0.76752268, 0.30256805, 0.30256805, 0.65128403,\n", " 0.30256805, 0.86051361, 0.30256805, 0.30256805, 0.30256805,\n", " 0.65128403, 0.30256805, 0.30256805, 0.30256805, 0.65128403,\n", " 0.65128403, 0.30256805, 0.30256805, 0.76752268, 0.30256805,\n", " 0.30256805, 0.30256805, 0.30256805, 0.65128403, 0.30256805,\n", " 0.30256805, 0.30256805, 0.86051361, 0.30256805, 0.30256805,\n", " 0.30256805, 0.82564201, 0.30256805, 0.82564201, 0.30256805,\n", " 0.30256805, 0.30256805, 0.76752268, 0.91282101, 0.30256805,\n", " 0.82564201, 0.82564201, 0.65128403, 0.30256805, 0.30256805,\n", " 0.30256805, 0.93025681, 0.30256805, 0.30256805, 0.30256805,\n", " 0.86051361, 0.92250756, 0.30256805, 0.30256805, 0.30256805,\n", " 0.30256805, 0.30256805, 0.95897459, 0.65128403, 0.30256805,\n", " 0.97317569, 0.30256805, 0.30256805, 0.65128403, 0.30256805,\n", " 0.93025681, 0.30256805, 0.98989229, 0.30256805, 0.30256805,\n", " 0.65128403, 0.30256805, 0.30256805, 0.30256805, 0.76752268,\n", " 0.65128403, 0.65128403, 0.76752268, 0.95350454, 0.30256805,\n", " 0.30256805, 0.86051361, 0.65128403, 0.30256805, 0.30256805,\n", " 0.65128403, 0.30256805, 0.65128403, 0.30256805, 0.30256805,\n", " 0.65128403, 0.65128403, 0.76752268, 0.30256805, 0.65128403,\n", " 0.30256805, 0.30256805, 0.98115049, 0.82564201, 0.65128403])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eta = eta_star(db_object_count, c_f, cache_sz, c_delta, lambda_vals)\n", "optimized_hitrates = (c_f - eta / lambda_vals) / c_delta\n", "optimized_hitrates" ] }, { "cell_type": "code", "execution_count": 8, "id": "0e21c26f-058a-4e56-a5ad-1c47bf28656c", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All values optimized.\n" ] } ], "source": [ "\"\"\"\n", "Perform theoretical optimization to compute optimal hit probabilities.\n", "\n", "Parameters:\n", "- lambda_vals (numpy array): Request rates for each item.\n", "- B (float): Total cache size.\n", "- c_f (float): Fetching linear cost (cache miss cost).\n", "- c_delta (float): Age linear cost.\n", "\n", "Returns:\n", "- h_opt (numpy array): Optimal hit probabilities for each item.\n", "\"\"\"\n", "optimized_hitrates = np.zeros(DATABASE_OBJECT_COUNT)\n", "current_db_object_count = DATABASE_OBJECT_COUNT\n", "current_cache_size = CACHE_SIZE\n", "\n", "differenc_set = np.arange(DATABASE_OBJECT_COUNT)\n", "fix_i = []\n", "\n", "while True:\n", " if current_db_object_count == 0:\n", " print(\"No objects left to optimize.\")\n", " if current_cache_size > 0:\n", " # Redistribute unused cache size among items with zero hit probability\n", " differenc_set = np.where(optimized_hitrates == 0)[0]\n", " fix_i = np.setdiff1d(np.arange(DATABASE_OBJECT_COUNT), differenc_set)\n", " current_db_object_count = len(differenc_set)\n", " continue\n", " else:\n", " optimized_hitrates[differenc_set] = 0\n", " break\n", " # Compute Lagrangian multiplier and optimal hit probabilities\n", " eta = eta_star(current_db_object_count, c_f, current_cache_size, c_delta, lambda_vals[differenc_set])\n", " optimized_hitrates[differenc_set] = (c_f - eta / lambda_vals[differenc_set]) / c_delta\n", "\n", " if eta < 0:\n", " print(\"eta was negative.\")\n", " current_cache_size = current_db_object_count * c_f / c_delta # Adjust cache size for next iteration\n", " continue\n", " \n", " if len((optimized_hitrates[differenc_set])[((optimized_hitrates[differenc_set]) < 0) | ((optimized_hitrates[differenc_set])> 1)]) == 0:\n", " print(\"All values optimized.\")\n", " break\n", " \n", " max_outbound_index = get_index_of_furthest_hitrate_from_boundary(optimized_hitrates)\n", " optimized_hitrates[max_outbound_index] = (1 if optimized_hitrates[max_outbound_index] > 1 else 0)\n", "\n", " current_cache_size =- optimized_hitrates[max_outbound_index]\n", " fix_i.append(max_outbound_index)\n", " differenc_set = np.setdiff1d(np.arange(DATABASE_OBJECT_COUNT), fix_i)\n", " current_db_object_count -= 1" ] }, { "cell_type": "code", "execution_count": null, "id": "11682b36-e705-4bd9-9d75-79012791d1ee", "metadata": {}, "outputs": [], "source": [] } ], "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 }