From 8cbeb52d9eb838c7f518da21fb36adbad9a2962f Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Thu, 18 Aug 2022 18:02:00 -0600 Subject: [PATCH] reworked to support state --- analysis/ec-placement.ipynb | 171 ++++++++++++++++++++++++++---------- 1 file changed, 125 insertions(+), 46 deletions(-) diff --git a/analysis/ec-placement.ipynb b/analysis/ec-placement.ipynb index 0630cf9..6a26c3d 100644 --- a/analysis/ec-placement.ipynb +++ b/analysis/ec-placement.ipynb @@ -2,13 +2,13 @@ "cells": [ { "cell_type": "code", - "execution_count": 97, + "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a58d0687e0b9452e93be2ef56ebc68ed", + "model_id": "dd5a5f6038bc44d1ac4b044894b50f30", "version_major": 2, "version_minor": 0 }, @@ -22,7 +22,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b3d1ec6e56d4467bb2ec8f202567ee58", + "model_id": "1dbdb23c07e4466e82d422c423af3bad", "version_major": 2, "version_minor": 0 }, @@ -42,13 +42,19 @@ "import tabulate as tb\n", "from functools import reduce\n", "from operator import concat\n", - "from copy import deepcopy\n", - "import math\n", "from collections import OrderedDict\n", + "import math\n", + "\n", + "DEFAULT_BLOCKS = 12\n", + "DEFAULT_NODES = 3\n", + "DEFAULT_K = 2\n", + "DEFAULT_M = 1\n", + "DEFAULT_LAYOUT = \"Inline\"\n", + "DEFAULT_DIRECTION = \"Horizontal\"\n", "\n", "\n", "def roundBlocks(factor, ob):\n", - " return ob + (factor - (ob % factor))\n", + " return ob + (factor - (ob % factor)) if (ob % factor) > 0 else 0\n", "\n", "\n", "def makeEcGroups(\n", @@ -113,59 +119,132 @@ " return readSequence\n", "\n", "\n", - "def buildModel(K, M, blocks, Dir, Layout, Nodes):\n", - " return\n", + "class ECPlacement:\n", + " blocks = []\n", + " nodesMap = OrderedDict()\n", + " blockSeq = []\n", + " ecGroups = []\n", + " rb = 0\n", + "\n", + " def __init__(\n", + " self,\n", + " k=DEFAULT_K, m=DEFAULT_M,\n", + " layout=DEFAULT_LAYOUT,\n", + " direction=DEFAULT_LAYOUT,\n", + " nodes=DEFAULT_NODES,\n", + " bc=DEFAULT_BLOCKS):\n", + " self.blocks = list(range(1, bc + 1))\n", + " self.k = k\n", + " self.m = m\n", + " self.layout = layout\n", + " self.direction = direction\n", + " self.nodes = nodes\n", + " self.bc = bc\n", + "\n", + " def reset(self):\n", + " self.k = DEFAULT_K\n", + " self.m = DEFAULT_M\n", + " self.layout = DEFAULT_LAYOUT\n", + " self.direction = DEFAULT_DIRECTION\n", + " self.nodes = DEFAULT_NODES\n", + " self.bc = DEFAULT_BLOCKS\n", + " self.rb = 0\n", + "\n", + " self.blocks = list(range(1, self.bc + 1))\n", + " self.nodesMap = OrderedDict()\n", + " self.blockSeq = []\n", + " self.ecGroups = []\n", + "\n", + " def update(self, k, m, bc, dir, layout, nodes):\n", + " if self.k != k or self.m != m or self.bc != bc:\n", + " # Calculate geometry\n", + " self.rb = roundBlocks(k, bc)\n", + " if (self.rb + bc) > len(self.blocks):\n", + " # Generate source blocks\n", + " self.blocks += list(\n", + " range(len(self.blocks) + 1, self.rb + 1))\n", + "\n", + " self.bc = bc\n", + " self.k = k\n", + " self.m = m\n", + " self.direction = dir\n", + " self.layout = layout\n", + " self.nodes = nodes\n", + "\n", + " if len(self.blocks) > 0:\n", + " self.ecGroups = makeEcGroups(\n", + " self.blocks, self.k, self.m, self.direction) # Calculate EC groups\n", + "\n", + " self.blockSeq = makeReadSeq(\n", + " self.k, self.m, self.ecGroups, self.direction, self.layout)\n", + "\n", + " self.nodesMap = mapNodes(\n", + " self.blockSeq, self.nodes).items()\n", + "\n", + " return self.blockSeq\n", + "\n", + " def render(self):\n", + " width = getZeros(len(self.blockSeq) or BC)\n", + " formatBlock = getBlockFormat(width)\n", + "\n", + " print(\"\\n\")\n", + " print(\"Rounded Blocks:\", self.rb)\n", + " print(\"Encoding Groups:\", len(self.ecGroups))\n", + " print(\"K + M = \", self.k + self.m)\n", + " print(\"Source Blocks:\", \", \".join(map(formatBlock, self.blocks)))\n", + " print(\"Read Layout:\", \", \".join(map(formatBlock, self.blockSeq)))\n", + "\n", + " groupsTable = tb.tabulate(\n", + " [[\", \".join(map(formatBlock, g[:self.k])), \", \".join(map(formatBlock, g[-self.m:]))]\n", + " for g in self.ecGroups], [\"Source\", \"Parity\"])\n", + " print(\"\\n\", groupsTable)\n", + "\n", + " nodesTable = tb.tabulate(\n", + " list(map(list, self.nodesMap)), [\"Nodes\", \"Blocks\"])\n", + " print(\"\\n\", nodesTable)\n", "\n", "\n", - "def main(K, M, BC, Dir, Layout, Nodes):\n", - " # K - The number of source blocks to encode\n", - " # M - The number of parity blocks produced\n", - " # BC - Initial block count\n", + "ecPlacement = ECPlacement()\n", + "\n", + "def main(k, m, bc, dir, layout, nodes):\n", + " # K - The number of source blocks to encode # BC - Initial block count\n", " # Dir - Coding direction\n", " # Layout - Block layout\n", " # Nodes - Nodes count\n", " ##\n", "\n", - " rb = roundBlocks(Nodes, BC) # Calculate geometry\n", - " blocks = list(range(1, rb + 1)) # Generate source blocks\n", - " ecGroups = makeEcGroups(blocks, K, M, Dir) # Calculate EC groups\n", - " readSequence = makeReadSeq(K, M, ecGroups, Dir, Layout)\n", - "\n", - " width = getZeros(len(readSequence) or BC)\n", - " formatBlock = getBlockFormat(width)\n", - "\n", - " print(\"\\n\")\n", - " print(K, M, BC, Dir, Layout, Nodes)\n", - "\n", - " print(\"Rounded Blocks:\", rb)\n", - " print(\"Encoding Groups:\", len(ecGroups))\n", - " print(\"K + M = \", K + M)\n", - " print(\"Source Blocks:\", \", \".join(map(formatBlock, blocks)))\n", - " print(\"Read Layout:\", \", \".join(map(formatBlock, readSequence)))\n", - "\n", - " groupsTable = tb.tabulate(\n", - " [[\", \".join(map(formatBlock, g[:K])), \", \".join(map(formatBlock, g[-M:]))]\n", - " for g in ecGroups], [\"Source\", \"Parity\"])\n", - " print(\"\\n\", groupsTable)\n", - "\n", - " nodesTable = tb.tabulate(\n", - " list(map(list, mapNodes(readSequence, Nodes).items())), [\"Nodes\", \"Blocks\"])\n", - " print(\"\\n\", nodesTable)\n", + " ecPlacement.update(k, m, bc, dir, layout, nodes)\n", + " ecPlacement.render()\n", "\n", "\n", "MaxBlocks = 256\n", "K = widgets.IntSlider(description=\"K\", min=2, max=MaxBlocks)\n", "M = widgets.IntSlider(description=\"M\", min=1, max=MaxBlocks)\n", "BC = widgets.IntSlider(description=\"Origina blocks count\",\n", - " min=1, max=10000, value=10)\n", + " min=1, max=10000, value=12)\n", "D = widgets.Dropdown(options=['Horizontal', 'Vertical'],\n", " description=\"EC Coding Direction\")\n", "Layout = widgets.Dropdown(\n", - " options=['Inline', 'Append'], description=\"Blocks Manifest Layout\")\n", + " options=['Inline', 'Append'],\n", + " description=\"Blocks Manifest Layout\")\n", + "\n", + "Clear = widgets.Button(description='Clear')\n", "Nodes = widgets.IntSlider(\n", " description=\"Nodes\", min=K.value + M.value, max=MaxBlocks)\n", "\n", - "ui = widgets.VBox([K, M, BC, D, Layout, Nodes])\n", + "ui = widgets.VBox([K, M, BC, D, Layout, Nodes, Clear])\n", + "\n", + "\n", + "def clearModelClick(button):\n", + " ecPlacement.reset()\n", + " K.value = K.min\n", + " M.value = M.min\n", + " BC.value = 12\n", + " D.value = \"Horizontal\"\n", + " Layout.value = \"Inline\"\n", + " Nodes.value = 3\n", + "\n", + "Clear.on_click(clearModelClick)\n", "\n", "\n", "def updateKRange(*args):\n", @@ -189,12 +268,12 @@ "out = widgets.interactive_output(\n", " main,\n", " {\n", - " 'K': K,\n", - " 'M': M,\n", - " 'BC': BC,\n", - " 'Dir': D,\n", - " 'Layout': Layout,\n", - " 'Nodes': Nodes})\n", + " 'k': K,\n", + " 'm': M,\n", + " 'bc': BC,\n", + " 'dir': D,\n", + " 'layout': Layout,\n", + " 'nodes': Nodes})\n", "\n", "display(ui, out)\n" ]