Skip to content

Commit 3088def

Browse files
author
Dmytro Ukhlov
committed
Refactor BuildReferenceMapAdapter
1 parent f836cdc commit 3088def

File tree

5 files changed

+191
-539
lines changed

5 files changed

+191
-539
lines changed

core/src/main/java/hudson/model/RunMap.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ protected String getIdOf(R r) {
201201

202202
/**
203203
* Add a <em>new</em> build to the map.
204-
* Do not use when loading existing builds (use {@link #put(Integer, Object)}).
204+
* Do not use when loading existing builds (use {@link #putAll(Map)}).
205205
*/
206206
@Override
207207
public R put(R r) {

core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java

Lines changed: 30 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@
3535
import hudson.util.CopyOnWriteMap;
3636
import java.io.File;
3737
import java.io.IOException;
38-
import java.util.AbstractCollection;
3938
import java.util.AbstractMap;
40-
import java.util.AbstractSet;
4139
import java.util.Collection;
4240
import java.util.Collections;
4341
import java.util.Comparator;
@@ -46,10 +44,7 @@
4644
import java.util.NoSuchElementException;
4745
import java.util.Set;
4846
import java.util.SortedMap;
49-
import java.util.Spliterator;
50-
import java.util.Spliterators;
5147
import java.util.TreeMap;
52-
import java.util.function.IntConsumer;
5348
import java.util.function.IntPredicate;
5449
import java.util.logging.Level;
5550
import java.util.logging.Logger;
@@ -101,146 +96,23 @@
10196
public abstract class AbstractLazyLoadRunMap<R> extends AbstractMap<Integer, R> implements SortedMap<Integer, R> {
10297
private final CopyOnWriteMap.Tree<Integer, BuildReference<R>> core = new CopyOnWriteMap.Tree<>(
10398
Collections.reverseOrder());
104-
105-
private LazyLoadRunMapEntrySet<R> entrySet = new LazyLoadRunMapEntrySet<>(this);
106-
107-
private transient volatile Set<Integer> keySet;
108-
private transient volatile Collection<R> values;
99+
private final BuildReferenceMapAdapter<R> adapter = new BuildReferenceMapAdapter<>(core, this::resolveBuildRef,
100+
this::getNumberOf, this::removeValue);
109101

110102
@Override
111103
public Set<Integer> keySet() {
112-
Set<Integer> ks = keySet;
113-
if (ks == null) {
114-
ks = new AbstractSet<>() {
115-
@Override
116-
public Iterator<Integer> iterator() {
117-
return new Iterator() {
118-
private final Iterator<Entry<Integer, R>> it = entrySet().iterator();
119-
120-
@Override
121-
public boolean hasNext() {
122-
return it.hasNext();
123-
}
124-
125-
@Override
126-
public Integer next() {
127-
return it.next().getKey();
128-
}
129-
130-
@Override
131-
public void remove() {
132-
it.remove();
133-
}
134-
};
135-
}
136-
137-
@Override
138-
public Spliterator<Integer> spliterator() {
139-
return new Spliterators.AbstractIntSpliterator(
140-
Long.MAX_VALUE,
141-
Spliterator.DISTINCT | Spliterator.ORDERED | Spliterator.SORTED) {
142-
private final Iterator<Integer> it = iterator();
143-
144-
@Override
145-
public boolean tryAdvance(IntConsumer action) {
146-
if (action == null) {
147-
throw new NullPointerException();
148-
}
149-
if (it.hasNext()) {
150-
action.accept(it.next());
151-
return true;
152-
}
153-
return false;
154-
}
155-
156-
@Override
157-
public Comparator<Integer> getComparator() {
158-
return Collections.reverseOrder();
159-
}
160-
};
161-
}
162-
163-
@Override
164-
public int size() {
165-
return AbstractLazyLoadRunMap.this.size();
166-
}
167-
168-
@Override
169-
public boolean isEmpty() {
170-
return AbstractLazyLoadRunMap.this.isEmpty();
171-
}
172-
173-
@Override
174-
public void clear() {
175-
AbstractLazyLoadRunMap.this.clear();
176-
}
177-
178-
@Override
179-
public boolean contains(Object k) {
180-
return AbstractLazyLoadRunMap.this.containsKey(k);
181-
}
182-
};
183-
keySet = ks;
184-
}
185-
return ks;
104+
return adapter.keySet();
186105
}
187106

188107
@Override
189108
public Collection<R> values() {
190-
Collection<R> vals = values;
191-
if (vals == null) {
192-
vals = new AbstractCollection<>() {
193-
@Override
194-
public Iterator<R> iterator() {
195-
return new Iterator<>() {
196-
private final Iterator<Entry<Integer, R>> it = entrySet().iterator();
197-
198-
@Override
199-
public boolean hasNext() {
200-
return it.hasNext();
201-
}
202-
203-
@Override
204-
public R next() {
205-
return it.next().getValue();
206-
}
207-
208-
@Override
209-
public void remove() {
210-
it.remove();
211-
}
212-
};
213-
}
214-
215-
@Override
216-
public Spliterator<R> spliterator() {
217-
return Spliterators.spliteratorUnknownSize(
218-
iterator(), Spliterator.DISTINCT | Spliterator.ORDERED);
219-
}
220-
221-
@Override
222-
public int size() {
223-
return AbstractLazyLoadRunMap.this.size();
224-
}
225-
226-
@Override
227-
public boolean isEmpty() {
228-
return AbstractLazyLoadRunMap.this.isEmpty();
229-
}
230-
231-
@Override
232-
public void clear() {
233-
AbstractLazyLoadRunMap.this.clear();
234-
}
109+
return adapter.values();
110+
}
235111

236-
@Override
237-
public boolean contains(Object v) {
238-
return AbstractLazyLoadRunMap.this.containsValue(v);
239-
}
240-
};
241-
values = vals;
242-
}
243-
return vals;
112+
@Override
113+
public Set<Entry<Integer, R>> entrySet() {
114+
assert baseDirInitialized();
115+
return adapter.entrySet();
244116
}
245117

246118
/**
@@ -359,13 +231,17 @@ public Comparator<? super Integer> comparator() {
359231

360232
@Override
361233
public boolean isEmpty() {
362-
return search(Integer.MAX_VALUE, DESC) == null;
234+
return adapter.isEmpty();
363235
}
364236

365237
@Override
366-
public Set<Entry<Integer, R>> entrySet() {
367-
assert baseDirInitialized();
368-
return entrySet;
238+
public boolean containsKey(Object value) {
239+
return adapter.containsKey(value);
240+
}
241+
242+
@Override
243+
public boolean containsValue(Object value) {
244+
return adapter.containsValue(value);
369245
}
370246

371247
/**
@@ -379,7 +255,7 @@ public SortedMap<Integer, R> getLoadedBuilds() {
379255
res.put(entry.getKey(), buildRef);
380256
}
381257
}
382-
return Collections.unmodifiableSortedMap(new BuildReferenceMapAdapter<>(this, res));
258+
return Collections.unmodifiableSortedMap(new BuildReferenceMapAdapter<>(res, this::resolveBuildRef, this::getNumberOf));
383259
}
384260

385261
/**
@@ -390,33 +266,17 @@ public SortedMap<Integer, R> getLoadedBuilds() {
390266
*/
391267
@Override
392268
public SortedMap<Integer, R> subMap(Integer fromKey, Integer toKey) {
393-
// TODO: if this method can produce a lazy map, that'd be wonderful
394-
// because due to the lack of floor/ceil/higher/lower kind of methods
395-
// to look up keys in SortedMap, various places of Jenkins rely on
396-
// subMap+firstKey/lastKey combo.
397-
398-
R start = search(fromKey, DESC);
399-
if (start == null) return EMPTY_SORTED_MAP;
400-
401-
R end = search(toKey, ASC);
402-
if (end == null) return EMPTY_SORTED_MAP;
403-
404-
for (R i = start; i != end; ) {
405-
i = search(getNumberOf(i) - 1, DESC);
406-
assert i != null;
407-
}
408-
409-
return Collections.unmodifiableSortedMap(new BuildReferenceMapAdapter<>(this, core.subMap(fromKey, toKey)));
269+
return Collections.unmodifiableSortedMap(adapter.subMap(fromKey, toKey));
410270
}
411271

412272
@Override
413273
public SortedMap<Integer, R> headMap(Integer toKey) {
414-
return subMap(Integer.MAX_VALUE, toKey);
274+
return Collections.unmodifiableSortedMap(adapter.headMap(toKey));
415275
}
416276

417277
@Override
418278
public SortedMap<Integer, R> tailMap(Integer fromKey) {
419-
return subMap(fromKey, Integer.MIN_VALUE);
279+
return Collections.unmodifiableSortedMap(adapter.tailMap(fromKey));
420280
}
421281

422282
@Override
@@ -463,7 +323,7 @@ public R get(int n) {
463323
* @since 2.14
464324
*/
465325
public boolean runExists(int number) {
466-
return this.core.containsKey(number);
326+
return adapter.containsKey(number);
467327
}
468328

469329
/**
@@ -552,7 +412,7 @@ private R resolveBuildRef(BuildReference<R> ref) {
552412
}
553413

554414
public R getByNumber(int n) {
555-
return resolveBuildRef(core.get(n));
415+
return adapter.get(n);
556416
}
557417

558418
/**
@@ -597,14 +457,13 @@ public synchronized void putAll(Map<? extends Integer, ? extends R> newData) {
597457
core.putAll(newWrapperData);
598458
}
599459

600-
/**
601-
* Return underlining {@link BuildReference} core map.
602-
*
603-
* @return
604-
* full build reference map.
605-
*/
606-
/*package*/ SortedMap<Integer, BuildReference<R>> all() {
607-
return core;
460+
@Override
461+
public R remove(Object key) {
462+
R val = get(key);
463+
if (val == null) {
464+
return null;
465+
}
466+
return removeValue(val) ? val : null;
608467
}
609468

610469
/**
@@ -652,7 +511,6 @@ protected BuildReference<R> createReference(R r) {
652511
return new BuildReference<>(getIdOf(r), r);
653512
}
654513

655-
656514
/**
657515
* Parses {@code R} instance from data in the specified directory.
658516
*
@@ -694,7 +552,5 @@ public enum Direction {
694552
ASC, DESC, EXACT
695553
}
696554

697-
private static final SortedMap EMPTY_SORTED_MAP = Collections.unmodifiableSortedMap(new TreeMap());
698-
699555
static final Logger LOGGER = Logger.getLogger(AbstractLazyLoadRunMap.class.getName());
700556
}

0 commit comments

Comments
 (0)