20
20
import static org .apache .hadoop .hdds .scm .exceptions .SCMException .ResultCodes .FAILED_TO_CHANGE_CONTAINER_STATE ;
21
21
22
22
import com .google .common .collect .ImmutableMap ;
23
- import com .google .common .collect .ImmutableSortedSet ;
24
23
import com .google .common .collect .Maps ;
24
+ import java .util .ArrayList ;
25
25
import java .util .EnumMap ;
26
- import java .util .NavigableSet ;
26
+ import java .util .List ;
27
+ import java .util .NavigableMap ;
27
28
import java .util .Objects ;
28
- import java .util .SortedSet ;
29
- import java .util .TreeSet ;
29
+ import java .util .SortedMap ;
30
+ import java .util .TreeMap ;
30
31
import org .apache .hadoop .hdds .scm .container .ContainerID ;
32
+ import org .apache .hadoop .hdds .scm .container .ContainerInfo ;
31
33
import org .apache .hadoop .hdds .scm .exceptions .SCMException ;
32
- import org .slf4j .Logger ;
33
- import org .slf4j .LoggerFactory ;
34
+ import org .apache .ratis .util .Preconditions ;
34
35
35
36
/**
36
37
* Each Attribute that we manage for a container is maintained as a map.
60
61
* @param <T> Attribute type
61
62
*/
62
63
public class ContainerAttribute <T extends Enum <T >> {
63
- private static final Logger LOG =
64
- LoggerFactory .getLogger (ContainerAttribute .class );
65
-
66
64
private final Class <T > attributeClass ;
67
- private final ImmutableMap <T , NavigableSet <ContainerID >> attributeMap ;
65
+ private final ImmutableMap <T , NavigableMap <ContainerID , ContainerInfo >> attributeMap ;
68
66
69
67
/**
70
68
* Create an empty Container Attribute map.
71
69
*/
72
70
public ContainerAttribute (Class <T > attributeClass ) {
73
71
this .attributeClass = attributeClass ;
74
72
75
- final EnumMap <T , NavigableSet <ContainerID >> map = new EnumMap <>(attributeClass );
73
+ final EnumMap <T , NavigableMap <ContainerID , ContainerInfo >> map = new EnumMap <>(attributeClass );
76
74
for (T t : attributeClass .getEnumConstants ()) {
77
- map .put (t , new TreeSet <>());
75
+ map .put (t , new TreeMap <>());
78
76
}
79
77
this .attributeMap = Maps .immutableEnumMap (map );
80
78
}
81
79
82
80
/**
83
- * Insert the value in the Attribute map, keep the original value if it exists
84
- * already.
85
- *
86
- * @param key - The key to the set where the ContainerID should exist.
87
- * @param value - Actual Container ID.
88
- * @return true if the value is added;
89
- * otherwise, the value already exists, return false.
81
+ * Add the given non-existing {@link ContainerInfo} to this attribute.
82
+ * @throws IllegalStateException if it already exists.
90
83
*/
91
- public boolean insert (T key , ContainerID value ) {
92
- Objects .requireNonNull (value , "value == null" );
93
- return get (key ).add (value );
84
+ public void addNonExisting (T key , ContainerInfo info ) {
85
+ Objects .requireNonNull (info , "value == null" );
86
+ final ContainerInfo previous = get (key ).put (info .containerID (), info );
87
+ Preconditions .assertNull (previous , "previous" );
94
88
}
95
89
96
90
/**
@@ -103,30 +97,30 @@ public void clearSet(T key) {
103
97
}
104
98
105
99
/**
106
- * Removes a container ID from the set pointed by the key.
107
- *
108
- * @param key - key to identify the set.
109
- * @param value - Container ID
100
+ * Remove a container for the given id.
101
+ * @return the info if there was a mapping for the id; otherwise, return null
110
102
*/
111
- public boolean remove (T key , ContainerID value ) {
112
- Objects .requireNonNull (value , "value == null" );
103
+ public ContainerInfo remove (T key , ContainerID id ) {
104
+ Objects .requireNonNull (id , "id == null" );
105
+ return get (key ).remove (id );
106
+ }
113
107
114
- if (! get ( key ). remove ( value )) {
115
- LOG . debug ( "Container {} not found in {} attribute" , value , key );
116
- return false ;
117
- }
118
- return true ;
108
+ /** Remove an existing {@link ContainerInfo}. */
109
+ public void removeExisting ( T key , ContainerInfo existing ) {
110
+ Objects . requireNonNull ( existing , "existing == null" ) ;
111
+ final ContainerInfo removed = remove ( key , existing . containerID ());
112
+ Preconditions . assertSame ( existing , removed , "removed" ) ;
119
113
}
120
114
121
- NavigableSet <ContainerID > get (T attribute ) {
115
+ NavigableMap <ContainerID , ContainerInfo > get (T attribute ) {
122
116
Objects .requireNonNull (attribute , "attribute == null" );
123
117
124
- final NavigableSet <ContainerID > set = attributeMap .get (attribute );
125
- if (set == null ) {
118
+ final NavigableMap <ContainerID , ContainerInfo > map = attributeMap .get (attribute );
119
+ if (map == null ) {
126
120
throw new IllegalStateException ("Attribute not found: " + attribute
127
121
+ " (" + attributeClass .getSimpleName () + ")" );
128
122
}
129
- return set ;
123
+ return map ;
130
124
}
131
125
132
126
/**
@@ -135,13 +129,13 @@ NavigableSet<ContainerID> get(T attribute) {
135
129
* @param key - Key to the bucket.
136
130
* @return Underlying Set in immutable form.
137
131
*/
138
- public NavigableSet < ContainerID > getCollection (T key ) {
139
- return ImmutableSortedSet . copyOf (get (key ));
132
+ public List < ContainerInfo > getCollection (T key ) {
133
+ return new ArrayList <> (get (key ). values ( ));
140
134
}
141
135
142
- public SortedSet <ContainerID > tailSet (T key , ContainerID start ) {
136
+ public SortedMap <ContainerID , ContainerInfo > tailMap (T key , ContainerID start ) {
143
137
Objects .requireNonNull (start , "start == null" );
144
- return get (key ).tailSet (start );
138
+ return get (key ).tailMap (start );
145
139
}
146
140
147
141
public int count (T key ) {
@@ -163,17 +157,13 @@ public void update(T currentKey, T newKey, ContainerID value)
163
157
}
164
158
165
159
Objects .requireNonNull (newKey , "newKey == null" );
166
- final boolean removed = remove (currentKey , value );
167
- if (! removed ) {
160
+ final ContainerInfo removed = remove (currentKey , value );
161
+ if (removed == null ) {
168
162
throw new SCMException ("Failed to update Container " + value + " from " + currentKey + " to " + newKey
169
163
+ ": Container " + value + " not found in attribute " + currentKey ,
170
164
FAILED_TO_CHANGE_CONTAINER_STATE );
171
165
}
172
166
173
- final boolean inserted = insert (newKey , value );
174
- if (!inserted ) {
175
- LOG .warn ("Update Container {} from {} to {}: Container {} already exists in {}" ,
176
- value , currentKey , newKey , value , newKey );
177
- }
167
+ addNonExisting (newKey , removed );
178
168
}
179
169
}
0 commit comments