Open Kilda Java Documentation
MeterPool.java
Go to the documentation of this file.
1 /* Copyright 2018 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.floodlight.switchmanager;
17 
20 
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.ConcurrentHashMap;
28 
32 public class MeterPool {
33  private static final Logger logger = LoggerFactory.getLogger(MeterPool.class);
34  //@carmine: Probably should also start it at 200 and not 1 …
35  // I doubt we’ll end up with 200 Metered flows before we fix this.
36  private static final Integer MIN_METER_ID = 200;
37  private static final Integer MAX_METER_ID = 4095;
38  private final Map<SwitchId, ResourcePool> switchMeterPool = new ConcurrentHashMap<>();
39  private final Map<String, Set<Integer>> flowMeterPool = new ConcurrentHashMap<>();
40 
41  public synchronized Set<Integer> getMetersByFlow(final String flowId) {
42  return flowMeterPool.get(flowId);
43  }
44 
45  public synchronized Set<Integer> getMetersBySwitch(final SwitchId switchId) {
46  ResourcePool pool = switchMeterPool.get(switchId);
47  return pool == null ? null : pool.dumpPool();
48  }
49 
58  public synchronized Integer allocate(final SwitchId switchId, final String flowId, Integer meterId) {
59  ResourcePool switchPool = getSwitchPool(switchId);
60  Set<Integer> flowPool = getFlowPool(flowId);
61 
62  Integer allocatedMeterId = switchPool.allocate(meterId);
63  if (allocatedMeterId == null) {
64  logger.warn("Meter pool already have record for meter id {}", meterId);
65  allocatedMeterId = meterId;
66  }
67  flowPool.add(allocatedMeterId);
68 
69  return allocatedMeterId;
70  }
71 
75  public synchronized Integer allocate(final SwitchId switchId, final String flowId) {
76  ResourcePool switchPool = getSwitchPool(switchId);
77  Set<Integer> flowPool = getFlowPool(flowId);
78 
79  Integer meterId = switchPool.allocate();
80  flowPool.add(meterId);
81 
82  return meterId;
83  }
84 
88  public synchronized Integer deallocate(final SwitchId switchId, final String flowId) {
89  ResourcePool switchPool = switchMeterPool.get(switchId);
90  if (switchPool == null) {
91  logger.error("Could not deallocate meter: no such switch {}", switchId);
92  return null;
93  }
94 
95  Set<Integer> flowPool = flowMeterPool.remove(flowId);
96  if (flowPool == null) {
97  logger.error("Could not deallocate meter: no such flow id={}", flowId);
98  return null;
99  }
100 
101  Integer meterId = null;
102 
103  for (Integer meter : flowPool) {
104  if (switchPool.deallocate(meter) != null) {
105  meterId = meter;
106  }
107  }
108 
109  return meterId;
110  }
111 
112  private ResourcePool getSwitchPool(final SwitchId switchId) {
113  ResourcePool switchPool = switchMeterPool.get(switchId);
114  if (switchPool == null) {
115  switchPool = new ResourcePool(MIN_METER_ID, MAX_METER_ID);
116  switchMeterPool.put(switchId, switchPool);
117  }
118 
119  return switchPool;
120  }
121 
122  private Set<Integer> getFlowPool(final String flowId) {
123  return flowMeterPool.computeIfAbsent(flowId, k -> new HashSet<>());
124  }
125 }
synchronized Set< Integer > getMetersBySwitch(final SwitchId switchId)
Definition: MeterPool.java:45
synchronized Integer deallocate(final SwitchId switchId, final String flowId)
Definition: MeterPool.java:88
synchronized Integer allocate(final SwitchId switchId, final String flowId)
Definition: MeterPool.java:75
Integer deallocate(final Integer resourceId)
synchronized Integer allocate(final SwitchId switchId, final String flowId, Integer meterId)
Definition: MeterPool.java:58
synchronized Set< Integer > getMetersByFlow(final String flowId)
Definition: MeterPool.java:41