From 162447a1c861715843680a5e54c299ff417a58c7 Mon Sep 17 00:00:00 2001
From: KyleKlenk <kyle.c.klenk@gmail.com>
Date: Wed, 18 May 2022 15:34:11 -0600
Subject: [PATCH] added the ability to remove a failed actor

---
 build/makefile                       |  16 +--
 build/source/actors/OutputManager.h  |  41 +++++++-
 build/source/testing/testing_main.cc | 145 +++++++++++++++++++++++++++
 3 files changed, 191 insertions(+), 11 deletions(-)

diff --git a/build/makefile b/build/makefile
index ab14e95..46d5f5c 100644
--- a/build/makefile
+++ b/build/makefile
@@ -16,16 +16,16 @@
 
 
 # Production runs
-FLAGS_NOAH = -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_COMM = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_SUMMA = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
-FLAGS_ACTORS = -O3
+# FLAGS_NOAH = -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_COMM = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_SUMMA = -O3 -ffree-line-length-none -fmax-errors=0 -fPIC
+# FLAGS_ACTORS = -O3
 
 # # Debug runs
-# FLAGS_NOAH = -pg -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC
-# FLAGS_COMM = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
-# FLAGS_SUMMA = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
-# FLAGS_ACTORS = -pg -g -O0 -Wall
+FLAGS_NOAH = -pg -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC
+FLAGS_COMM = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
+FLAGS_SUMMA = -pg -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
+FLAGS_ACTORS = -pg -g -O0 -Wall
 
 
 #========================================================================
diff --git a/build/source/actors/OutputManager.h b/build/source/actors/OutputManager.h
index 74aa7c5..ebb2119 100644
--- a/build/source/actors/OutputManager.h
+++ b/build/source/actors/OutputManager.h
@@ -3,6 +3,7 @@
 
 #include "caf/all.hpp"
 #include <vector>
+#include <algorithm>
 /**
  * @brief Basic Container class to hold actor references. This has a size component for checking when it is full.
  * 
@@ -36,6 +37,10 @@ class ActorRefList {
         int getCurrentSize() {
             return this->currentSize;
         }
+
+        int getMaxSize() {
+            return this->maxSize;
+        }
         
         bool isFull() {
             return list.size() == this->maxSize;
@@ -82,9 +87,25 @@ class ActorRefList {
             return list.empty();
         }
 
-        
-
+        /**
+        * Remove the failed HRU from the list
+        *
+        */
+        void removeFailed(caf::actor actorRef) {
+            bool found = false;
+            for(std::vector<std::tuple<caf::actor, int>>::iterator it = this->list.begin(); it != this->list.end(); it++) {
+                if (std::get<0>(*it) == actorRef) {
+                    found = true;
+                    this->list.erase(it);
+                    this->currentSize--; this->maxSize--;
+                    break;
+                }
+            }
 
+            if (!found) {
+                throw "Element To Remove Not Found";
+            }
+        }
 };
 
 
@@ -139,6 +160,10 @@ class OutputManager {
             return listIndex;
         }
 
+        /**
+        * Remove tuple from list[index]
+        *
+        */
         std::tuple<caf::actor,int> popActor(int index) {
             if (index > this->numVectors - 1 || index < 0) {
                 throw "List Index Out Of Range";
@@ -147,9 +172,19 @@ class OutputManager {
             }
 
             return this->list[index]->popActor();
+        }
+
+
+        void removeFailed(caf::actor actorRef, int index) {
+            // Find the list this actor is on
+            int listIndex = (index - 1) / this->avgSizeOfActorList;
+            if (listIndex > this->numVectors - 1) {
+                listIndex =  this->numVectors - 1;
+            }
+            
+            this->list[listIndex]->removeFailed(actorRef);
 
         }
-        
 
         bool isFull(int listIndex) {
             if (listIndex > this->numVectors - 1) {
diff --git a/build/source/testing/testing_main.cc b/build/source/testing/testing_main.cc
index 9c034a5..d693fab 100644
--- a/build/source/testing/testing_main.cc
+++ b/build/source/testing/testing_main.cc
@@ -151,6 +151,124 @@ void testActorRefList(caf::actor_system& sys) {
     }
 
     IS_TRUE(om->isEmpty())
+
+
+    // Test Remove Failed
+    aout(self) << "Testing Remove Failed" << std::endl;
+    IS_TRUE(om->getCurrentSize() == 0);
+    om->addActor(a1, 1, 9999);
+    IS_TRUE(om->getCurrentSize() == 1);
+    om->addActor(a2, 2, 3);
+    IS_TRUE(om->getCurrentSize() == 2);
+    om->addActor(a3, 3, 7);
+    IS_TRUE(om->getCurrentSize() == 3);
+    om->addActor(a4, 4, 9999);
+    IS_TRUE(om->getCurrentSize() == 4);
+    om->addActor(a5, 5, 8);
+    IS_TRUE(om->getCurrentSize() == 5);
+
+    // Test the removal of a failed actor from middle
+    try {
+        om->removeFailed(a3);
+    } catch (const char* msg) {
+        std::cerr << msg << std::endl;
+    }
+    IS_TRUE(om->getCurrentSize() == 4);
+    IS_TRUE(om->getMaxSize() == 4);
+
+    // Ensure the proper actor was removed
+    a7 = om->popActor();
+    IS_TRUE(get<0>(a7) == a5 && get<1>(a7) == 8);
+    IS_TRUE(om->getCurrentSize() == 3);
+    a8 = om->popActor();
+    IS_TRUE(get<0>(a8) == a4 && get<1>(a8) == 9999);
+    IS_TRUE(om->getCurrentSize() == 2);
+    a10 = om->popActor();
+    IS_TRUE(get<0>(a10) == a2 && get<1>(a10) == 3);
+    IS_TRUE(om->getCurrentSize() == 1);
+    a11 = om->popActor();
+    IS_TRUE(get<0>(a11) == a1 && get<1>(a11) == 9999);
+
+    IS_TRUE(om->isEmpty())
+
+    delete om;
+    om = new ActorRefList(5);
+
+    // Remove Failed Actor from beginning of list
+    IS_TRUE(om->getCurrentSize() == 0);
+    om->addActor(a1, 1, 9999);
+    IS_TRUE(om->getCurrentSize() == 1);
+    om->addActor(a2, 2, 3);
+    IS_TRUE(om->getCurrentSize() == 2);
+    om->addActor(a3, 3, 7);
+    IS_TRUE(om->getCurrentSize() == 3);
+    om->addActor(a4, 4, 9999);
+    IS_TRUE(om->getCurrentSize() == 4);
+    om->addActor(a5, 5, 8);
+    IS_TRUE(om->getCurrentSize() == 5);
+
+    try {
+        om->removeFailed(a1);
+    } catch (const char* msg) {
+        std::cerr << msg << std::endl;
+    }
+    IS_TRUE(om->getCurrentSize() == 4);
+    IS_TRUE(om->getMaxSize() == 4);
+
+    a8 = om->popActor();
+    IS_TRUE(get<0>(a8) == a5 && get<1>(a8) == 8);
+    IS_TRUE(om->getCurrentSize() == 3);
+    a9 = om->popActor();
+    IS_TRUE(get<0>(a9) == a4 && get<1>(a9) == 9999);
+    IS_TRUE(om->getCurrentSize() == 2);
+    a10 = om->popActor();
+    IS_TRUE(get<0>(a10) == a3 && get<1>(a10) == 7);
+    IS_TRUE(om->getCurrentSize() == 1);
+    a11 = om->popActor();
+    IS_TRUE(get<0>(a11) == a2 && get<1>(a11) == 3);
+
+    IS_TRUE(om->isEmpty())
+    delete om;
+    om = new ActorRefList(5);
+
+    // Remove Failed Actor from end of list
+    IS_TRUE(om->getCurrentSize() == 0);
+    om->addActor(a1, 1, 9999);
+    IS_TRUE(om->getCurrentSize() == 1);
+    om->addActor(a2, 2, 3);
+    IS_TRUE(om->getCurrentSize() == 2);
+    om->addActor(a3, 3, 7);
+    IS_TRUE(om->getCurrentSize() == 3);
+    om->addActor(a4, 4, 9999);
+    IS_TRUE(om->getCurrentSize() == 4);
+    om->addActor(a5, 5, 8);
+    IS_TRUE(om->getCurrentSize() == 5);
+
+    try {
+        om->removeFailed(a5);
+    } catch (const char* msg) {
+        std::cerr << msg << std::endl;
+    }
+    IS_TRUE(om->getCurrentSize() == 4);
+    IS_TRUE(om->getMaxSize() == 4);
+
+    a7 = om->popActor();
+    IS_TRUE(get<0>(a7) == a4 && get<1>(a7) == 9999);
+    IS_TRUE(om->getCurrentSize() == 3);
+    a8 = om->popActor();
+    IS_TRUE(get<0>(a8) == a3 && get<1>(a8) == 7);
+    IS_TRUE(om->getCurrentSize() == 2);
+    a9 = om->popActor();
+    IS_TRUE(get<0>(a9) == a2 && get<1>(a9) == 3);
+    IS_TRUE(om->getCurrentSize() == 1);
+    a10 = om->popActor();
+    IS_TRUE(get<0>(a10) == a1 && get<1>(a10) == 9999);
+
+    IS_TRUE(om->isEmpty())
+
+    delete om;
+
+
 }
 
 void testOutputManager(caf::actor_system& sys) {
@@ -366,6 +484,33 @@ void testOutputManager(caf::actor_system& sys) {
     IS_TRUE(OM2->isFull(2));
 
 
+    // Testing Remove Failed
+    aout(self) << "testing Remove Failed from Output Structure \n";
+    OM2->removeFailed(a1, 1);
+    IS_TRUE(OM2->getSize(0) == 2);
+    IS_TRUE(OM2->getSize(1) == 3);
+    IS_TRUE(OM2->getSize(2) == 4);
+    IS_TRUE(OM2->isFull(0));
+    OM2->removeFailed(a5, 5);
+    IS_TRUE(OM2->getSize(0) == 2);
+    IS_TRUE(OM2->getSize(1) == 2);
+    IS_TRUE(OM2->getSize(2) == 4);
+    IS_TRUE(OM2->isFull(1));
+
+    // Pop Actors
+
+    a11 = OM2->popActor(0);
+    IS_TRUE(get<0>(a11) == a3);
+    a12 = OM2->popActor(0);
+    IS_TRUE(get<0>(a12) == a2);
+    IS_TRUE(OM2->isEmpty(0));
+
+    OM2->addActor(a2, 2, 2);
+    OM2->addActor(a3, 3, 3);
+    IS_TRUE(OM2->isFull(0));
+
+
+
 
 
 }
-- 
GitLab