From 268cd538e2a9cdca7499deccc0cab2dd2acb5e78 Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@lothar.com>
Date: Thu, 19 Feb 2009 01:44:35 -0700
Subject: [PATCH] reliability: switch to NumPy, since Numeric is deprecated

---
 src/allmydata/reliability.py            | 35 +++++++++----------------
 src/allmydata/test/test_provisioning.py |  4 +--
 src/allmydata/test/test_web.py          |  2 +-
 src/allmydata/web/reliability.py        |  2 +-
 src/allmydata/web/root.py               |  2 +-
 twisted/plugins/allmydata_trial.py      |  2 +-
 6 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/src/allmydata/reliability.py b/src/allmydata/reliability.py
index ecbd7c08..2729692a 100644
--- a/src/allmydata/reliability.py
+++ b/src/allmydata/reliability.py
@@ -2,23 +2,12 @@
 
 import math
 from allmydata.util import statistics
-import Numeric
-from Numeric import array, matrixmultiply as mm
+from numpy import array
 
 DAY=24*60*60
 MONTH=31*DAY
 YEAR=365*DAY
 
-def my_dot(v1, v2):
-    #print v1.shape, v2.shape
-    #assert len(v1.shape) == 2
-    #assert v1.shape[0] == 1
-    #assert len(v2.shape) == 2
-    #assert v2.shape[0] == 1
-    #assert v1.shape[1] == v2.shape[1]
-    #for i in range(v1.shape[1]):
-    return Numeric.sum(Numeric.sum(v1*v2))
-
 class ReliabilityModel:
     """Generate a model of system-wide reliability, given several input
     parameters.
@@ -85,9 +74,9 @@ class ReliabilityModel:
 
         #print "DECAY:", decay
         #print "OLD-POST-REPAIR:", old_post_repair
-        #print "NEW-POST-REPAIR:", mm(decay, repair)
+        #print "NEW-POST-REPAIR:", decay * repair
         #print "REPAIR:", repair
-        #print "DIFF:", (old_post_repair - mm(decay, repair))
+        #print "DIFF:", (old_post_repair - decay * repair)
 
         START = array([[0]*N + [1]])
         ALIVE = array([[0]*k + [1]*(1+N-k)])
@@ -112,24 +101,24 @@ class ReliabilityModel:
         report = ReliabilityReport()
 
         for t in range(0, report_span+delta, delta):
-            unmaintained_state = mm(unmaintained_state, decay)
-            maintained_state = mm(maintained_state, decay)
+            unmaintained_state = unmaintained_state * decay
+            maintained_state = maintained_state * decay
             if (t-last_check) > check_period:
                 last_check = t
                 # we do a check-and-repair this frequently
-                need_repair = my_dot(maintained_state, REPAIRp)
+                need_repair = (maintained_state * REPAIRp).sum()
 
                 P_repaired_last_check_period = need_repair
-                new_shares = my_dot(maintained_state, REPAIR_newshares)
+                new_shares = (maintained_state * REPAIR_newshares).sum()
                 needed_repairs.append(need_repair)
                 needed_new_shares.append(new_shares)
 
-                maintained_state = mm(maintained_state, repair)
+                maintained_state = maintained_state * repair
 
             if (t-last_report) > report_period:
                 last_report = t
-                P_dead_unmaintained = my_dot(unmaintained_state, DEAD)
-                P_dead_maintained = my_dot(maintained_state, DEAD)
+                P_dead_unmaintained = (unmaintained_state * DEAD).sum()
+                P_dead_maintained = (maintained_state * DEAD).sum()
                 cumulative_number_of_repairs = sum(needed_repairs)
                 cumulative_number_of_new_shares = sum(needed_new_shares)
                 report.add_sample(t, unmaintained_state, maintained_state,
@@ -139,8 +128,8 @@ class ReliabilityModel:
                                   P_dead_unmaintained, P_dead_maintained)
 
         # record one more sample at the end of the run
-        P_dead_unmaintained = my_dot(unmaintained_state, DEAD)
-        P_dead_maintained = my_dot(maintained_state, DEAD)
+        P_dead_unmaintained = (unmaintained_state * DEAD).sum()
+        P_dead_maintained = (maintained_state * DEAD).sum()
         cumulative_number_of_repairs = sum(needed_repairs)
         cumulative_number_of_new_shares = sum(needed_new_shares)
         report.add_sample(t, unmaintained_state, maintained_state,
diff --git a/src/allmydata/test/test_provisioning.py b/src/allmydata/test/test_provisioning.py
index ec99961e..74c57c4a 100644
--- a/src/allmydata/test/test_provisioning.py
+++ b/src/allmydata/test/test_provisioning.py
@@ -5,7 +5,7 @@ ReliabilityModel = None
 try:
     from allmydata.reliability import ReliabilityModel
 except ImportError:
-    pass # might not be importable, since it needs Numeric
+    pass # might not be importable, since it needs NumPy
 
 from nevow import inevow
 from zope.interface import implements
@@ -70,7 +70,7 @@ YEAR=365*DAY
 class Reliability(unittest.TestCase):
     def test_basic(self):
         if ReliabilityModel is None:
-            raise unittest.SkipTest("reliability model requires Numeric")
+            raise unittest.SkipTest("reliability model requires NumPy")
         r = ReliabilityModel.run(delta=100000,
                                  report_period=3*MONTH,
                                  report_span=5*YEAR)
diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py
index 8ea358de..940a1c8b 100644
--- a/src/allmydata/test/test_web.py
+++ b/src/allmydata/test/test_web.py
@@ -476,7 +476,7 @@ class Web(WebMixin, testutil.StallMixin, unittest.TestCase):
             from allmydata import reliability
             _hush_pyflakes = reliability
         except:
-            raise unittest.SkipTest("reliability tool requires Numeric")
+            raise unittest.SkipTest("reliability tool requires NumPy")
 
         d = self.GET("/reliability/")
         def _check(res):
diff --git a/src/allmydata/web/reliability.py b/src/allmydata/web/reliability.py
index 796f614d..593ceca0 100644
--- a/src/allmydata/web/reliability.py
+++ b/src/allmydata/web/reliability.py
@@ -2,7 +2,7 @@
 from nevow import rend, inevow, tags as T
 reliability = None # might not be usable
 try:
-    from allmydata import reliability # requires Numeric and PIL
+    from allmydata import reliability # requires NumPy
 except ImportError:
     pass
 from allmydata.web.common import getxmlfile, get_arg
diff --git a/src/allmydata/web/root.py b/src/allmydata/web/root.py
index 3a57e6b3..f429e05f 100644
--- a/src/allmydata/web/root.py
+++ b/src/allmydata/web/root.py
@@ -122,7 +122,7 @@ class NoReliability(rend.Page):
   </head>
   <body>
   <h2>"Reliability" page not available</h2>
-  <p>Please install the python "Numeric" module to enable this page.</p>
+  <p>Please install the python "NumPy" module to enable this page.</p>
   </body>
 </html>
 ''')
diff --git a/twisted/plugins/allmydata_trial.py b/twisted/plugins/allmydata_trial.py
index 93af3802..275bbb24 100644
--- a/twisted/plugins/allmydata_trial.py
+++ b/twisted/plugins/allmydata_trial.py
@@ -10,7 +10,7 @@ from twisted.plugin import IPlugin
 # note that this .py file is *not* in a package: there is no __init__.py in
 # our parent directory. This is important, because otherwise ours would fight
 # with Twisted's. When trial looks for plugins, it merely executes all the
-# *.py files it finds in and twisted/plugins/ subdirectories of anything on
+# *.py files it finds in any twisted/plugins/ subdirectories of anything on
 # sys.path . The namespace that results from executing these .py files is
 # examined for instances which provide both IPlugin and the target interface
 # (in this case, trial is looking for IReporter instances). Each such
-- 
2.45.2