2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.idmanager;
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;
18 public class ReleasedIdHolder implements IdHolder {
19 private static final int INITIAL_INDEX = 0;
21 private final AtomicLong availableIdCount = new AtomicLong();
23 private final long timeDelaySec;
24 private final IdUtils idUtils;
26 private volatile List<DelayedIdEntry> delayedEntries = new CopyOnWriteArrayList<>();
28 public ReleasedIdHolder(IdUtils idUtils, long timeDelaySec) {
29 this.idUtils = idUtils;
30 this.timeDelaySec = timeDelaySec;
31 availableIdCount.set(0);
34 public ReleasedIdHolder(IdUtils idUtils, long timeDelaySec, List<DelayedIdEntry> delayedEntries) {
35 this(idUtils, timeDelaySec);
36 this.delayedEntries.addAll(delayedEntries);
39 public static class DelayedIdEntry implements Serializable {
41 private static final long serialVersionUID = 1L;
43 private final long id;
44 private final long readyTimeSec;
46 public DelayedIdEntry(long id, long readyTimeSec) {
48 this.readyTimeSec = readyTimeSec;
52 public String toString() {
53 return "{Id: " + id + " ReadyTimeSec: " + readyTimeSec + "}";
60 public long getReadyTimeSec() {
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();
72 availableIdCount.incrementAndGet();
75 DelayedIdEntry idEntry = delayedEntries.remove(INITIAL_INDEX);
76 if (idEntry.getReadyTimeSec() <= curTimeSec) {
77 allocatedId = Optional.of(idEntry.getId());
79 delayedEntries.add(INITIAL_INDEX, idEntry);
80 availableIdCount.incrementAndGet();
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);
95 public boolean isIdAvailable(long curTimeSec) {
96 if (availableIdCount.get() <= 0) {
99 boolean isIdExists = false;
100 if (!delayedEntries.isEmpty() && delayedEntries.get(INITIAL_INDEX).readyTimeSec <= curTimeSec) {
107 public long getAvailableIdCount() {
108 long availableDelayedEntries = availableIdCount.get();
109 int index = INITIAL_INDEX;
110 if (delayedEntries.isEmpty()) {
113 long curTimeSec = System.currentTimeMillis() / 1000;
114 while (index < availableDelayedEntries && delayedEntries.get(index).readyTimeSec <= curTimeSec) {
120 public long getTimeDelaySec() {
125 public List<DelayedIdEntry> getDelayedEntries() {
126 return delayedEntries;
129 public void replaceDelayedEntries(@NonNull List<DelayedIdEntry> newDelayedEntries) {
130 this.delayedEntries = new CopyOnWriteArrayList<>(newDelayedEntries);
133 public void setAvailableIdCount(long availableIdCount) {
134 this.availableIdCount.set(availableIdCount);
138 public String toString() {
139 return "ReleasedIdHolder [availableIdCount=" + availableIdCount
140 + ", timeDelaySec=" + timeDelaySec + ", delayedEntries="
141 + delayedEntries + "]";
145 public void refreshDataStore(IdPoolBuilder idPoolBuilder) {
146 idUtils.syncReleaseIdHolder(this, idPoolBuilder);