2 * Copyright 2011-2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
36 package gr.grnet.aquarium.policy
38 import gr.grnet.aquarium.Timespan
39 import gr.grnet.aquarium.util.Lock
40 import gr.grnet.aquarium.store.PolicyStore
41 import gr.grnet.aquarium.logic.accounting.dsl.Timeslot
42 import collection.immutable
45 * A caching [[gr.grnet.aquarium.store.PolicyStore]].
47 * @author Christos KK Loverdos <loverdos@gmail.com>
48 * @author Prodromos Gerakios <pgerakios@grnet.gr>
51 class CachingPolicyStore(defaultPolicy: PolicyModel, policyStore: PolicyStore) extends PolicyStore {
52 private[this] final val lock = new Lock()
53 private[this] final val EmptyPolicyByTimeslotMap = immutable.SortedMap[Timeslot, PolicyModel]()
55 private[this] var _policies = immutable.TreeSet[PolicyModel]()
57 private[this] def ensureLoaded[A](andThen: ⇒ A): A = {
59 if(_policies.isEmpty) {
60 _policies ++= policyStore.loadAllPolicies
62 if(_policies.isEmpty) {
63 _policies += defaultPolicy
64 policyStore.insertPolicy(defaultPolicy)
72 private[this] def policyAt(s:Long) : PolicyModel =
73 new StdPolicy("", None, Timespan(s), Set(), Set(), Map())
75 def loadAndSortPoliciesWithin(fromMillis: Long, toMillis: Long): immutable.SortedMap[Timeslot, PolicyModel] =
77 val range = Timeslot(fromMillis,toMillis)
78 /* ``to'' method: return the subset of all policies.from <= range.to */
79 _policies.to(policyAt(range.to.getTime)).foldLeft (EmptyPolicyByTimeslotMap) { (map,p) =>
80 if(p.validityTimespan.toTimeslot.to.getTime >= range.from.getTime)
81 map + ((p.validityTimespan.toTimeslot,p))
89 * Return the last (ordered) policy that starts before timeMillis
94 def loadValidPolicyAt(atMillis: Long): Option[PolicyModel] =
96 // Take the subset of all ordered policies up to the one with less than or equal start time
97 // and then return the last item. This should be the policy right before the given time.
98 // TODO: optimize the creation of the fake StdPolicy
99 _policies.to(policyAt(atMillis)).lastOption
104 * Store an accounting policy.
106 def insertPolicy(policy: PolicyModel): PolicyModel = {
108 this._policies += policy
109 policyStore.insertPolicy(policy)