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                     defaultHeaders.valueValidator == valueValidator) {
494                 // Fastest copy. The entries of the other headers have been validated by the same validators that
495                 // we use, so there is no need to validate them again.
496                 while (e != defaultHeaders.head) {
497                     add0(e.hash, index(e.hash), e.key, e.value);
498                     e = e.after;
499                 }
500             } else {
501                 // Fast copy
502                 while (e != defaultHeaders.head) {
503                     add(e.key, e.value);
504                     e = e.after;
505                 }
506             }
507         } else {
508             // Slow copy
509             for (Entry<? extends K, ? extends V> header : headers) {
510                 add(header.getKey(), header.getValue());
511             }
512         }
513     }
514 
515     @Override
516     public T set(K name, V value) {
517         validateName(nameValidator, false, name);
518         validateValue(valueValidator, name, value);
519         checkNotNull(value, "value");
520         int h = hashingStrategy.hashCode(name);
521         int i = index(h);
522         remove0(h, i, name);
523         add0(h, i, name, value);
524         return thisT();
525     }
526 
527     @Override
528     public T set(K name, Iterable<? extends V> values) {
529         validateName(nameValidator, false, name);
530         checkNotNull(values, "values");
531 
532         int h = hashingStrategy.hashCode(name);
533         int i = index(h);
534 
535         remove0(h, i, name);
536         for (V v: values) {
537             if (v == null) {
538                 break;
539             }
540             validateValue(valueValidator, name, v);
541             add0(h, i, name, v);
542         }
543 
544         return thisT();
545     }
546 
547     @Override
548     public T set(K name, V... values) {
549         validateName(nameValidator, false, name);
550         checkNotNull(values, "values");
551 
552         int h = hashingStrategy.hashCode(name);
553         int i = index(h);
554 
555         remove0(h, i, name);
556         for (V v: values) {
557             if (v == null) {
558                 break;
559             }
560             validateValue(valueValidator, name, v);
561             add0(h, i, name, v);
562         }
563 
564         return thisT();
565     }
566 
567     @Override
568     public T setObject(K name, Object value) {
569         V convertedValue = checkNotNull(fromObject(name, value), "convertedValue");
570         return set(name, convertedValue);
571     }
572 
573     @Override
574     public T setObject(K name, Iterable<?> values) {
575         validateName(nameValidator, false, name);
576 
577         int h = hashingStrategy.hashCode(name);
578         int i = index(h);
579 
580         remove0(h, i, name);
581         for (Object v: values) {
582             if (v == null) {
583                 break;
584             }
585             V converted = fromObject(name, v);
586             validateValue(valueValidator, name, converted);
587             add0(h, i, name, converted);
588         }
589 
590         return thisT();
591     }
592 
593     @Override
594     public T setObject(K name, Object... values) {
595         validateName(nameValidator, false, name);
596 
597         int h = hashingStrategy.hashCode(name);
598         int i = index(h);
599 
600         remove0(h, i, name);
601         for (Object v: values) {
602             if (v == null) {
603                 break;
604             }
605             V converted = fromObject(name, v);
606             validateValue(valueValidator, name, converted);
607             add0(h, i, name, converted);
608         }
609 
610         return thisT();
611     }
612 
613     @Override
614     public T setInt(K name, int value) {
615         return set(name, fromInt(name, value));
616     }
617 
618     @Override
619     public T setLong(K name, long value) {
620         return set(name, fromLong(name, value));
621     }
622 
623     @Override
624     public T setDouble(K name, double value) {
625         return set(name, fromDouble(name, value));
626     }
627 
628     @Override
629     public T setTimeMillis(K name, long value) {
630         return set(name, fromTimeMillis(name, value));
631     }
632 
633     @Override
634     public T setFloat(K name, float value) {
635         return set(name, fromFloat(name, value));
636     }
637 
638     @Override
639     public T setChar(K name, char value) {
640         return set(name, fromChar(name, value));
641     }
642 
643     @Override
644     public T setBoolean(K name, boolean value) {
645         return set(name, fromBoolean(name, value));
646     }
647 
648     @Override
649     public T setByte(K name, byte value) {
650         return set(name, fromByte(name, value));
651     }
652 
653     @Override
654     public T setShort(K name, short value) {
655         return set(name, fromShort(name, value));
656     }
657 
658     @Override
659     public T set(Headers<? extends K, ? extends V, ?> headers) {
660         if (headers != this) {
661             clear();
662             addImpl(headers);
663         }
664         return thisT();
665     }
666 
667     @Override
668     public T setAll(Headers<? extends K, ? extends V, ?> headers) {
669         if (headers != this) {
670             for (K key : headers.names()) {
671                 remove(key);
672             }
673             addImpl(headers);
674         }
675         return thisT();
676     }
677 
678     @Override
679     public boolean remove(K name) {
680         return getAndRemove(name) != null;
681     }
682 
683     @Override
684     public T clear() {
685         Arrays.fill(entries, null);
686         head.before = head.after = head;
687         size = 0;
688         return thisT();
689     }
690 
691     @Override
692     public Iterator<Entry<K, V>> iterator() {
693         return new HeaderIterator();
694     }
695 
696     @Override
697     public Boolean getBoolean(K name) {
698         V v = get(name);
699         try {
700             return v != null ? toBoolean(name, v) : null;
701         } catch (RuntimeException ignore) {
702             return null;
703         }
704     }
705 
706     @Override
707     public boolean getBoolean(K name, boolean defaultValue) {
708         Boolean v = getBoolean(name);
709         return v != null ? v : defaultValue;
710     }
711 
712     @Override
713     public Byte getByte(K name) {
714         V v = get(name);
715         try {
716             return v != null ? toByte(name, v) : null;
717         } catch (RuntimeException ignore) {
718             return null;
719         }
720     }
721 
722     @Override
723     public byte getByte(K name, byte defaultValue) {
724         Byte v = getByte(name);
725         return v != null ? v : defaultValue;
726     }
727 
728     @Override
729     public Character getChar(K name) {
730         V v = get(name);
731         try {
732             return v != null ? toChar(name, v) : null;
733         } catch (RuntimeException ignore) {
734             return null;
735         }
736     }
737 
738     @Override
739     public char getChar(K name, char defaultValue) {
740         Character v = getChar(name);
741         return v != null ? v : defaultValue;
742     }
743 
744     @Override
745     public Short getShort(K name) {
746         V v = get(name);
747         try {
748             return v != null ? toShort(name, v) : null;
749         } catch (RuntimeException ignore) {
750             return null;
751         }
752     }
753 
754     @Override
755     public short getShort(K name, short defaultValue) {
756         Short v = getShort(name);
757         return v != null ? v : defaultValue;
758     }
759 
760     @Override
761     public Integer getInt(K name) {
762         V v = get(name);
763         try {
764             return v != null ? toInt(name, v) : null;
765         } catch (RuntimeException ignore) {
766             return null;
767         }
768     }
769 
770     @Override
771     public int getInt(K name, int defaultValue) {
772         Integer v = getInt(name);
773         return v != null ? v : defaultValue;
774     }
775 
776     @Override
777     public Long getLong(K name) {
778         V v = get(name);
779         try {
780             return v != null ? toLong(name, v) : null;
781         } catch (RuntimeException ignore) {
782             return null;
783         }
784     }
785 
786     @Override
787     public long getLong(K name, long defaultValue) {
788         Long v = getLong(name);
789         return v != null ? v : defaultValue;
790     }
791 
792     @Override
793     public Float getFloat(K name) {
794         V v = get(name);
795         try {
796             return v != null ? toFloat(name, v) : null;
797         } catch (RuntimeException ignore) {
798             return null;
799         }
800     }
801 
802     @Override
803     public float getFloat(K name, float defaultValue) {
804         Float v = getFloat(name);
805         return v != null ? v : defaultValue;
806     }
807 
808     @Override
809     public Double getDouble(K name) {
810         V v = get(name);
811         try {
812             return v != null ? toDouble(name, v) : null;
813         } catch (RuntimeException ignore) {
814             return null;
815         }
816     }
817 
818     @Override
819     public double getDouble(K name, double defaultValue) {
820         Double v = getDouble(name);
821         return v != null ? v : defaultValue;
822     }
823 
824     @Override
825     public Long getTimeMillis(K name) {
826         V v = get(name);
827         try {
828             return v != null ? toTimeMillis(name, v) : null;
829         } catch (RuntimeException ignore) {
830             return null;
831         }
832     }
833 
834     @Override
835     public long getTimeMillis(K name, long defaultValue) {
836         Long v = getTimeMillis(name);
837         return v != null ? v : defaultValue;
838     }
839 
840     @Override
841     public Boolean getBooleanAndRemove(K name) {
842         V v = getAndRemove(name);
843         try {
844             return v != null ? toBoolean(name, v) : null;
845         } catch (RuntimeException ignore) {
846             return null;
847         }
848     }
849 
850     @Override
851     public boolean getBooleanAndRemove(K name, boolean defaultValue) {
852         Boolean v = getBooleanAndRemove(name);
853         return v != null ? v : defaultValue;
854     }
855 
856     @Override
857     public Byte getByteAndRemove(K name) {
858         V v = getAndRemove(name);
859         try {
860             return v != null ? toByte(name, v) : null;
861         } catch (RuntimeException ignore) {
862             return null;
863         }
864     }
865 
866     @Override
867     public byte getByteAndRemove(K name, byte defaultValue) {
868         Byte v = getByteAndRemove(name);
869         return v != null ? v : defaultValue;
870     }
871 
872     @Override
873     public Character getCharAndRemove(K name) {
874         V v = getAndRemove(name);
875         try {
876             return v != null ? toChar(name, v) : null;
877         } catch (RuntimeException ignore) {
878             return null;
879         }
880     }
881 
882     @Override
883     public char getCharAndRemove(K name, char defaultValue) {
884         Character v = getCharAndRemove(name);
885         return v != null ? v : defaultValue;
886     }
887 
888     @Override
889     public Short getShortAndRemove(K name) {
890         V v = getAndRemove(name);
891         try {
892             return v != null ? toShort(name, v) : null;
893         } catch (RuntimeException ignore) {
894             return null;
895         }
896     }
897 
898     @Override
899     public short getShortAndRemove(K name, short defaultValue) {
900         Short v = getShortAndRemove(name);
901         return v != null ? v : defaultValue;
902     }
903 
904     @Override
905     public Integer getIntAndRemove(K name) {
906         V v = getAndRemove(name);
907         try {
908             return v != null ? toInt(name, v) : null;
909         } catch (RuntimeException ignore) {
910             return null;
911         }
912     }
913 
914     @Override
915     public int getIntAndRemove(K name, int defaultValue) {
916         Integer v = getIntAndRemove(name);
917         return v != null ? v : defaultValue;
918     }
919 
920     @Override
921     public Long getLongAndRemove(K name) {
922         V v = getAndRemove(name);
923         try {
924             return v != null ? toLong(name, v) : null;
925         } catch (RuntimeException ignore) {
926             return null;
927         }
928     }
929 
930     @Override
931     public long getLongAndRemove(K name, long defaultValue) {
932         Long v = getLongAndRemove(name);
933         return v != null ? v : defaultValue;
934     }
935 
936     @Override
937     public Float getFloatAndRemove(K name) {
938         V v = getAndRemove(name);
939         try {
940             return v != null ? toFloat(name, v) : null;
941         } catch (RuntimeException ignore) {
942             return null;
943         }
944     }
945 
946     @Override
947     public float getFloatAndRemove(K name, float defaultValue) {
948         Float v = getFloatAndRemove(name);
949         return v != null ? v : defaultValue;
950     }
951 
952     @Override
953     public Double getDoubleAndRemove(K name) {
954         V v = getAndRemove(name);
955         try {
956             return v != null ? toDouble(name, v) : null;
957         } catch (RuntimeException ignore) {
958             return null;
959         }
960     }
961 
962     @Override
963     public double getDoubleAndRemove(K name, double defaultValue) {
964         Double v = getDoubleAndRemove(name);
965         return v != null ? v : defaultValue;
966     }
967 
968     @Override
969     public Long getTimeMillisAndRemove(K name) {
970         V v = getAndRemove(name);
971         try {
972             return v != null ? toTimeMillis(name, v) : null;
973         } catch (RuntimeException ignore) {
974             return null;
975         }
976     }
977 
978     @Override
979     public long getTimeMillisAndRemove(K name, long defaultValue) {
980         Long v = getTimeMillisAndRemove(name);
981         return v != null ? v : defaultValue;
982     }
983 
984     @SuppressWarnings("unchecked")
985     @Override
986     public boolean equals(Object o) {
987         if (!(o instanceof Headers)) {
988             return false;
989         }
990 
991         return equals((Headers<K, V, ?>) o, JAVA_HASHER);
992     }
993 
994     @SuppressWarnings("unchecked")
995     @Override
996     public int hashCode() {
997         return hashCode(JAVA_HASHER);
998     }
999 
1000     /**
1001      * Test this object for equality against {@code h2}.
1002      * @param h2 The object to check equality for.
1003      * @param valueHashingStrategy Defines how values will be compared for equality.
1004      * @return {@code true} if this object equals {@code h2} given {@code valueHashingStrategy}.
1005      * {@code false} otherwise.
1006      */
1007     public final boolean equals(Headers<K, V, ?> h2, HashingStrategy<V> valueHashingStrategy) {
1008         if (h2.size() != size()) {
1009             return false;
1010         }
1011 
1012         if (this == h2) {
1013             return true;
1014         }
1015 
1016         for (K name : names()) {
1017             List<V> otherValues = h2.getAll(name);
1018             List<V> values = getAll(name);
1019             if (otherValues.size() != values.size()) {
1020                 return false;
1021             }
1022             for (int i = 0; i < otherValues.size(); i++) {
1023                 if (!valueHashingStrategy.equals(otherValues.get(i), values.get(i))) {
1024                     return false;
1025                 }
1026             }
1027         }
1028         return true;
1029     }
1030 
1031     /**
1032      * Generate a hash code for this object given a {@link HashingStrategy} to generate hash codes for
1033      * individual values.
1034      * @param valueHashingStrategy Defines how values will be hashed.
1035      */
1036     public final int hashCode(HashingStrategy<V> valueHashingStrategy) {
1037         int result = HASH_CODE_SEED;
1038         for (K name : names()) {
1039             result = 31 * result + hashingStrategy.hashCode(name);
1040             List<V> values = getAll(name);
1041             for (int i = 0; i < values.size(); ++i) {
1042                 result = 31 * result + valueHashingStrategy.hashCode(values.get(i));
1043             }
1044         }
1045         return result;
1046     }
1047 
1048     @Override
1049     public String toString() {
1050         return HeadersUtils.toString(getClass(), iterator(), size());
1051     }
1052 
1053     /**
1054      * Call out to the given {@link NameValidator} to validate the given name.
1055      *
1056      * @param validator the validator to use
1057      * @param forAdd {@code true } if this validation is for adding to the headers, or {@code false} if this is for
1058      * setting (overwriting) the given header.
1059      * @param name the name to validate.
1060      */
1061     protected void validateName(NameValidator<K> validator, boolean forAdd, K name) {
1062         validator.validateName(name);
1063     }
1064 
1065     protected void validateValue(ValueValidator<V> validator, K name, V value) {
1066         try {
1067             validator.validate(value);
1068         } catch (IllegalArgumentException e) {
1069             throw new IllegalArgumentException("Validation failed for header '" + name + "'", e);
1070         }
1071     }
1072 
1073     protected HeaderEntry<K, V> newHeaderEntry(int h, K name, V value, HeaderEntry<K, V> next) {
1074         return new HeaderEntry<K, V>(h, name, value, next, head);
1075     }
1076 
1077     protected ValueConverter<V> valueConverter() {
1078         return valueConverter;
1079     }
1080 
1081     protected NameValidator<K> nameValidator() {
1082         return nameValidator;
1083     }
1084 
1085     protected ValueValidator<V> valueValidator() {
1086         return valueValidator;
1087     }
1088 
1089     private int index(int hash) {
1090         return hash & hashMask;
1091     }
1092 
1093     private void add0(int h, int i, K name, V value) {
1094         // Update the hash table.
1095         HeaderEntry<K, V> entry = newHeaderEntry(h, name, value, entries[i]);
1096         if (valueValidator != ValueValidator.NO_VALIDATION) {
1097             // Allows HeaderEntry.setValue(...) to validate new values, also for subclasses of HeaderEntry.
1098             entry.origin = this;
1099         }
1100         entries[i] = entry;
1101         ++size;
1102     }
1103 
1104     /**
1105      * @return the first value inserted whose hash code equals {@code h} and whose name is equal to {@code name}.
1106      */
1107     private V remove0(int h, int i, K name) {
1108         HeaderEntry<K, V> e = entries[i];
1109         if (e == null) {
1110             return null;
1111         }
1112 
1113         V value = null;
1114         HeaderEntry<K, V> next = e.next;
1115         while (next != null) {
1116             if (next.hash == h && hashingStrategy.equals(name, next.key)) {
1117                 value = next.value;
1118                 e.next = next.next;
1119                 next.remove();
1120                 --size;
1121             } else {
1122                 e = next;
1123             }
1124 
1125             next = e.next;
1126         }
1127 
1128         e = entries[i];
1129         if (e.hash == h && hashingStrategy.equals(name, e.key)) {
1130             if (value == null) {
1131                 value = e.value;
1132             }
1133             entries[i] = e.next;
1134             e.remove();
1135             --size;
1136         }
1137 
1138         return value;
1139     }
1140 
1141     HeaderEntry<K, V> remove0(HeaderEntry<K, V> entry, HeaderEntry<K, V> previous) {
1142         int i = index(entry.hash);
1143         HeaderEntry<K, V> firstEntry = entries[i];
1144         if (firstEntry == entry) {
1145             entries[i] = entry.next;
1146             previous = entries[i];
1147         } else if (previous == null) {
1148             // If we don't have any existing starting point, then start from the beginning.
1149             previous = firstEntry;
1150             HeaderEntry<K, V> next = firstEntry.next;
1151             while (next != null && next != entry) {
1152                 previous = next;
1153                 next = next.next;
1154             }
1155             assert next != null: "Entry not found in its hash bucket: " + entry;
1156             previous.next = entry.next;
1157         } else {
1158             previous.next = entry.next;
1159         }
1160         entry.remove();
1161         --size;
1162         return previous;
1163     }
1164 
1165     @SuppressWarnings("unchecked")
1166     private T thisT() {
1167         return (T) this;
1168     }
1169 
1170     private V fromObject(K name, Object value) {
1171         try {
1172             return valueConverter.convertObject(checkNotNull(value, "value"));
1173         } catch (IllegalArgumentException e) {
1174             throw new IllegalArgumentException("Failed to convert object value for header '" + name + '\'', e);
1175         }
1176     }
1177 
1178     private V fromBoolean(K name, boolean value) {
1179         try {
1180             return valueConverter.convertBoolean(value);
1181         } catch (IllegalArgumentException e) {
1182             throw new IllegalArgumentException("Failed to convert boolean value for header '" + name + '\'', e);
1183         }
1184     }
1185 
1186     private V fromByte(K name, byte value) {
1187         try {
1188             return valueConverter.convertByte(value);
1189         } catch (IllegalArgumentException e) {
1190             throw new IllegalArgumentException("Failed to convert byte value for header '" + name + '\'', e);
1191         }
1192     }
1193 
1194     private V fromChar(K name, char value) {
1195         try {
1196             return valueConverter.convertChar(value);
1197         } catch (IllegalArgumentException e) {
1198             throw new IllegalArgumentException("Failed to convert char value for header '" + name + '\'', e);
1199         }
1200     }
1201 
1202     private V fromShort(K name, short value) {
1203         try {
1204             return valueConverter.convertShort(value);
1205         } catch (IllegalArgumentException e) {
1206             throw new IllegalArgumentException("Failed to convert short value for header '" + name + '\'', e);
1207         }
1208     }
1209 
1210     private V fromInt(K name, int value) {
1211         try {
1212             return valueConverter.convertInt(value);
1213         } catch (IllegalArgumentException e) {
1214             throw new IllegalArgumentException("Failed to convert int value for header '" + name + '\'', e);
1215         }
1216     }
1217 
1218     private V fromLong(K name, long value) {
1219         try {
1220             return valueConverter.convertLong(value);
1221         } catch (IllegalArgumentException e) {
1222             throw new IllegalArgumentException("Failed to convert long value for header '" + name + '\'', e);
1223         }
1224     }
1225 
1226     private V fromFloat(K name, float value) {
1227         try {
1228             return valueConverter.convertFloat(value);
1229         } catch (IllegalArgumentException e) {
1230             throw new IllegalArgumentException("Failed to convert float value for header '" + name + '\'', e);
1231         }
1232     }
1233 
1234     private V fromDouble(K name, double value) {
1235         try {
1236             return valueConverter.convertDouble(value);
1237         } catch (IllegalArgumentException e) {
1238             throw new IllegalArgumentException("Failed to convert double value for header '" + name + '\'', e);
1239         }
1240     }
1241 
1242     private V fromTimeMillis(K name, long value) {
1243         try {
1244             return valueConverter.convertTimeMillis(value);
1245         } catch (IllegalArgumentException e) {
1246             throw new IllegalArgumentException("Failed to convert millsecond value for header '" + name + '\'', e);
1247         }
1248     }
1249 
1250     private boolean toBoolean(K name, V value) {
1251         try {
1252             return valueConverter.convertToBoolean(value);
1253         } catch (IllegalArgumentException e) {
1254             throw new IllegalArgumentException("Failed to convert header value to boolean for header '" + name + '\'');
1255         }
1256     }
1257 
1258     private byte toByte(K name, V value) {
1259         try {
1260             return valueConverter.convertToByte(value);
1261         } catch (IllegalArgumentException e) {
1262             throw new IllegalArgumentException("Failed to convert header value to byte for header '" + name + '\'');
1263         }
1264     }
1265 
1266     private char toChar(K name, V value) {
1267         try {
1268             return valueConverter.convertToChar(value);
1269         } catch (IllegalArgumentException e) {
1270             throw new IllegalArgumentException("Failed to convert header value to char for header '" + name + '\'');
1271         }
1272     }
1273 
1274     private short toShort(K name, V value) {
1275         try {
1276             return valueConverter.convertToShort(value);
1277         } catch (IllegalArgumentException e) {
1278             throw new IllegalArgumentException("Failed to convert header value to short for header '" + name + '\'');
1279         }
1280     }
1281 
1282     private int toInt(K name, V value) {
1283         try {
1284             return valueConverter.convertToInt(value);
1285         } catch (IllegalArgumentException e) {
1286             throw new IllegalArgumentException("Failed to convert header value to int for header '" + name + '\'');
1287         }
1288     }
1289 
1290     private long toLong(K name, V value) {
1291         try {
1292             return valueConverter.convertToLong(value);
1293         } catch (IllegalArgumentException e) {
1294             throw new IllegalArgumentException("Failed to convert header value to long for header '" + name + '\'');
1295         }
1296     }
1297 
1298     private float toFloat(K name, V value) {
1299         try {
1300             return valueConverter.convertToFloat(value);
1301         } catch (IllegalArgumentException e) {
1302             throw new IllegalArgumentException("Failed to convert header value to float for header '" + name + '\'');
1303         }
1304     }
1305 
1306     private double toDouble(K name, V value) {
1307         try {
1308             return valueConverter.convertToDouble(value);
1309         } catch (IllegalArgumentException e) {
1310             throw new IllegalArgumentException("Failed to convert header value to double for header '" + name + '\'');
1311         }
1312     }
1313 
1314     private long toTimeMillis(K name, V value) {
1315         try {
1316             return valueConverter.convertToTimeMillis(value);
1317         } catch (IllegalArgumentException e) {
1318             throw new IllegalArgumentException(
1319                     "Failed to convert header value to millsecond for header '" + name + '\'');
1320         }
1321     }
1322 
1323     /**
1324      * Returns a deep copy of this instance.
1325      */
1326     public DefaultHeaders<K, V, T> copy() {
1327         DefaultHeaders<K, V, T> copy = new DefaultHeaders<K, V, T>(
1328                 hashingStrategy, valueConverter, nameValidator, entries.length, valueValidator);
1329         copy.addImpl(this);
1330         return copy;
1331     }
1332 
1333     private final class HeaderIterator implements Iterator<Entry<K, V>> {
1334         private HeaderEntry<K, V> current = head;
1335 
1336         @Override
1337         public boolean hasNext() {
1338             return current.after != head;
1339         }
1340 
1341         @Override
1342         public Entry<K, V> next() {
1343             current = current.after;
1344 
1345             if (current == head) {
1346                 throw new NoSuchElementException();
1347             }
1348 
1349             return current;
1350         }
1351 
1352         @Override
1353         public void remove() {
1354             throw new UnsupportedOperationException("read only");
1355         }
1356     }
1357 
1358     private final class ValueIterator implements Iterator<V> {
1359         private final K name;
1360         private final int hash;
1361         private HeaderEntry<K, V> removalPrevious;
1362         private HeaderEntry<K, V> previous;
1363         private HeaderEntry<K, V> next;
1364 
1365         ValueIterator(K name) {
1366             this.name = checkNotNull(name, "name");
1367             hash = hashingStrategy.hashCode(name);
1368             calculateNext(entries[index(hash)]);
1369         }
1370 
1371         @Override
1372         public boolean hasNext() {
1373             return next != null;
1374         }
1375 
1376         @Override
1377         public V next() {
1378             if (!hasNext()) {
1379                 throw new NoSuchElementException();
1380             }
1381             if (previous != null) {
1382                 removalPrevious = previous;
1383             }
1384             previous = next;
1385             calculateNext(next.next);
1386             return previous.value;
1387         }
1388 
1389         @Override
1390         public void remove() {
1391             if (previous == null) {
1392                 throw new IllegalStateException();
1393             }
1394             removalPrevious = remove0(previous, removalPrevious);
1395             previous = null;
1396         }
1397 
1398         private void calculateNext(HeaderEntry<K, V> entry) {
1399             while (entry != null) {
1400                 if (entry.hash == hash && hashingStrategy.equals(name, entry.key)) {
1401                     next = entry;
1402                     return;
1403                 }
1404                 entry = entry.next;
1405             }
1406             next = null;
1407         }
1408     }
1409 
1410     protected static class HeaderEntry<K, V> implements Entry<K, V> {
1411         protected final int hash;
1412         protected final K key;
1413         protected V value;
1414         /**
1415          * In bucket linked list
1416          */
1417         protected HeaderEntry<K, V> next;
1418         /**
1419          * Overall insertion order linked list
1420          */
1421         protected HeaderEntry<K, V> before, after;
1422         /**
1423          * The validator of the owning headers, or {@code null} if values are not validated.
1424          */
1425         private DefaultHeaders<K, V, ?> origin;
1426 
1427         protected HeaderEntry(int hash, K key) {
1428             this.hash = hash;
1429             this.key = key;
1430         }
1431 
1432         HeaderEntry(int hash, K key, V value, HeaderEntry<K, V> next, HeaderEntry<K, V> head) {
1433             this.hash = hash;
1434             this.key = key;
1435             this.value = value;
1436             this.next = next;
1437 
1438             after = head;
1439             before = head.before;
1440             pointNeighborsToThis();
1441         }
1442 
1443         HeaderEntry() {
1444             hash = -1;
1445             key = null;
1446             before = after = this;
1447         }
1448 
1449         protected final void pointNeighborsToThis() {
1450             before.after = this;
1451             after.before = this;
1452         }
1453 
1454         public final HeaderEntry<K, V> before() {
1455             return before;
1456         }
1457 
1458         public final HeaderEntry<K, V> after() {
1459             return after;
1460         }
1461 
1462         protected void remove() {
1463             before.after = after;
1464             after.before = before;
1465         }
1466 
1467         @Override
1468         public final K getKey() {
1469             return key;
1470         }
1471 
1472         @Override
1473         public final V getValue() {
1474             return value;
1475         }
1476 
1477         @Override
1478         public final V setValue(V value) {
1479             checkNotNull(value, "value");
1480             if (origin != null) {
1481                 try {
1482                     origin.validateValue(origin.valueValidator, key, value);
1483                 } catch (IllegalArgumentException e) {
1484                     throw new IllegalArgumentException("Validation failed for header '" + key + "'", e);
1485                 }
1486             }
1487             V oldValue = this.value;
1488             this.value = value;
1489             return oldValue;
1490         }
1491 
1492         @Override
1493         public final String toString() {
1494             return key.toString() + '=' + value.toString();
1495         }
1496 
1497         @Override
1498         public boolean equals(Object o) {
1499             if (!(o instanceof Map.Entry)) {
1500                 return false;
1501             }
1502             Entry<?, ?> other = (Entry<?, ?>) o;
1503             return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey()))  &&
1504                    (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
1505         }
1506 
1507         @Override
1508         public int hashCode() {
1509             return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
1510         }
1511     }
1512 }