Package com.netflix.ice.processor

Source Code of com.netflix.ice.processor.Ec2InstanceReservationPrice$Price

/*
*
*  Copyright 2013 Netflix, Inc.
*
*     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.netflix.ice.processor;

import com.google.common.collect.Maps;
import com.netflix.ice.tag.Region;
import com.netflix.ice.tag.UsageType;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Hours;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class Ec2InstanceReservationPrice {

    public final VersionedPrice upfrontPrice;
    public final VersionedPrice hourlyPrice;

    public Ec2InstanceReservationPrice() {
        upfrontPrice = new VersionedPrice();
        hourlyPrice = new VersionedPrice();
    }

    private Ec2InstanceReservationPrice(VersionedPrice upfrontPrice, VersionedPrice hourlyPrice) {
        this.upfrontPrice = upfrontPrice;
        this.hourlyPrice = hourlyPrice;
    }

    public static class VersionedPrice {
        private ConcurrentSkipListMap<Long, Price> prices = new ConcurrentSkipListMap<Long, Price>();

        public Price getCreatePrice(Long millis) {
            Price price = prices.get(millis);
            if (price == null) {
                price = new Price();
                prices.put(millis, price);
            }
            return price;
        }

        public Price getPrice(Long millis) {
            if (millis == null)
                return prices.lastEntry().getValue();

            for (Map.Entry<Long, Price> entry : prices.entrySet()) {
                if (entry.getKey() > millis) {
                    return entry.getValue();
                }
            }
            return prices.lastEntry().getValue();
            //throw new RuntimeException("Cannot find list price");
        }

        public double getListPrice(long millis) {
            for (Map.Entry<Long, Price> entry : prices.entrySet()) {
                if (entry.getKey() > millis) {
                    return entry.getValue().listPrice;
                }
            }
            throw new RuntimeException("Cannot find list price");
        }
    }

    public static class Price {
        private Double listPrice = null;
        private TreeMap<Long, Double> tierPrice = Maps.newTreeMap();

        public void setListPrice(double listPrice) {
            this.listPrice = listPrice;
        }

        public Double getListPrice() {
            return this.listPrice;
        }

        public void setPrice(Long tier, Double price) {
            tierPrice.put(tier, price);
        }

        public double getPrice(double tier) {
            for (Map.Entry<Long, Double> entry : tierPrice.descendingMap().entrySet()) {
                if (tier > entry.getKey()) {
                    return entry.getValue();
                }
            }
            return listPrice;
        }

        public double getUpfrontAmortized(long startMillis, ReservationPeriod reservationPeriod, double tier) {
            double price = -1;
            for (Map.Entry<Long, Double> entry : tierPrice.descendingMap().entrySet()) {
                if (tier > entry.getKey()) {
                    price = entry.getValue();
                    break;
                }
            }
            if (price < 0)
                price = listPrice;

            DateTime start = new DateTime(startMillis, DateTimeZone.UTC);
            DateTime end = start.plusYears(reservationPeriod.years);
            int hours = Hours.hoursBetween(start, end).getHours();
            return price / hours;
        }
    }

    public static class Serializer {
        private static void serializeVersionedPrice(DataOutput out, VersionedPrice versionedPrice) throws IOException {
            out.writeInt(versionedPrice.prices.size());
            for (Long millis: versionedPrice.prices.keySet()) {
                out.writeLong(millis);
                out.writeDouble(versionedPrice.prices.get(millis).listPrice);
            }
        }

        private static VersionedPrice deserializeVersionedPrice(DataInput in) throws IOException {
            VersionedPrice versionedPrice = new VersionedPrice();
            int size = in.readInt();
            for (int i = 0; i < size; i++) {
                long millis = in.readLong();
                double price = in.readDouble();
                versionedPrice.getCreatePrice(millis).setListPrice(price);
            }
            return versionedPrice;
        }

        public static void serialize(DataOutput out, Ec2InstanceReservationPrice reservationPrice) throws IOException {
            serializeVersionedPrice(out, reservationPrice.upfrontPrice);
            serializeVersionedPrice(out, reservationPrice.hourlyPrice);
        }

        public static Ec2InstanceReservationPrice deserialize(DataInput in) throws IOException {
            VersionedPrice upfrontPrice = deserializeVersionedPrice(in);
            VersionedPrice hourlyPrice = deserializeVersionedPrice(in);

            return new Ec2InstanceReservationPrice(upfrontPrice, hourlyPrice);
        }
    }

    public static class Key implements Comparable<Key> {
        public final Region region;
        public final UsageType usageType;

        public Key(Region region, UsageType usageType) {
            this.region = region;
            this.usageType = usageType;
        }

        public int compareTo(Key t) {
            int result = this.region.compareTo(t.region);
            if (result != 0)
                return result;
            result = this.usageType.compareTo(t.usageType);
            return result;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(region.toString()).append("|").append(usageType);
            return sb.toString();
        }

        @Override
        public boolean equals(Object o) {
            if (o == null)
                return false;
            Key other = (Key)o;
            return
                this.region == other.region &&
                this.usageType == other.usageType;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + this.region.hashCode();
            result = prime * result + this.usageType.hashCode();
            return result;
        }

        public static class Serializer {
            public static void serialize(DataOutput out, Key key) throws IOException {
                out.writeUTF(key.region.toString());
                UsageType.serialize(out, key.usageType);
            }

            public static Key deserialize(DataInput in) throws IOException {
                Region region = Region.getRegionByName(in.readUTF());
                UsageType usageType = UsageType.deserialize(in);

                return new Key(region, usageType);
            }
        }
    }

    public static enum ReservationPeriod {
        oneyear(1, "yrTerm1"),
        threeyear(3, "yrTerm3");

        public final int years;
        public final String jsonTag;

        private ReservationPeriod(int years, String jsonTag) {
            this.years = years;
            this.jsonTag = jsonTag;
        }

    }

    public static enum ReservationUtilization {
        LIGHT,
        MEDIUM,
        HEAVY,
        FIXED;

        public static ReservationUtilization get(String offeringType) {
            if (offeringType.indexOf(" ") > 0) {
                offeringType = offeringType.substring(0, offeringType.indexOf(" ")).toUpperCase();
                return valueOf(offeringType);
            }
            else {
                for (ReservationUtilization utilization: values()) {
                    if (offeringType.toUpperCase().startsWith(utilization.name()))
                        return utilization;
                }
                throw new RuntimeException("Unknown ReservationUtilization " + offeringType);
            }
        }
    }
}
TOP

Related Classes of com.netflix.ice.processor.Ec2InstanceReservationPrice$Price

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.