1818
1919package org .apache .hadoop .fs .impl ;
2020
21- import java .util .Collections ;
21+ import java .util .EnumSet ;
2222import java .util .Map ;
23+ import java .util .Objects ;
2324import java .util .Set ;
2425import java .util .concurrent .atomic .AtomicBoolean ;
2526import java .util .stream .Collectors ;
2627
2728import org .apache .hadoop .conf .Configuration ;
2829import org .apache .hadoop .fs .StreamCapabilities ;
30+ import org .apache .hadoop .util .ConfigurationHelper ;
2931import org .apache .hadoop .util .Preconditions ;
3032
31- import static java .util .Objects .requireNonNull ;
32- import static org .apache .hadoop .util .ConfigurationUtil .mapEnumNamesToValues ;
33+ import static org .apache .hadoop .util .ConfigurationHelper .mapEnumNamesToValues ;
3334
3435/**
3536 * A set of flags, constructed from a configuration option or from a string,
3637 * with the semantics of
37- * {@link org.apache.hadoop.util.ConfigurationUtil #parseEnumSet(String, String, Class, boolean)}
38+ * {@link ConfigurationHelper #parseEnumSet(String, String, Class, boolean)}
3839 * and implementing {@link StreamCapabilities}.
39- * Once declared immutable, flags cannot be changed .
40- * While mutable, all getters and setters are synchronized , so
41- * an instance is always thread-safe.
40+ * Thread safety: there is no synchronization on a mutable {@code FlagSet} .
41+ * Once declared immutable, flags cannot be changed , so they
42+ * becomes implicitly thread-safe.
4243 */
4344public final class FlagSet <E extends Enum <E >> implements StreamCapabilities {
4445
@@ -61,10 +62,10 @@ public final class FlagSet<E extends Enum<E>> implements StreamCapabilities {
6162 * Create a FlagSet.
6263 * @param enumClass class of enum
6364 * @param prefix prefix (with trailing ".") for path capabilities probe
64- * @param flags flags
65+ * @param flags flags. A copy of these are made.
6566 */
66- private FlagSet (final Class <E > enumClass , final String prefix , final Set <E > flags ) {
67- this .flags = requireNonNull (flags );
67+ private FlagSet (final Class <E > enumClass , final String prefix , final EnumSet <E > flags ) {
68+ this .flags = EnumSet . copyOf (flags );
6869 this .namesToValues = mapEnumNamesToValues (prefix , enumClass );
6970 }
7071
@@ -73,16 +74,24 @@ private FlagSet(final Class<E> enumClass, final String prefix, final Set<E> flag
7374 * This is immutable.
7475 * @return the flags.
7576 */
76- public synchronized Set <E > flags () {
77- return Collections .unmodifiableSet (flags );
77+ public EnumSet <E > flags () {
78+ return EnumSet .copyOf (flags );
79+ }
80+
81+ /**
82+ * Probe for the FlagSet being empty.
83+ * @return true if there are no flags set.
84+ */
85+ public boolean isEmpty () {
86+ return flags .isEmpty ();
7887 }
7988
8089 /**
8190 * Is a flag enabled?
8291 * @param flag flag to check
8392 * @return true if it is in the set of enabled flags.
8493 */
85- public synchronized boolean enabled (final E flag ) {
94+ public boolean enabled (final E flag ) {
8695 return flags .contains (flag );
8796 }
8897
@@ -98,7 +107,7 @@ private void checkMutable() {
98107 * Enable a flag.
99108 * @param flag flag to enable.
100109 */
101- public synchronized void enable (final E flag ) {
110+ public void enable (final E flag ) {
102111 checkMutable ();
103112 flags .add (flag );
104113 }
@@ -107,7 +116,7 @@ public synchronized void enable(final E flag) {
107116 * Disable a flag.
108117 * @param flag flag to disable
109118 */
110- public synchronized void disable (final E flag ) {
119+ public void disable (final E flag ) {
111120 checkMutable ();
112121 flags .remove (flag );
113122 }
@@ -140,7 +149,7 @@ public boolean hasCapability(final String capability) {
140149 /**
141150 * Make immutable; no-op if already set.
142151 */
143- public synchronized void makeImmutable () {
152+ public void makeImmutable () {
144153 immutable .set (true );
145154 }
146155
@@ -153,18 +162,51 @@ public String toString() {
153162 + '}' ;
154163 }
155164
165+ /**
166+ * Equality is based on the set.
167+ * @param o
168+ * @return
169+ */
170+ @ Override
171+ public boolean equals (final Object o ) {
172+ if (this == o ) {return true ;}
173+ if (o == null || getClass () != o .getClass ()) {return false ;}
174+ FlagSet <?> flagSet = (FlagSet <?>) o ;
175+ return Objects .equals (flags , flagSet .flags );
176+ }
177+
178+ /**
179+ * Hash code is based on the flags.
180+ * @return a hash code.
181+ */
182+ @ Override
183+ public int hashCode () {
184+ return Objects .hashCode (flags );
185+ }
186+
187+ /**
188+ * Convert to a string which can be then set in a configuration.
189+ * This is effectively a marshalled form of the flags.
190+ * @return a comma separated list of flag names.
191+ */
192+ public String toConfigurationString () {
193+ return flags .stream ()
194+ .map (e -> e .name ())
195+ .collect (Collectors .joining (", " ));
196+ }
197+
156198 /**
157199 * Create a FlagSet.
158200 * @param enumClass class of enum
159201 * @param prefix prefix (with trailing ".") for path capabilities probe
160202 * @param flags flags
161- * @return a FlagSet
162203 * @param <E> enum type
204+ * @return a mutable FlagSet
163205 */
164- public static <E extends Enum <E >> FlagSet <E > createFlagSet (
206+ public static <E extends Enum <E >> FlagSet <E > createFlagSet (
165207 final Class <E > enumClass ,
166208 final String prefix ,
167- final Set <E > flags ) {
209+ final EnumSet <E > flags ) {
168210 return new FlagSet <>(enumClass , prefix , flags );
169211 }
170212
@@ -176,17 +218,17 @@ public static <E extends Enum<E>> FlagSet<E> createFlagSet(
176218 * @param conf configuration
177219 * @param key key to look for
178220 * @param ignoreUnknown should unknown values raise an exception?
179- * @return a FlagSet
180221 * @param <E> enumeration type
222+ * @return a mutable FlagSet
181223 * @throws IllegalArgumentException if one of the entries was unknown and ignoreUnknown is false,
182- * or there are two entries in the enum which differ only by case.
224+ * or there are two entries in the enum which differ only by case.
183225 */
184- public static <E extends Enum <E >> FlagSet <E > buildFlagSet (
226+ public static <E extends Enum <E >> FlagSet <E > buildFlagSet (
185227 final Class <E > enumClass ,
186228 final Configuration conf ,
187229 final String key ,
188230 final boolean ignoreUnknown ) {
189- final Set <E > flags = conf .getEnumSet (key , enumClass , ignoreUnknown );
231+ final EnumSet <E > flags = conf .getEnumSet (key , enumClass , ignoreUnknown );
190232 return createFlagSet (enumClass , key + "." , flags );
191233 }
192234
0 commit comments