View Javadoc
1   /*
2    * Copyright 2014 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at:
7    *
8    * https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  package io.netty.handler.codec;
16  
17  import io.netty.util.HashingStrategy;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.Collections;
22  import java.util.Iterator;
23  import java.util.LinkedHashSet;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Map.Entry;
27  import java.util.NoSuchElementException;
28  import java.util.Set;
29  import java.util.function.BiPredicate;
30  
31  import static io.netty.util.HashingStrategy.JAVA_HASHER;
32  import static io.netty.util.internal.MathUtil.findNextPositivePowerOfTwo;
33  import static io.netty.util.internal.ObjectUtil.checkNotNull;
34  import static java.lang.Math.max;
35  import static java.lang.Math.min;
36  
37  /**
38   * Default implementation of {@link Headers};
39   *
40   * @param <K> the type of the header name.
41   * @param <V> the type of the header value.
42   * @param <T> the type to use for return values when the intention is to return {@code this} object.
43   */
44  public class DefaultHeaders<K, V, T extends Headers<K, V, T>> implements Headers<K, V, T> {
45      /**
46       * Constant used to seed the hash code generation. Could be anything but this was borrowed from murmur3.
47       */
48      static final int HASH_CODE_SEED = 0xc2b2ae35;
49  
50      private final HeaderEntry<K, V>[] entries;
51      protected final HeaderEntry<K, V> head;
52  
53      private final byte hashMask;
54      private final ValueConverter<V> valueConverter;
55      private final NameValidator<K> nameValidator;
56      private final ValueValidator<V> valueValidator;
57      private final HashingStrategy<K> hashingStrategy;
58      int size;
59  
60      public interface NameValidator<K> {
61          /**
62           * Verify that {@code name} is valid.
63           * @param name The name to validate.
64           * @throws RuntimeException if {@code name} is not valid.
65           */
66          void validateName(K name);
67  
68          @SuppressWarnings("rawtypes")
69          NameValidator NOT_NULL = new NameValidator() {
70              @Override
71              public void validateName(Object name) {
72                  checkNotNull(name, "name");
73              }
74          };
75      }
76  
77      public interface ValueValidator<V> {
78          /**
79           * Validate the given value. If the validation fails, then an implementation specific runtime exception may be
80           * thrown.
81           *
82           * @param value The value to validate.
83           */
84          void validate(V value);
85  
86          ValueValidator<?> NO_VALIDATION = new ValueValidator<Object>() {
87              @Override
88              public void validate(Object value) {
89              }
90          };
91      }
92  
93      @SuppressWarnings("unchecked")
94      public DefaultHeaders(ValueConverter<V> valueConverter) {
95          this(JAVA_HASHER, valueConverter);
96      }
97  
98      @SuppressWarnings("unchecked")
99      public DefaultHeaders(ValueConverter<V> valueConverter, NameValidator<K> nameValidator) {
100         this(JAVA_HASHER, valueConverter, nameValidator);
101     }
102 
103     @SuppressWarnings("unchecked")
104     public DefaultHeaders(HashingStrategy<K> nameHashingStrategy, ValueConverter<V> valueConverter) {
105         this(nameHashingStrategy, valueConverter, NameValidator.NOT_NULL);
106     }
107 
108     public DefaultHeaders(HashingStrategy<K> nameHashingStrategy,
109             ValueConverter<V> valueConverter, NameValidator<K> nameValidator) {
110         this(nameHashingStrategy, valueConverter, nameValidator, 16);
111     }
112 
113     /**
114      * Create a new instance.
115      * @param nameHashingStrategy Used to hash and equality compare names.
116      * @param valueConverter Used to convert values to/from native types.
117      * @param nameValidator Used to validate name elements.
118      * @param arraySizeHint A hint as to how large the hash data structure should be.
119      * The next positive power of two will be used. An upper bound may be enforced.
120      */
121     @SuppressWarnings("unchecked")
122     public DefaultHeaders(HashingStrategy<K> nameHashingStrategy,
123                           ValueConverter<V> valueConverter, NameValidator<K> nameValidator, int arraySizeHint) {
124         this(nameHashingStrategy, valueConverter, nameValidator, arraySizeHint,
125                 (ValueValidator<V>) ValueValidator.NO_VALIDATION);
126     }
127 
128     /**
129      * Create a new instance.
130      * @param nameHashingStrategy Used to hash and equality compare names.
131      * @param valueConverter Used to convert values to/from native types.
132      * @param nameValidator Used to validate name elements.
133      * @param arraySizeHint A hint as to how large the hash data structure should be.
134      * The next positive power of two will be used. An upper bound may be enforced.
135      * @param valueValidator The validation strategy for entry values.
136      */
137     @SuppressWarnings("unchecked")
138     public DefaultHeaders(HashingStrategy<K> nameHashingStrategy, ValueConverter<V> valueConverter,
139                           NameValidator<K> nameValidator, int arraySizeHint, ValueValidator<V> valueValidator) {
140         this.valueConverter = checkNotNull(valueConverter, "valueConverter");
141         this.nameValidator = checkNotNull(nameValidator, "nameValidator");
142         hashingStrategy = checkNotNull(nameHashingStrategy, "nameHashingStrategy");
143         this.valueValidator = checkNotNull(valueValidator, "valueValidator");
144         // Enforce a bound of [2, 128] because hashMask is a byte. The max possible value of hashMask is one less
145         // than the length of this array, and we want the mask to be > 0.
146         entries = new HeaderEntry[findNextPositivePowerOfTwo(max(2, min(arraySizeHint, 128)))];
147         hashMask = (byte) (entries.length - 1);
148         head = new HeaderEntry<K, V>();
149     }
150 
151     /**
152      * Returns {@code true} if there exists a header with the given {@code name} for which the
153      * supplied {@code valuePredicate} returns {@code true} when invoked with the stored header
154      * value as the first argument and {@code predicateArg} as the second argument.
155      * <p>
156      * Matching is performed by invoking {@code valuePredicate.test(storedValue, predicateArg)}
157      * on each stored header value for {@code name}.
158      *
159      * @param name           the header name to search for (must not be {@code null})
160      * @param predicateArg   argument passed as the second parameter to {@code valuePredicate} (may be {@code null})
161      * @param valuePredicate predicate used to test stored header values (must not be {@code null})
162      */
163     public boolean containsAny(K name, V predicateArg, BiPredicate<? super V, ? super V> valuePredicate) {
164         checkNotNull(name, "name");
165         checkNotNull(valuePredicate, "valuePredicate");
166         int h = hashingStrategy.hashCode(name);
167         int i = index(h);
168         HeaderEntry<K, V> e = entries[i];
169         while (e != null) {
170             if (e.hash == h && hashingStrategy.equals(name, e.key) && valuePredicate.test(e.value, predicateArg)) {
171                 return true;
172             }
173             e = e.next;
174         }
175         return false;
176     }
177 
178     @Override
179     public V get(K name) {
180         checkNotNull(name, "name");
181 
182         int h = hashingStrategy.hashCode(name);
183         int i = index(h);
184         HeaderEntry<K, V> e = entries[i];
185         V value = null;
186         // loop until the first header was found
187         while (e != null) {
188             if (e.hash == h && hashingStrategy.equals(name, e.key)) {
189                 value = e.value;
190             }
191 
192             e = e.next;
193         }
194         return value;
195     }
196 
197     @Override
198     public V get(K name, V defaultValue) {
199         V value = get(name);
200         if (value == null) {
201             return defaultValue;
202         }
203         return value;
204     }
205 
206     @Override
207     public V getAndRemove(K name) {
208         int h = hashingStrategy.hashCode(name);
209         return remove0(h, index(h), checkNotNull(name, "name"));
210     }
211 
212     @Override
213     public V getAndRemove(K name, V defaultValue) {
214         V value = getAndRemove(name);
215         if (value == null) {
216             return defaultValue;
217         }
218         return value;
219     }
220 
221     @Override
222     public List<V> getAll(K name) {
223         checkNotNull(name, "name");
224 
225         int h = hashingStrategy.hashCode(name);
226         int i = index(h);
227 
228         ArrayList<V> values = null;
229         V value = null;
230         HeaderEntry<K, V> e = entries[i];
231         while (e != null) {
232             if (e.hash == h && hashingStrategy.equals(name, e.key)) {
233                 if (value == null) {
234                     value = e.getValue();
235                 } else {
236                     if (values == null) {
237                         values = new ArrayList<>(2);
238                         values.add(value);
239                     }
240                     values.add(e.getValue());
241                 }
242             }
243             e = e.next;
244         }
245 
246         if (values == null) {
247             if (value == null) {
248                 return Collections.emptyList();
249             }
250             return Collections.singletonList(value);
251         }
252 
253         assert values.size() > 1;
254         Collections.reverse(values);
255 
256         return values;
257     }
258 
259     /**
260      * Equivalent to {@link #getAll(Object)} but no intermediate list is generated.
261      * @param name the name of the header to retrieve
262      * @return an {@link Iterator} of header values corresponding to {@code name}.
263      */
264     public Iterator<V> valueIterator(K name) {
265         return new ValueIterator(name);
266     }
267 
268     @Override
269     public List<V> getAllAndRemove(K name) {
270         List<V> all = getAll(name);
271         remove(name);
272         return all;
273     }
274 
275     @Override
276     public boolean contains(K name) {
277         return get(name) != null;
278     }
279 
280     @Override
281     public boolean containsObject(K name, Object value) {
282         return contains(name, fromObject(name, value));
283     }
284 
285     @Override
286     public boolean containsBoolean(K name, boolean value) {
287         return contains(name, fromBoolean(name, value));
288     }
289 
290     @Override
291     public boolean containsByte(K name, byte value) {
292         return contains(name, fromByte(name, value));
293     }
294 
295     @Override
296     public boolean containsChar(K name, char value) {
297         return contains(name, fromChar(name, value));
298     }
299 
300     @Override
301     public boolean containsShort(K name, short value) {
302         return contains(name, fromShort(name, value));
303     }
304 
305     @Override
306     public boolean containsInt(K name, int value) {
307         return contains(name, fromInt(name, value));
308     }
309 
310     @Override
311     public boolean containsLong(K name, long value) {
312         return contains(name, fromLong(name, value));
313     }
314 
315     @Override
316     public boolean containsFloat(K name, float value) {
317         return contains(name, fromFloat(name, value));
318     }
319 
320     @Override
321     public boolean containsDouble(K name, double value) {
322         return contains(name, fromDouble(name, value));
323     }
324 
325     @Override
326     public boolean containsTimeMillis(K name, long value) {
327         return contains(name, fromTimeMillis(name, value));
328     }
329 
330     @SuppressWarnings("unchecked")
331     @Override
332     public boolean contains(K name, V value) {
333         return contains(name, value, JAVA_HASHER);
334     }
335 
336     public final boolean contains(K name, V value, HashingStrategy<? super V> valueHashingStrategy) {
337         checkNotNull(name, "name");
338 
339         int h = hashingStrategy.hashCode(name);
340         int i = index(h);
341         HeaderEntry<K, V> e = entries[i];
342         while (e != null) {
343             if (e.hash == h && hashingStrategy.equals(name, e.key) && valueHashingStrategy.equals(value, e.value)) {
344                 return true;
345             }
346             e = e.next;
347         }
348         return false;
349     }
350 
351     @Override
352     public int size() {
353         return size;
354     }
355 
356     @Override
357     public boolean isEmpty() {
358         return head == head.after;
359     }
360 
361     @Override
362     public Set<K> names() {
363         if (isEmpty()) {
364             return Collections.emptySet();
365         }
366         Set<K> names = new LinkedHashSet<K>(size());
367         HeaderEntry<K, V> e = head.after;
368         while (e != head) {
369             names.add(e.getKey());
370             e = e.after;
371         }
372         return names;
373     }
374 
375     @Override
376     public T add(K name, V value) {
377         validateName(nameValidator, true, name);
378         validateValue(valueValidator, name, value);
379         checkNotNull(value, "value");
380         int h = hashingStrategy.hashCode(name);
381         int i = index(h);
382         add0(h, i, name, value);
383         return thisT();
384     }
385 
386     @Override
387     public T add(K name, Iterable<? extends V> values) {
388         validateName(nameValidator, true, name);
389         int h = hashingStrategy.hashCode(name);
390         int i = index(h);
391         for (V v: values) {
392             validateValue(valueValidator, name, v);
393             add0(h, i, name, v);
394         }
395         return thisT();
396     }
397 
398     @Override
399     public T add(K name, V... values) {
400         validateName(nameValidator, true, name);
401         int h = hashingStrategy.hashCode(name);
402         int i = index(h);
403         for (V v: values) {
404             validateValue(valueValidator, name, v);
405             add0(h, i, name, v);
406         }
407         return thisT();
408     }
409 
410     @Override
411     public T addObject(K name, Object value) {
412         return add(name, fromObject(name, value));
413     }
414 
415     @Override
416     public T addObject(K name, Iterable<?> values) {
417         for (Object value : values) {
418             addObject(name, value);
419         }
420         return thisT();
421     }
422 
423     @Override
424     public T addObject(K name, Object... values) {
425         for (Object value: values) {
426             addObject(name, value);
427         }
428         return thisT();
429     }
430 
431     @Override
432     public T addInt(K name, int value) {
433         return add(name, fromInt(name, value));
434     }
435 
436     @Override
437     public T addLong(K name, long value) {
438         return add(name, fromLong(name, value));
439     }
440 
441     @Override
442     public T addDouble(K name, double value) {
443         return add(name, fromDouble(name, value));
444     }
445 
446     @Override
447     public T addTimeMillis(K name, long value) {
448         return add(name, fromTimeMillis(name, value));
449     }
450 
451     @Override
452     public T addChar(K name, char value) {
453         return add(name, fromChar(name, value));
454     }
455 
456     @Override
457     public T addBoolean(K name, boolean value) {
458         return add(name, fromBoolean(name, value));
459     }
460 
461     @Override
462     public T addFloat(K name, float value) {
463         return add(name, fromFloat(name, value));
464     }
465 
466     @Override
467     public T addByte(K name, byte value) {
468         return add(name, fromByte(name, value));
469     }
470 
471     @Override
472     public T addShort(K name, short value) {
473         return add(name, fromShort(name, value));
474     }
475 
476     @Override
477     public T add(Headers<? extends K, ? extends V, ?> headers) {
478         if (headers == this) {
479             throw new IllegalArgumentException("can't add to itself.");
480         }
481         addImpl(headers);
482         return thisT();
483     }
484 
485     protected void addImpl(Headers<? extends K, ? extends V, ?> headers) {
486         if (headers instanceof DefaultHeaders) {
487             @SuppressWarnings("unchecked")
488             final DefaultHeaders<? extends K, ? extends V, T> defaultHeaders =
489                     (DefaultHeaders<? extends K, ? extends V, T>) headers;
490             HeaderEntry<? extends K, ? extends V> e = defaultHeaders.head.after;
491             if (defaultHeaders.hashingStrategy == hashingStrategy &&
492                     defaultHeaders.nameValidator == nameValidator) {
493                 // Fastest copy
494                 while (e != defaultHeaders.head) {
495                     add0(e.hash, index(e.hash), e.key, e.value);
496                     e = e.after;
497                 }
498             } else {
499                 // Fast copy
500                 while (e != defaultHeaders.head) {
501                     add(e.key, e.value);
502                     e = e.after;
503                 }
504             }
505         } else {
506             // Slow copy
507             for (Entry<? extends K, ? extends V> header : headers) {
508                 add(header.getKey(), header.getValue());
509             }
510         }
511     }
512 
513     @Override
514     public T set(K name, V value) {
515         validateName(nameValidator, false, name);
516         validateValue(valueValidator, name, value);
517         checkNotNull(value, "value");
518         int h = hashingStrategy.hashCode(name);
519         int i = index(h);
520         remove0(h, i, name);
521         add0(h, i, name, value);
522         return thisT();
523     }
524 
525     @Override
526     public T set(K name, Iterable<? extends V> values) {
527         validateName(nameValidator, false, name);
528         checkNotNull(values, "values");
529 
530         int h = hashingStrategy.hashCode(name);
531         int i = index(h);
532 
533         remove0(h, i, name);
534         for (V v: values) {
535             if (v == null) {
536                 break;
537             }
538             validateValue(valueValidator, name, v);
539             add0(h, i, name, v);
540         }
541 
542         return thisT();
543     }
544 
545     @Override
546     public T set(K name, V... values) {
547         validateName(nameValidator, false, name);
548         checkNotNull(values, "values");
549 
550         int h = hashingStrategy.hashCode(name);
551         int i = index(h);
552 
553         remove0(h, i, name);
554         for (V v: values) {
555             if (v == null) {
556                 break;
557             }
558             validateValue(valueValidator, name, v);
559             add0(h, i, name, v);
560         }
561 
562         return thisT();
563     }
564 
565     @Override
566     public T setObject(K name, Object value) {
567         V convertedValue = checkNotNull(fromObject(name, value), "convertedValue");
568         return set(name, convertedValue);
569     }
570 
571     @Override
572     public T setObject(K name, Iterable<?> values) {
573         validateName(nameValidator, false, name);
574 
575         int h = hashingStrategy.hashCode(name);
576         int i = index(h);
577 
578         remove0(h, i, name);
579         for (Object v: values) {
580             if (v == null) {
581                 break;
582             }
583             V converted = fromObject(name, v);
584             validateValue(valueValidator, name, converted);
585             add0(h, i, name, converted);
586         }
587 
588         return thisT();
589     }
590 
591     @Override
592     public T setObject(K name, Object... values) {
593         validateName(nameValidator, false, name);
594 
595         int h = hashingStrategy.hashCode(name);
596         int i = index(h);
597 
598         remove0(h, i, name);
599         for (Object v: values) {
600             if (v == null) {
601                 break;
602             }
603             V converted = fromObject(name, v);
604             validateValue(valueValidator, name, converted);
605             add0(h, i, name, converted);
606         }
607 
608         return thisT();
609     }
610 
611     @Override
612     public T setInt(K name, int value) {
613         return set(name, fromInt(name, value));
614     }
615 
616     @Override
617     public T setLong(K name, long value) {
618         return set(name, fromLong(name, value));
619     }
620 
621     @Override
622     public T setDouble(K name, double value) {
623         return set(name, fromDouble(name, value));
624     }
625 
626     @Override
627     public T setTimeMillis(K name, long value) {
628         return set(name, fromTimeMillis(name, value));
629     }
630 
631     @Override
632     public T setFloat(K name, float value) {
633         return set(name, fromFloat(name, value));
634     }
635 
636     @Override
637     public T setChar(K name, char value) {
638         return set(name, fromChar(name, value));
639     }
640 
641     @Override
642     public T setBoolean(K name, boolean value) {
643         return set(name, fromBoolean(name, value));
644     }
645 
646     @Override
647     public T setByte(K name, byte value) {
648         return set(name, fromByte(name, value));
649     }
650 
651     @Override
652     public T setShort(K name, short value) {
653         return set(name, fromShort(name, value));
654     }
655 
656     @Override
657     public T set(Headers<? extends K, ? extends V, ?> headers) {
658         if (headers != this) {
659             clear();
660             addImpl(headers);
661         }
662         return thisT();
663     }
664 
665     @Override
666     public T setAll(Headers<? extends K, ? extends V, ?> headers) {
667         if (headers != this) {
668             for (K key : headers.names()) {
669                 remove(key);
670             }
671             addImpl(headers);
672         }
673         return thisT();
674     }
675 
676     @Override
677     public boolean remove(K name) {
678         return getAndRemove(name) != null;
679     }
680 
681     @Override
682     public T clear() {
683         Arrays.fill(entries, null);
684         head.before = head.after = head;
685         size = 0;
686         return thisT();
687     }
688 
689     @Override
690     public Iterator<Entry<K, V>> iterator() {
691         return new HeaderIterator();
692     }
693 
694     @Override
695     public Boolean getBoolean(K name) {
696         V v = get(name);
697         try {
698             return v != null ? toBoolean(name, v) : null;
699         } catch (RuntimeException ignore) {
700             return null;
701         }
702     }
703 
704     @Override
705     public boolean getBoolean(K name, boolean defaultValue) {
706         Boolean v = getBoolean(name);
707         return v != null ? v : defaultValue;
708     }
709 
710     @Override
711     public Byte getByte(K name) {
712         V v = get(name);
713         try {
714             return v != null ? toByte(name, v) : null;
715         } catch (RuntimeException ignore) {
716             return null;
717         }
718     }
719 
720     @Override
721     public byte getByte(K name, byte defaultValue) {
722         Byte v = getByte(name);
723         return v != null ? v : defaultValue;
724     }
725 
726     @Override
727     public Character getChar(K name) {
728         V v = get(name);
729         try {
730             return v != null ? toChar(name, v) : null;
731         } catch (RuntimeException ignore) {
732             return null;
733         }
734     }
735 
736     @Override
737     public char getChar(K name, char defaultValue) {
738         Character v = getChar(name);
739         return v != null ? v : defaultValue;
740     }
741 
742     @Override
743     public Short getShort(K name) {
744         V v = get(name);
745         try {
746             return v != null ? toShort(name, v) : null;
747         } catch (RuntimeException ignore) {
748             return null;
749         }
750     }
751 
752     @Override
753     public short getShort(K name, short defaultValue) {
754         Short v = getShort(name);
755         return v != null ? v : defaultValue;
756     }
757 
758     @Override
759     public Integer getInt(K name) {
760         V v = get(name);
761         try {
762             return v != null ? toInt(name, v) : null;
763         } catch (RuntimeException ignore) {
764             return null;
765         }
766     }
767 
768     @Override
769     public int getInt(K name, int defaultValue) {
770         Integer v = getInt(name);
771         return v != null ? v : defaultValue;
772     }
773 
774     @Override
775     public Long getLong(K name) {
776         V v = get(name);
777         try {
778             return v != null ? toLong(name, v) : null;
779         } catch (RuntimeException ignore) {
780             return null;
781         }
782     }
783 
784     @Override
785     public long getLong(K name, long defaultValue) {
786         Long v = getLong(name);
787         return v != null ? v : defaultValue;
788     }
789 
790     @Override
791     public Float getFloat(K name) {
792         V v = get(name);
793         try {
794             return v != null ? toFloat(name, v) : null;
795         } catch (RuntimeException ignore) {
796             return null;
797         }
798     }
799 
800     @Override
801     public float getFloat(K name, float defaultValue) {
802         Float v = getFloat(name);
803         return v != null ? v : defaultValue;
804     }
805 
806     @Override
807     public Double getDouble(K name) {
808         V v = get(name);
809         try {
810             return v != null ? toDouble(name, v) : null;
811         } catch (RuntimeException ignore) {
812             return null;
813         }
814     }
815 
816     @Override
817     public double getDouble(K name, double defaultValue) {
818         Double v = getDouble(name);
819         return v != null ? v : defaultValue;
820     }
821 
822     @Override
823     public Long getTimeMillis(K name) {
824         V v = get(name);
825         try {
826             return v != null ? toTimeMillis(name, v) : null;
827         } catch (RuntimeException ignore) {
828             return null;
829         }
830     }
831 
832     @Override
833     public long getTimeMillis(K name, long defaultValue) {
834         Long v = getTimeMillis(name);
835         return v != null ? v : defaultValue;
836     }
837 
838     @Override
839     public Boolean getBooleanAndRemove(K name) {
840         V v = getAndRemove(name);
841         try {
842             return v != null ? toBoolean(name, v) : null;
843         } catch (RuntimeException ignore) {
844             return null;
845         }
846     }
847 
848     @Override
849     public boolean getBooleanAndRemove(K name, boolean defaultValue) {
850         Boolean v = getBooleanAndRemove(name);
851         return v != null ? v : defaultValue;
852     }
853 
854     @Override
855     public Byte getByteAndRemove(K name) {
856         V v = getAndRemove(name);
857         try {
858             return v != null ? toByte(name, v) : null;
859         } catch (RuntimeException ignore) {
860             return null;
861         }
862     }
863 
864     @Override
865     public byte getByteAndRemove(K name, byte defaultValue) {
866         Byte v = getByteAndRemove(name);
867         return v != null ? v : defaultValue;
868     }
869 
870     @Override
871     public Character getCharAndRemove(K name) {
872         V v = getAndRemove(name);
873         try {
874             return v != null ? toChar(name, v) : null;
875         } catch (RuntimeException ignore) {
876             return null;
877         }
878     }
879 
880     @Override
881     public char getCharAndRemove(K name, char defaultValue) {
882         Character v = getCharAndRemove(name);
883         return v != null ? v : defaultValue;
884     }
885 
886     @Override
887     public Short getShortAndRemove(K name) {
888         V v = getAndRemove(name);
889         try {
890             return v != null ? toShort(name, v) : null;
891         } catch (RuntimeException ignore) {
892             return null;
893         }
894     }
895 
896     @Override
897     public short getShortAndRemove(K name, short defaultValue) {
898         Short v = getShortAndRemove(name);
899         return v != null ? v : defaultValue;
900     }
901 
902     @Override
903     public Integer getIntAndRemove(K name) {
904         V v = getAndRemove(name);
905         try {
906             return v != null ? toInt(name, v) : null;
907         } catch (RuntimeException ignore) {
908             return null;
909         }
910     }
911 
912     @Override
913     public int getIntAndRemove(K name, int defaultValue) {
914         Integer v = getIntAndRemove(name);
915         return v != null ? v : defaultValue;
916     }
917 
918     @Override
919     public Long getLongAndRemove(K name) {
920         V v = getAndRemove(name);
921         try {
922             return v != null ? toLong(name, v) : null;
923         } catch (RuntimeException ignore) {
924             return null;
925         }
926     }
927 
928     @Override
929     public long getLongAndRemove(K name, long defaultValue) {
930         Long v = getLongAndRemove(name);
931         return v != null ? v : defaultValue;
932     }
933 
934     @Override
935     public Float getFloatAndRemove(K name) {
936         V v = getAndRemove(name);
937         try {
938             return v != null ? toFloat(name, v) : null;
939         } catch (RuntimeException ignore) {
940             return null;
941         }
942     }
943 
944     @Override
945     public float getFloatAndRemove(K name, float defaultValue) {
946         Float v = getFloatAndRemove(name);
947         return v != null ? v : defaultValue;
948     }
949 
950     @Override
951     public Double getDoubleAndRemove(K name) {
952         V v = getAndRemove(name);
953         try {
954             return v != null ? toDouble(name, v) : null;
955         } catch (RuntimeException ignore) {
956             return null;
957         }
958     }
959 
960     @Override
961     public double getDoubleAndRemove(K name, double defaultValue) {
962         Double v = getDoubleAndRemove(name);
963         return v != null ? v : defaultValue;
964     }
965 
966     @Override
967     public Long getTimeMillisAndRemove(K name) {
968         V v = getAndRemove(name);
969         try {
970             return v != null ? toTimeMillis(name, v) : null;
971         } catch (RuntimeException ignore) {
972             return null;
973         }
974     }
975 
976     @Override
977     public long getTimeMillisAndRemove(K name, long defaultValue) {
978         Long v = getTimeMillisAndRemove(name);
979         return v != null ? v : defaultValue;
980     }
981 
982     @SuppressWarnings("unchecked")
983     @Override
984     public boolean equals(Object o) {
985         if (!(o instanceof Headers)) {
986             return false;
987         }
988 
989         return equals((Headers<K, V, ?>) o, JAVA_HASHER);
990     }
991 
992     @SuppressWarnings("unchecked")
993     @Override
994     public int hashCode() {
995         return hashCode(JAVA_HASHER);
996     }
997 
998     /**
999      * Test this object for equality against {@code h2}.
1000      * @param h2 The object to check equality for.
1001      * @param valueHashingStrategy Defines how values will be compared for equality.
1002      * @return {@code true} if this object equals {@code h2} given {@code valueHashingStrategy}.
1003      * {@code false} otherwise.
1004      */
1005     public final boolean equals(Headers<K, V, ?> h2, HashingStrategy<V> valueHashingStrategy) {
1006         if (h2.size() != size()) {
1007             return false;
1008         }
1009 
1010         if (this == h2) {
1011             return true;
1012         }
1013 
1014         for (K name : names()) {
1015             List<V> otherValues = h2.getAll(name);
1016             List<V> values = getAll(name);
1017             if (otherValues.size() != values.size()) {
1018                 return false;
1019             }
1020             for (int i = 0; i < otherValues.size(); i++) {
1021                 if (!valueHashingStrategy.equals(otherValues.get(i), values.get(i))) {
1022                     return false;
1023                 }
1024             }
1025         }
1026         return true;
1027     }
1028 
1029     /**
1030      * Generate a hash code for this object given a {@link HashingStrategy} to generate hash codes for
1031      * individual values.
1032      * @param valueHashingStrategy Defines how values will be hashed.
1033      */
1034     public final int hashCode(HashingStrategy<V> valueHashingStrategy) {
1035         int result = HASH_CODE_SEED;
1036         for (K name : names()) {
1037             result = 31 * result + hashingStrategy.hashCode(name);
1038             List<V> values = getAll(name);
1039             for (int i = 0; i < values.size(); ++i) {
1040                 result = 31 * result + valueHashingStrategy.hashCode(values.get(i));
1041             }
1042         }
1043         return result;
1044     }
1045 
1046     @Override
1047     public String toString() {
1048         return HeadersUtils.toString(getClass(), iterator(), size());
1049     }
1050 
1051     /**
1052      * Call out to the given {@link NameValidator} to validate the given name.
1053      *
1054      * @param validator the validator to use
1055      * @param forAdd {@code true } if this validation is for adding to the headers, or {@code false} if this is for
1056      * setting (overwriting) the given header.
1057      * @param name the name to validate.
1058      */
1059     protected void validateName(NameValidator<K> validator, boolean forAdd, K name) {
1060         validator.validateName(name);
1061     }
1062 
1063     protected void validateValue(ValueValidator<V> validator, K name, V value) {
1064         try {
1065             validator.validate(value);
1066         } catch (IllegalArgumentException e) {
1067             throw new IllegalArgumentException("Validation failed for header '" + name + "'", e);
1068         }
1069     }
1070 
1071     protected HeaderEntry<K, V> newHeaderEntry(int h, K name, V value, HeaderEntry<K, V> next) {
1072         return new HeaderEntry<K, V>(h, name, value, next, head);
1073     }
1074 
1075     protected ValueConverter<V> valueConverter() {
1076         return valueConverter;
1077     }
1078 
1079     protected NameValidator<K> nameValidator() {
1080         return nameValidator;
1081     }
1082 
1083     protected ValueValidator<V> valueValidator() {
1084         return valueValidator;
1085     }
1086 
1087     private int index(int hash) {
1088         return hash & hashMask;
1089     }
1090 
1091     private void add0(int h, int i, K name, V value) {
1092         // Update the hash table.
1093         entries[i] = newHeaderEntry(h, name, value, entries[i]);
1094         ++size;
1095     }
1096 
1097     /**
1098      * @return the first value inserted whose hash code equals {@code h} and whose name is equal to {@code name}.
1099      */
1100     private V remove0(int h, int i, K name) {
1101         HeaderEntry<K, V> e = entries[i];
1102         if (e == null) {
1103             return null;
1104         }
1105 
1106         V value = null;
1107         HeaderEntry<K, V> next = e.next;
1108         while (next != null) {
1109             if (next.hash == h && hashingStrategy.equals(name, next.key)) {
1110                 value = next.value;
1111                 e.next = next.next;
1112                 next.remove();
1113                 --size;
1114             } else {
1115                 e = next;
1116             }
1117 
1118             next = e.next;
1119         }
1120 
1121         e = entries[i];
1122         if (e.hash == h && hashingStrategy.equals(name, e.key)) {
1123             if (value == null) {
1124                 value = e.value;
1125             }
1126             entries[i] = e.next;
1127             e.remove();
1128             --size;
1129         }
1130 
1131         return value;
1132     }
1133 
1134     HeaderEntry<K, V> remove0(HeaderEntry<K, V> entry, HeaderEntry<K, V> previous) {
1135         int i = index(entry.hash);
1136         HeaderEntry<K, V> firstEntry = entries[i];
1137         if (firstEntry == entry) {
1138             entries[i] = entry.next;
1139             previous = entries[i];
1140         } else if (previous == null) {
1141             // If we don't have any existing starting point, then start from the beginning.
1142             previous = firstEntry;
1143             HeaderEntry<K, V> next = firstEntry.next;
1144             while (next != null && next != entry) {
1145                 previous = next;
1146                 next = next.next;
1147             }
1148             assert next != null: "Entry not found in its hash bucket: " + entry;
1149             previous.next = entry.next;
1150         } else {
1151             previous.next = entry.next;
1152         }
1153         entry.remove();
1154         --size;
1155         return previous;
1156     }
1157 
1158     @SuppressWarnings("unchecked")
1159     private T thisT() {
1160         return (T) this;
1161     }
1162 
1163     private V fromObject(K name, Object value) {
1164         try {
1165             return valueConverter.convertObject(checkNotNull(value, "value"));
1166         } catch (IllegalArgumentException e) {
1167             throw new IllegalArgumentException("Failed to convert object value for header '" + name + '\'', e);
1168         }
1169     }
1170 
1171     private V fromBoolean(K name, boolean value) {
1172         try {
1173             return valueConverter.convertBoolean(value);
1174         } catch (IllegalArgumentException e) {
1175             throw new IllegalArgumentException("Failed to convert boolean value for header '" + name + '\'', e);
1176         }
1177     }
1178 
1179     private V fromByte(K name, byte value) {
1180         try {
1181             return valueConverter.convertByte(value);
1182         } catch (IllegalArgumentException e) {
1183             throw new IllegalArgumentException("Failed to convert byte value for header '" + name + '\'', e);
1184         }
1185     }
1186 
1187     private V fromChar(K name, char value) {
1188         try {
1189             return valueConverter.convertChar(value);
1190         } catch (IllegalArgumentException e) {
1191             throw new IllegalArgumentException("Failed to convert char value for header '" + name + '\'', e);
1192         }
1193     }
1194 
1195     private V fromShort(K name, short value) {
1196         try {
1197             return valueConverter.convertShort(value);
1198         } catch (IllegalArgumentException e) {
1199             throw new IllegalArgumentException("Failed to convert short value for header '" + name + '\'', e);
1200         }
1201     }
1202 
1203     private V fromInt(K name, int value) {
1204         try {
1205             return valueConverter.convertInt(value);
1206         } catch (IllegalArgumentException e) {
1207             throw new IllegalArgumentException("Failed to convert int value for header '" + name + '\'', e);
1208         }
1209     }
1210 
1211     private V fromLong(K name, long value) {
1212         try {
1213             return valueConverter.convertLong(value);
1214         } catch (IllegalArgumentException e) {
1215             throw new IllegalArgumentException("Failed to convert long value for header '" + name + '\'', e);
1216         }
1217     }
1218 
1219     private V fromFloat(K name, float value) {
1220         try {
1221             return valueConverter.convertFloat(value);
1222         } catch (IllegalArgumentException e) {
1223             throw new IllegalArgumentException("Failed to convert float value for header '" + name + '\'', e);
1224         }
1225     }
1226 
1227     private V fromDouble(K name, double value) {
1228         try {
1229             return valueConverter.convertDouble(value);
1230         } catch (IllegalArgumentException e) {
1231             throw new IllegalArgumentException("Failed to convert double value for header '" + name + '\'', e);
1232         }
1233     }
1234 
1235     private V fromTimeMillis(K name, long value) {
1236         try {
1237             return valueConverter.convertTimeMillis(value);
1238         } catch (IllegalArgumentException e) {
1239             throw new IllegalArgumentException("Failed to convert millsecond value for header '" + name + '\'', e);
1240         }
1241     }
1242 
1243     private boolean toBoolean(K name, V value) {
1244         try {
1245             return valueConverter.convertToBoolean(value);
1246         } catch (IllegalArgumentException e) {
1247             throw new IllegalArgumentException("Failed to convert header value to boolean for header '" + name + '\'');
1248         }
1249     }
1250 
1251     private byte toByte(K name, V value) {
1252         try {
1253             return valueConverter.convertToByte(value);
1254         } catch (IllegalArgumentException e) {
1255             throw new IllegalArgumentException("Failed to convert header value to byte for header '" + name + '\'');
1256         }
1257     }
1258 
1259     private char toChar(K name, V value) {
1260         try {
1261             return valueConverter.convertToChar(value);
1262         } catch (IllegalArgumentException e) {
1263             throw new IllegalArgumentException("Failed to convert header value to char for header '" + name + '\'');
1264         }
1265     }
1266 
1267     private short toShort(K name, V value) {
1268         try {
1269             return valueConverter.convertToShort(value);
1270         } catch (IllegalArgumentException e) {
1271             throw new IllegalArgumentException("Failed to convert header value to short for header '" + name + '\'');
1272         }
1273     }
1274 
1275     private int toInt(K name, V value) {
1276         try {
1277             return valueConverter.convertToInt(value);
1278         } catch (IllegalArgumentException e) {
1279             throw new IllegalArgumentException("Failed to convert header value to int for header '" + name + '\'');
1280         }
1281     }
1282 
1283     private long toLong(K name, V value) {
1284         try {
1285             return valueConverter.convertToLong(value);
1286         } catch (IllegalArgumentException e) {
1287             throw new IllegalArgumentException("Failed to convert header value to long for header '" + name + '\'');
1288         }
1289     }
1290 
1291     private float toFloat(K name, V value) {
1292         try {
1293             return valueConverter.convertToFloat(value);
1294         } catch (IllegalArgumentException e) {
1295             throw new IllegalArgumentException("Failed to convert header value to float for header '" + name + '\'');
1296         }
1297     }
1298 
1299     private double toDouble(K name, V value) {
1300         try {
1301             return valueConverter.convertToDouble(value);
1302         } catch (IllegalArgumentException e) {
1303             throw new IllegalArgumentException("Failed to convert header value to double for header '" + name + '\'');
1304         }
1305     }
1306 
1307     private long toTimeMillis(K name, V value) {
1308         try {
1309             return valueConverter.convertToTimeMillis(value);
1310         } catch (IllegalArgumentException e) {
1311             throw new IllegalArgumentException(
1312                     "Failed to convert header value to millsecond for header '" + name + '\'');
1313         }
1314     }
1315 
1316     /**
1317      * Returns a deep copy of this instance.
1318      */
1319     public DefaultHeaders<K, V, T> copy() {
1320         DefaultHeaders<K, V, T> copy = new DefaultHeaders<K, V, T>(
1321                 hashingStrategy, valueConverter, nameValidator, entries.length);
1322         copy.addImpl(this);
1323         return copy;
1324     }
1325 
1326     private final class HeaderIterator implements Iterator<Entry<K, V>> {
1327         private HeaderEntry<K, V> current = head;
1328 
1329         @Override
1330         public boolean hasNext() {
1331             return current.after != head;
1332         }
1333 
1334         @Override
1335         public Entry<K, V> next() {
1336             current = current.after;
1337 
1338             if (current == head) {
1339                 throw new NoSuchElementException();
1340             }
1341 
1342             return current;
1343         }
1344 
1345         @Override
1346         public void remove() {
1347             throw new UnsupportedOperationException("read only");
1348         }
1349     }
1350 
1351     private final class ValueIterator implements Iterator<V> {
1352         private final K name;
1353         private final int hash;
1354         private HeaderEntry<K, V> removalPrevious;
1355         private HeaderEntry<K, V> previous;
1356         private HeaderEntry<K, V> next;
1357 
1358         ValueIterator(K name) {
1359             this.name = checkNotNull(name, "name");
1360             hash = hashingStrategy.hashCode(name);
1361             calculateNext(entries[index(hash)]);
1362         }
1363 
1364         @Override
1365         public boolean hasNext() {
1366             return next != null;
1367         }
1368 
1369         @Override
1370         public V next() {
1371             if (!hasNext()) {
1372                 throw new NoSuchElementException();
1373             }
1374             if (previous != null) {
1375                 removalPrevious = previous;
1376             }
1377             previous = next;
1378             calculateNext(next.next);
1379             return previous.value;
1380         }
1381 
1382         @Override
1383         public void remove() {
1384             if (previous == null) {
1385                 throw new IllegalStateException();
1386             }
1387             removalPrevious = remove0(previous, removalPrevious);
1388             previous = null;
1389         }
1390 
1391         private void calculateNext(HeaderEntry<K, V> entry) {
1392             while (entry != null) {
1393                 if (entry.hash == hash && hashingStrategy.equals(name, entry.key)) {
1394                     next = entry;
1395                     return;
1396                 }
1397                 entry = entry.next;
1398             }
1399             next = null;
1400         }
1401     }
1402 
1403     protected static class HeaderEntry<K, V> implements Entry<K, V> {
1404         protected final int hash;
1405         protected final K key;
1406         protected V value;
1407         /**
1408          * In bucket linked list
1409          */
1410         protected HeaderEntry<K, V> next;
1411         /**
1412          * Overall insertion order linked list
1413          */
1414         protected HeaderEntry<K, V> before, after;
1415 
1416         protected HeaderEntry(int hash, K key) {
1417             this.hash = hash;
1418             this.key = key;
1419         }
1420 
1421         HeaderEntry(int hash, K key, V value, HeaderEntry<K, V> next, HeaderEntry<K, V> head) {
1422             this.hash = hash;
1423             this.key = key;
1424             this.value = value;
1425             this.next = next;
1426 
1427             after = head;
1428             before = head.before;
1429             pointNeighborsToThis();
1430         }
1431 
1432         HeaderEntry() {
1433             hash = -1;
1434             key = null;
1435             before = after = this;
1436         }
1437 
1438         protected final void pointNeighborsToThis() {
1439             before.after = this;
1440             after.before = this;
1441         }
1442 
1443         public final HeaderEntry<K, V> before() {
1444             return before;
1445         }
1446 
1447         public final HeaderEntry<K, V> after() {
1448             return after;
1449         }
1450 
1451         protected void remove() {
1452             before.after = after;
1453             after.before = before;
1454         }
1455 
1456         @Override
1457         public final K getKey() {
1458             return key;
1459         }
1460 
1461         @Override
1462         public final V getValue() {
1463             return value;
1464         }
1465 
1466         @Override
1467         public final V setValue(V value) {
1468             checkNotNull(value, "value");
1469             V oldValue = this.value;
1470             this.value = value;
1471             return oldValue;
1472         }
1473 
1474         @Override
1475         public final String toString() {
1476             return key.toString() + '=' + value.toString();
1477         }
1478 
1479         @Override
1480         public boolean equals(Object o) {
1481             if (!(o instanceof Map.Entry)) {
1482                 return false;
1483             }
1484             Entry<?, ?> other = (Entry<?, ?>) o;
1485             return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey()))  &&
1486                    (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
1487         }
1488 
1489         @Override
1490         public int hashCode() {
1491             return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
1492         }
1493     }
1494 }