Jelajahi Sumber

HPCC-25750 Update DFUInfo cost calculation to reflect access cost

Signed-off-by: Shamser Ahmed <shamser.ahmed@lexisnexis.com>
Shamser Ahmed 3 tahun lalu
induk
melakukan
812f999371
4 mengubah file dengan 33 tambahan dan 10 penghapusan
  1. 22 9
      dali/base/dadfs.cpp
  2. 8 0
      helm/hpcc/values.schema.json
  3. 2 0
      helm/hpcc/values.yaml
  4. 1 1
      system/jlib/jstats.cpp

+ 22 - 9
dali/base/dadfs.cpp

@@ -177,21 +177,27 @@ static IPropertyTree *getEmptyAttr()
     return createPTree("Attr");
 }
 
-static double calcFileCost(const char * cluster, double sizeGB, double fileAgeDays)
+static double calcFileCost(const char * cluster, double sizeGB, double fileAgeDays, __int64 numDiskWrites, __int64 numDiskReads)
 {
     Owned<IPropertyTree> plane = getStoragePlane(cluster);
-    double atRestCost = 0.0;
+    Owned<IPropertyTree> global;
+    IPropertyTree * costPT = nullptr;
+
     if (plane && plane->hasProp("cost/@storageAtRest"))
     {
-        atRestCost = plane->getPropReal("cost/@storageAtRest", 0.0);
+        costPT = plane->queryPropTree("cost");
     }
     else
     {
-        Owned<IPropertyTree> global = getGlobalConfig();
-        atRestCost = global->getPropReal("cost/@storageAtRest", 0.0);
+        global.setown(getGlobalConfig());
+        costPT = global->queryPropTree("cost");
     }
-    double storageCostDaily = atRestCost * 12 / 365;
-    return storageCostDaily * sizeGB * fileAgeDays;
+    constexpr int accessPriceScalingFactor = 10000; // read/write pricing based on 10,000 operations
+    double atRestPrice = costPT->getPropReal("@storageAtRest", 0.0);
+    double readPrice =  costPT->getPropReal("@storageReads", 0.0);
+    double writePrice =  costPT->getPropReal("@storageWrites", 0.0);
+    double storageCostDaily = atRestPrice * 12 / 365;
+    return (storageCostDaily * sizeGB * fileAgeDays) + (readPrice * numDiskReads / accessPriceScalingFactor) + (writePrice * numDiskWrites / accessPriceScalingFactor);
 }
 
 RemoteFilename &constructPartFilename(IGroup *grp,unsigned partno,unsigned partmax,const char *name,const char *partmask,const char *partdir,unsigned copy,ClusterPartDiskMapSpec &mspec,RemoteFilename &rfn)
@@ -4767,6 +4773,13 @@ public:
         getModificationTime(dt);
         double fileAgeDays = difftime(time(nullptr), dt.getSimple())/(24*60*60);
         double sizeGB = getDiskSize(true, false) / ((double)1024 * 1024 * 1024);
+        const IPropertyTree *attrs = root->queryPropTree("Attr");
+        __int64 numDiskWrites = 0, numDiskReads = 0;
+        if (attrs)
+        {
+            numDiskWrites = attrs->getPropInt64("@numDiskWrites");
+            numDiskReads = attrs->getPropInt64("@numDiskReads");
+        }
 
         if (isEmptyString(cluster))
         {
@@ -4774,12 +4787,12 @@ public:
             unsigned countClusters = getClusterNames(clusterNames);
             double totalCost = 0.0;
             for (unsigned i = 0; i < countClusters; i++)
-                totalCost += calcFileCost(clusterNames[i], sizeGB, fileAgeDays);
+                totalCost += calcFileCost(clusterNames[i], sizeGB, fileAgeDays, numDiskWrites, numDiskReads);
             return totalCost;
         }
         else
         {
-            return calcFileCost(cluster, sizeGB, fileAgeDays);
+            return calcFileCost(cluster, sizeGB, fileAgeDays, numDiskWrites, numDiskReads);
         }
     }
 };

+ 8 - 0
helm/hpcc/values.schema.json

@@ -272,6 +272,14 @@
             "storageAtRest": {
                 "description": "storage cost (GiB per month)",
                 "type": "number"
+            },
+            "storageReads": {
+                "description": "cost per 10,000 read operations",
+                "type": "number"
+            },
+            "storageWrites": {
+                "description": "cost per 10,000 write operations",
+                "type": "number"
             }
           }
         },

+ 2 - 0
helm/hpcc/values.yaml

@@ -50,6 +50,8 @@ global:
     moneyLocale: "en_US.UTF-8"
     perCpu: 0.126
     storageAtRest: 0.0135
+    storageReads: 0.0485
+    storageWrites: 0.0038
 
   # postJobCommand will execute at the end of a dynamically launched K8s job,
   # when the main entrypoint process finishes, or if the readiness probes trigger a preStop event.

+ 1 - 1
system/jlib/jstats.cpp

@@ -430,7 +430,7 @@ StringBuffer & formatMoney(StringBuffer &out, unsigned __int64 value)
     std::locale & loc = moneyLocale.queryMoneyLocale();
     ss.imbue(loc);
     unsigned decplaces = std::use_facet<std::moneypunct<char>>(loc).frac_digits();
-    long double mvalue = cost_type2money(value)*std::pow(10, decplaces);
+    long double mvalue = ((long double)cost_type2money(value))*std::pow(10, decplaces);
     ss << std::showbase << std::put_money(mvalue);
     return out.append(ss.str().c_str());
 }