File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\model\ResourceList.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.model;
25
26 import java.util.Set;
27 import java.util.HashSet;
28 import java.util.Map;
29 import java.util.HashMap;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Map.Entry;
33
34 /**
35 * List of {@link Resource}s that an activity needs.
36 *
37 * <p>
38 * There are two ways to access resources. Read and write.
39 * As with usual reader/writer pattern, multiple read accesses can
40 * co-exist concurrently, but write access requires exclusive access
41 * (the number of allowed concurrent write activity is determined by
42 * {@link Resource#numConcurrentWrite}.
43 *
44 * @author Kohsuke Kawaguchi
45 * @since 1.121
46 */
47 public final class ResourceList {
48 /**
49 * All resources (R/W.)
50 */
51 private final Set<Resource> all = new HashSet<Resource>();
52
53 /**
54 * Write accesses. Values are the # of write counts that this list uses.
55 *
56 * The values are mostly supposed to be 1, but when {@link ResourceController}
57 * uses a list to keep track of the union of all the activities, it can get larger.
58 */
59 private final Map<Resource,Integer> write = new HashMap<Resource,Integer>();
60 private static final Integer MAX_INT = Integer.MAX_VALUE;
61
62 /**
63 * Creates union of all resources.
64 */
65 public static ResourceList union(ResourceList... lists) {
66 return union(Arrays.asList(lists));
67 }
68
69 /**
70 * Creates union of all resources.
71 */
72 public static ResourceList union(Collection<ResourceList> lists) {
73 switch(lists.size()) {
74 case 0:
75 return EMPTY;
76 case 1:
77 return lists.iterator().next();
78 default:
79 ResourceList r = new ResourceList();
80 for (ResourceList l : lists) {
81 r.all.addAll(l.all);
82 for (Entry<Resource, Integer> e : l.write.entrySet())
83 r.write.put(e.getKey(), unbox(r.write.get(e.getKey()))+e.getValue());
84 }
85 return r;
86 }
87 }
88
89 /**
90 * Adds a resource for read access.
91 */
92 public ResourceList r(Resource r) {
93 all.add(r);
94 return this;
95 }
96
97 /**
98 * Adds a resource for write access.
99 */
100 public ResourceList w(Resource r) {
101 all.add(r);
102 write.put(r, unbox(write.get(r))+1);
103 return this;
104 }
105
106 /**
107 * Checks if this resource list and that resource list has any conflicting
108 * resource access.
109 */
110 public boolean isCollidingWith(ResourceList that) {
111 return getConflict(that)!=null;
112 }
113
114 /**
115 * Returns the resource in this list that's colliding with the given resource list.
116 */
117 public Resource getConflict(ResourceList that) {
118 Resource r = _getConflict(this,that);
119 if(r!=null) return r;
120 return _getConflict(that,this);
121 }
122
123 private Resource _getConflict(ResourceList lhs, ResourceList rhs) {
124 for (Entry<Resource,Integer> r : lhs.write.entrySet()) {
125 for (Resource l : rhs.all) {
126 Integer v = rhs.write.get(l);
127 if(v!=null) // this is write/write conflict.
128 v += r.getValue();
129 else // Otherwise set it to a very large value, since it's read/write conflict
130 v = MAX_INT;
131 if(r.getKey().isCollidingWith(l,unbox(v)))
132 return r.getKey();
133 }
134 }
135 return null;
136 }
137
138 @Override
139 public String toString() {
140 Map<Resource,String> m = new HashMap<Resource,String>();
141 for (Resource r : all)
142 m.put(r,"R");
143 for (Entry<Resource,Integer> e : write.entrySet())
144 m.put(e.getKey(),"W"+e.getValue());
145 return m.toString();
146 }
147
148 /**
149 * {@link Integer} unbox operation that treats null as 0.
150 */
151 private static int unbox(Integer x) {
152 return x==null ? 0 : x;
153 }
154
155 /**
156 * Empty resource list.
157 */
158 public static final ResourceList EMPTY = new ResourceList();
159 }
160