// Copyright 2016 Twitter. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.twitter.heron.spi.packing; import com.twitter.heron.common.basics.ByteAmount; /** * Definition of Resources. Used to form packing structure output. */ public class Resource { private double cpu; private ByteAmount ram; private ByteAmount disk; public Resource(double cpu, ByteAmount ram, ByteAmount disk) { this.cpu = cpu; this.ram = ram; this.disk = disk; } @Override public boolean equals(Object obj) { if (obj instanceof Resource) { Resource r = (Resource) obj; return (this.getCpu() == r.getCpu()) && (this.getRam().equals(r.getRam())) && (this.getDisk().equals(r.getDisk())); } else { return false; } } public double getCpu() { return cpu; } public ByteAmount getRam() { return ram; } public ByteAmount getDisk() { return disk; } public Resource cloneWithRam(ByteAmount newRam) { return new Resource(this.getCpu(), newRam, this.getDisk()); } /** * Subtracts a given resource from the current resource. The results is never negative. */ public Resource subtractAbsolute(Resource other) { double cpuDifference = this.getCpu() - other.getCpu(); double extraCpu = Math.max(0, cpuDifference); ByteAmount ramDifference = this.getRam().minus(other.getRam()); ByteAmount extraRam = ByteAmount.ZERO.max(ramDifference); ByteAmount diskDifference = this.getDisk().minus(other.getDisk()); ByteAmount extraDisk = ByteAmount.ZERO.max(diskDifference); return new Resource(extraCpu, extraRam, extraDisk); } /** * Adds a given resource from the current resource. */ public Resource plus(Resource other) { double totalCpu = this.getCpu() + other.getCpu(); ByteAmount totalRam = this.getRam().plus(other.getRam()); ByteAmount totalDisk = this.getDisk().plus(other.getDisk()); return new Resource(totalCpu, totalRam, totalDisk); } /** * Divides a resource by another resource by dividing the cpu, memory and disk values of the resources. * It returns the maximum of the three results. */ public double divideBy(Resource other) throws RuntimeException { if (other.getCpu() == 0 || other.getRam().isZero() || other.getDisk().isZero()) { throw new RuntimeException("Division by 0."); } else { double cpuFactor = Math.ceil(this.getCpu() / other.getCpu()); double ramFactor = Math.ceil((double) this.getRam().asBytes() / other.getRam().asBytes()); double diskFactor = Math.ceil((double) this.getDisk().asBytes() / other.getDisk().asBytes()); return Math.max(cpuFactor, Math.max(ramFactor, diskFactor)); } } @Override public int hashCode() { int result; long temp; temp = Double.doubleToLongBits(cpu); result = (int) (temp ^ (temp >>> 32)); result = 31 * result + ram.hashCode(); result = 31 * result + disk.hashCode(); return result; } @Override public String toString() { return String.format("{cpu: %f, ram: %s, disk: %s}", getCpu(), getRam(), getDisk()); } }