org.powertac.common.repo.TariffRepo.java Source code

Java tutorial

Introduction

Here is the source code for org.powertac.common.repo.TariffRepo.java

Source

/*
* Copyright (c) 2011-2014 by John Collins.
*
* 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 org.powertac.common.repo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.powertac.common.Broker;
import org.powertac.common.Rate;
import org.powertac.common.Tariff;
import org.powertac.common.TariffSpecification;
import org.powertac.common.enumerations.PowerType;
import org.powertac.common.msg.BalancingOrder;
import org.springframework.stereotype.Repository;

/**
 * Repository for TariffSpecifications, Tariffs, Rates, and other related types.
 * @author John Collins
 */
@Repository
public class TariffRepo implements DomainRepo {
    static private Logger log = Logger.getLogger(TariffRepo.class.getName());

    //@Autowired
    //private TimeService timeService;

    private HashMap<Long, TariffSpecification> specs;
    private HashSet<Long> deletedTariffs;
    private HashMap<PowerType, Tariff> defaultTariffs;
    private HashMap<Long, Tariff> tariffs;
    private HashMap<Long, Rate> rates;
    private HashMap<Long, BoPair> balancingOrders;
    private HashMap<Long, LinkedList<Tariff>> brokerTariffs;

    public TariffRepo() {
        super();
        specs = new HashMap<Long, TariffSpecification>();
        deletedTariffs = new HashSet<Long>();
        defaultTariffs = new HashMap<PowerType, Tariff>();
        tariffs = new HashMap<Long, Tariff>();
        brokerTariffs = new HashMap<Long, LinkedList<Tariff>>();
        rates = new HashMap<Long, Rate>();
        balancingOrders = new HashMap<Long, BoPair>();
    }

    /**
     * Adds a TariffSpecification to the repo just in case another spec
     * (or this one) has not already been added sometime in the past.
     */
    public synchronized void addSpecification(TariffSpecification spec) {
        if (isRemoved(spec.getId()) || null != specs.get(spec.getId())) {
            log.error("Attempt to insert tariff spec with duplicate ID " + spec.getId());
            return;
        }
        specs.put(spec.getId(), spec);
        for (Rate r : spec.getRates()) {
            rates.put(r.getId(), r);
        }
    }

    public void removeSpecification(long id) {
        specs.remove(id);
    }

    public void setDefaultTariff(TariffSpecification newSpec) {
        addSpecification(newSpec);
        Tariff tariff = new Tariff(newSpec);
        tariff.init();
        defaultTariffs.put(newSpec.getPowerType(), tariff);
    }

    public Tariff getDefaultTariff(PowerType type) {
        Tariff result = defaultTariffs.get(type);
        if (null == result) {
            result = defaultTariffs.get(type.getGenericType());
        }
        if (null == result) {
            log.error("Cannot find default tariff for PowerType " + type);
        }
        return result;
    }

    public synchronized TariffSpecification findSpecificationById(long id) {
        return specs.get(id);
    }

    public synchronized List<TariffSpecification> findTariffSpecificationsByBroker(Broker broker) {
        List<TariffSpecification> result = new ArrayList<TariffSpecification>();
        for (TariffSpecification spec : specs.values()) {
            if (spec.getBroker() == broker) {
                result.add(spec);
            }
        }
        return result;
    }

    public synchronized List<TariffSpecification> findTariffSpecificationsByPowerType(PowerType type) {
        List<TariffSpecification> result = new ArrayList<TariffSpecification>();
        for (TariffSpecification spec : specs.values()) {
            if (spec.getPowerType().canUse(type)) {
                result.add(spec);
            }
        }
        return result;
    }

    public synchronized List<TariffSpecification> findAllTariffSpecifications() {
        return new ArrayList<TariffSpecification>(specs.values());
    }

    public synchronized void addTariff(Tariff tariff) {
        // add to the tariffs list
        if (isRemoved(tariff.getId()) || null != tariffs.get(tariff.getId())) {
            log.error("Attempt to insert tariff with duplicate ID " + tariff.getId());
            return;
        }
        tariffs.put(tariff.getId(), tariff);

        // add to the brokerTariffs list
        LinkedList<Tariff> tariffList = brokerTariffs.get(tariff.getBroker().getId());
        if (null == tariffList) {
            tariffList = new LinkedList<Tariff>();
            brokerTariffs.put(tariff.getBroker().getId(), tariffList);
        }
        tariffList.push(tariff);
    }

    public synchronized Tariff findTariffById(long id) {
        return tariffs.get(id);
    }

    public synchronized List<Tariff> findAllTariffs() {
        return new ArrayList<Tariff>(tariffs.values());
    }

    public synchronized List<Tariff> findTariffsByState(Tariff.State state) {
        ArrayList<Tariff> result = new ArrayList<Tariff>();
        for (Tariff tariff : tariffs.values()) {
            if (state == tariff.getState()) {
                result.add(tariff);
            }
        }
        return result;
    }

    /**
     * Returns the list of active tariffs that exactly match the given
     * PowerType.
     */
    public synchronized List<Tariff> findActiveTariffs(PowerType type) {
        List<Tariff> result = new ArrayList<Tariff>();
        for (Tariff tariff : tariffs.values()) {
            if (tariff.getPowerType() == type && tariff.isSubscribable()) {
                result.add(tariff);
            }
        }
        return result;
    }

    /**
     * Returns the list of active tariffs that can be used by a customer
     * of the given PowerType, including those that are more generic than
     * the specific type.
     */
    public synchronized List<Tariff> findAllActiveTariffs(PowerType type) {
        List<Tariff> result = new ArrayList<Tariff>();
        for (Tariff tariff : tariffs.values()) {
            if (type.canUse(tariff.getPowerType()) && tariff.isSubscribable()) {
                result.add(tariff);
            }
        }
        return result;
    }

    /**
     * Returns the n most "recent" active tariffs from each broker
     * that can be used by a customer with the given powerType. 
     */
    public synchronized List<Tariff> findRecentActiveTariffs(int n, PowerType type) {
        List<Tariff> result = new ArrayList<Tariff>();
        HashMap<PowerType, Integer> ptCounter = new HashMap<PowerType, Integer>();
        for (Long id : brokerTariffs.keySet()) {
            ptCounter.clear();
            for (Tariff tariff : brokerTariffs.get(id)) {
                PowerType pt = tariff.getPowerType();
                if (tariff.isSubscribable() && type.canUse(pt)) {
                    Integer count = ptCounter.get(pt);
                    if (null == count)
                        count = 0;
                    if (count < n) {
                        result.add(tariff);
                        ptCounter.put(pt, count + 1);
                    }
                }
            }
        }
        return result;
    }

    public List<Tariff> findTariffsByBroker(Broker broker) {
        List<Tariff> result = brokerTariffs.get(broker.getId());
        if (null == result)
            return new LinkedList<Tariff>();
        else
            return result;
    }

    /**
     * Removes a tariff and its specification from the repo. remembers that tariff
     * has been removed, prevents re-adding.
     */
    public synchronized void removeTariff(Tariff tariff) {
        tariffs.remove(tariff.getId());
        deletedTariffs.add(tariff.getId());
        removeSpecification(tariff.getId());
    }

    /**
     * Deletes a tariff and its specification from the repo, without tracking.
     * Should not be used in the server.
     */
    public synchronized void deleteTariff(Tariff tariff) {
        tariffs.remove(tariff.getId());
        List<Tariff> bt = brokerTariffs.get(tariff.getBroker().getId());
        bt.remove(tariff);
        removeSpecification(tariff.getId());
    }

    /**
     * Tests whether a tariff has been deleted.
     */
    public synchronized boolean isRemoved(long tariffId) {
        return deletedTariffs.contains(tariffId);
    }

    public synchronized Rate findRateById(long id) {
        return rates.get(id);
    }

    /**
     * Adds a balancing order, indexed by its TariffSpec
     */
    public synchronized void addBalancingOrder(BalancingOrder order) {
        long tariffId = order.getTariffId();
        if (null != specs.get(tariffId)) {
            BoPair pair = balancingOrders.get(tariffId);
            if (null == pair) {
                pair = new BoPair();
                balancingOrders.put(tariffId, pair);
            }
            pair.add(order);
        }
    }

    /**
     * Retrieves the complete set of balancing orders
     */
    public synchronized Collection<BalancingOrder> getBalancingOrders() {
        ArrayList<BalancingOrder> result = new ArrayList<BalancingOrder>();
        for (BoPair pair : balancingOrders.values()) {
            for (BalancingOrder item : pair.getOrders()) {
                result.add(item);
            }
        }
        return result;
    }

    @Override
    public synchronized void recycle() {
        specs.clear();
        tariffs.clear();
        defaultTariffs.clear();
        deletedTariffs.clear();
        rates.clear();
        balancingOrders.clear();
        brokerTariffs.clear();
    }

    // Balancing orders come in pairs
    class BoPair {
        private BalancingOrder upOrder;
        private BalancingOrder downOrder;

        BoPair() {
            super();
        }

        BalancingOrder getUpOrder() {
            return upOrder;
        }

        void setUpOrder(BalancingOrder order) {
            upOrder = order;
        }

        BalancingOrder getDownOrder() {
            return downOrder;
        }

        void setDownOrder(BalancingOrder order) {
            downOrder = order;
        }

        // adds a new order of either gender
        void add(BalancingOrder order) {
            if (order.getExerciseRatio() >= 0.0)
                upOrder = order;
            else
                downOrder = order;
        }

        // returns contents as a list
        List<BalancingOrder> getOrders() {
            List<BalancingOrder> result = new ArrayList<BalancingOrder>();
            if (null != upOrder)
                result.add(upOrder);
            if (null != downOrder)
                result.add(downOrder);
            return result;
        }
    }
}