MDSAL-API Migration
[genius.git] / idmanager / idmanager-impl / src / main / java / org / opendaylight / genius / idmanager / ReleasedIdHolder.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.idmanager;
9
10 import java.io.Serializable;
11 import java.util.List;
12 import java.util.Optional;
13 import java.util.concurrent.CopyOnWriteArrayList;
14 import java.util.concurrent.atomic.AtomicLong;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolBuilder;
17
18 public class ReleasedIdHolder implements IdHolder {
19     private static final int INITIAL_INDEX = 0;
20
21     private final AtomicLong availableIdCount = new AtomicLong();
22
23     private final long timeDelaySec;
24     private final IdUtils idUtils;
25
26     private volatile List<DelayedIdEntry> delayedEntries = new CopyOnWriteArrayList<>();
27
28     public ReleasedIdHolder(IdUtils idUtils, long timeDelaySec) {
29         this.idUtils = idUtils;
30         this.timeDelaySec = timeDelaySec;
31         availableIdCount.set(0);
32     }
33
34     public ReleasedIdHolder(IdUtils idUtils, long timeDelaySec, List<DelayedIdEntry> delayedEntries) {
35         this(idUtils, timeDelaySec);
36         this.delayedEntries.addAll(delayedEntries);
37     }
38
39     public static class DelayedIdEntry implements Serializable {
40
41         private static final long serialVersionUID = 1L;
42
43         private final long id;
44         private final long readyTimeSec;
45
46         public DelayedIdEntry(long id, long readyTimeSec) {
47             this.id = id;
48             this.readyTimeSec = readyTimeSec;
49         }
50
51         @Override
52         public String toString() {
53             return "{Id: " + id + " ReadyTimeSec: " + readyTimeSec + "}";
54         }
55
56         public long getId() {
57             return id;
58         }
59
60         public long getReadyTimeSec() {
61             return readyTimeSec;
62         }
63     }
64
65     @Override
66     public Optional<Long> allocateId() {
67         long curTimeSec = System.currentTimeMillis() / 1000;
68         Optional<Long> allocatedId = Optional.empty();
69         if (isIdAvailable(curTimeSec)) {
70             Long count = availableIdCount.decrementAndGet();
71             if (count < 0L) {
72                 availableIdCount.incrementAndGet();
73                 return allocatedId;
74             }
75             DelayedIdEntry idEntry = delayedEntries.remove(INITIAL_INDEX);
76             if (idEntry.getReadyTimeSec() <= curTimeSec) {
77                 allocatedId = Optional.of(idEntry.getId());
78             } else {
79                 delayedEntries.add(INITIAL_INDEX, idEntry);
80                 availableIdCount.incrementAndGet();
81             }
82         }
83         return allocatedId;
84     }
85
86     @Override
87     public void addId(long id) {
88         long curTimeSec = System.currentTimeMillis() / 1000;
89         DelayedIdEntry entry = new DelayedIdEntry(id, curTimeSec + timeDelaySec);
90         availableIdCount.incrementAndGet();
91         delayedEntries.add(entry);
92     }
93
94     @Override
95     public boolean isIdAvailable(long curTimeSec) {
96         if (availableIdCount.get() <= 0) {
97             return false;
98         }
99         boolean isIdExists = false;
100         if (!delayedEntries.isEmpty() && delayedEntries.get(INITIAL_INDEX).readyTimeSec <= curTimeSec) {
101             isIdExists = true;
102         }
103         return isIdExists;
104     }
105
106     @Override
107     public long getAvailableIdCount() {
108         long availableDelayedEntries = availableIdCount.get();
109         int index = INITIAL_INDEX;
110         if (delayedEntries.isEmpty()) {
111             return index;
112         }
113         long curTimeSec = System.currentTimeMillis() / 1000;
114         while (index < availableDelayedEntries && delayedEntries.get(index).readyTimeSec <= curTimeSec) {
115             index++;
116         }
117         return index;
118     }
119
120     public long getTimeDelaySec() {
121         return timeDelaySec;
122     }
123
124     @NonNull
125     public List<DelayedIdEntry> getDelayedEntries() {
126         return delayedEntries;
127     }
128
129     public void replaceDelayedEntries(@NonNull List<DelayedIdEntry> newDelayedEntries) {
130         this.delayedEntries = new CopyOnWriteArrayList<>(newDelayedEntries);
131     }
132
133     public void setAvailableIdCount(long availableIdCount) {
134         this.availableIdCount.set(availableIdCount);
135     }
136
137     @Override
138     public String toString() {
139         return "ReleasedIdHolder [availableIdCount=" + availableIdCount
140                 + ", timeDelaySec=" + timeDelaySec + ", delayedEntries="
141                 + delayedEntries + "]";
142     }
143
144     @Override
145     public void refreshDataStore(IdPoolBuilder idPoolBuilder) {
146         idUtils.syncReleaseIdHolder(this, idPoolBuilder);
147     }
148 }