简体   繁体   中英

get hashmap value from protected method java

I am new in complicated concepts of java, and i also know that its not a difficult question, but I know i am doing some mistake, here is a method in my class, and i am extracting its values in my main method, but it shows NaN this is method:

protected static Map<String, Double> getSlaMetrics(List<Vm> vms) {
        Map<String, Double> metrics = new HashMap<String, Double>();
        List<Double> slaViolation = new LinkedList<Double>();
        double totalAllocated = 0;
        double totalRequested = 0;
        double totalUnderAllocatedDueToMigration = 0;

    for (Vm vm : vms) {
        double vmTotalAllocated = 0;
        double vmTotalRequested = 0;
        double vmUnderAllocatedDueToMigration = 0;
        double previousTime = -1;
        double previousAllocated = 0;
        double previousRequested = 0;
        boolean previousIsInMigration = false;

        for (VmStateHistoryEntry entry : vm.getStateHistory()) {
            if (previousTime != -1) {
                double timeDiff = entry.getTime() - previousTime;
                vmTotalAllocated += previousAllocated * timeDiff;
                vmTotalRequested += previousRequested * timeDiff;

                if (previousAllocated < previousRequested) {
                    slaViolation.add((previousRequested - previousAllocated) / previousRequested);
                    if (previousIsInMigration) {
                        vmUnderAllocatedDueToMigration += (previousRequested - previousAllocated)
                                * timeDiff;
                    }
                }
            }

            previousAllocated = entry.getAllocatedMips();
            previousRequested = entry.getRequestedMips();
            previousTime = entry.getTime();
            previousIsInMigration = entry.isInMigration();
        }

        totalAllocated += vmTotalAllocated;
        totalRequested += vmTotalRequested;
        totalUnderAllocatedDueToMigration += vmUnderAllocatedDueToMigration;
    }

    metrics.put("overall", (totalRequested - totalAllocated) / totalRequested);
    if (slaViolation.isEmpty()) {
        metrics.put("average", 0.);
    } else {
        metrics.put("average", MathUtil.mean(slaViolation));
    }
    metrics.put("underallocated_migration", totalUnderAllocatedDueToMigration / totalRequested);
    // metrics.put("sla_time_per_vm_with_migration", slaViolationTimePerVmWithMigration /
    // totalTime);
    // metrics.put("sla_time_per_vm_without_migration", slaViolationTimePerVmWithoutMigration /
    // totalTime);

    return metrics;
}

I am trying to print its values by this code:

Map<String, Double> results = getSlaMetrics(vmList);
System.out.println("Overall Violations:" + results.get("overall"));

I know its a basic question but please dont mind.

Getting NaN "Not a Number" means we tried to divide zero by zero. Dividing non-zero number by zero will result to -Infinity or Infinity . I would take a look at this line and make sure don't divide the number by zero.

metrics.put("overall", (totalRequested - totalAllocated) / totalRequested);

As mentioned by Ivan in the comment below, let's demonstrate several cases of NaN , -Infinity and Infinity

System.out.println(0.0/0.0);
System.out.println(0/0.0);
System.out.println(-1/0.0);
System.out.println(1/0.0);

It produces the following output:

NaN
NaN
-Infinity
Infinity

The actual problem here is not with the Map and its methods but it is with the code. If you go through this code then the control is never going to the following


if (previousTime != -1) {
                double timeDiff = entry.getTime() - previousTime;
                vmTotalAllocated += previousAllocated * timeDiff;
                vmTotalRequested += previousRequested * timeDiff;

                if (previousAllocated < previousRequested) {
                    slaViolation.add((previousRequested - previousAllocated) / previousRequested);
                    if (previousIsInMigration) {
                        vmUnderAllocatedDueToMigration += (previousRequested - previousAllocated)
                                * timeDiff;
                    }
                }

so values assigned in the following assignment are zero

         totalAllocated += vmTotalAllocated;          //  zero
        totalRequested += vmTotalRequested;           // zero
        totalUnderAllocatedDueToMigration += vmUnderAllocatedDueToMigration;  // zero

Hence the following value in Map is 0.0/ 0.0 ie NaN

 metrics.put("overall", (totalRequested - totalAllocated) / totalRequested); 

   // Value in Map for Key "overall" is ==> 0.0 - 0.0/0.0 = NaN

So it's not a surprise if you get NaN in output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM