3535import hudson .util .CopyOnWriteMap ;
3636import java .io .File ;
3737import java .io .IOException ;
38- import java .util .AbstractCollection ;
3938import java .util .AbstractMap ;
40- import java .util .AbstractSet ;
4139import java .util .Collection ;
4240import java .util .Collections ;
4341import java .util .Comparator ;
4644import java .util .NoSuchElementException ;
4745import java .util .Set ;
4846import java .util .SortedMap ;
49- import java .util .Spliterator ;
50- import java .util .Spliterators ;
5147import java .util .TreeMap ;
52- import java .util .function .IntConsumer ;
5348import java .util .function .IntPredicate ;
5449import java .util .logging .Level ;
5550import java .util .logging .Logger ;
10196public 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