1 /*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 * ====================================================================
20 *
21 * This software consists of voluntary contributions made by many
22 * individuals on behalf of the Apache Software Foundation. For more
23 * information on the Apache Software Foundation, please see
24 * <http://www.apache.org/>.
25 *
26 */
27 package org.apache.hc.client5.http.impl;
28
29 import java.util.concurrent.atomic.AtomicLong;
30 import org.apache.hc.core5.annotation.Internal;
31 import org.apache.hc.core5.util.Args;
32
33 /**
34 * A thread safe incrementing identifier.
35 *
36 * @since 5.1.4
37 */
38 @Internal
39 public final class PrefixedIncrementingId {
40
41 private final AtomicLong count = new AtomicLong(0);
42 private final String prefix0;
43 private final String prefix1;
44 private final String prefix2;
45 private final String prefix3;
46 private final String prefix4;
47 private final String prefix5;
48 private final String prefix6;
49 private final String prefix7;
50 private final String prefix8;
51 private final String prefix9;
52
53 /**
54 * Creates an incrementing identifier.
55 * @param prefix string prefix for generated IDs
56 */
57 public PrefixedIncrementingId(final String prefix) {
58 this.prefix0 = Args.notNull(prefix, "prefix");
59 this.prefix1 = prefix0 + '0';
60 this.prefix2 = prefix1 + '0';
61 this.prefix3 = prefix2 + '0';
62 this.prefix4 = prefix3 + '0';
63 this.prefix5 = prefix4 + '0';
64 this.prefix6 = prefix5 + '0';
65 this.prefix7 = prefix6 + '0';
66 this.prefix8 = prefix7 + '0';
67 this.prefix9 = prefix8 + '0';
68 }
69
70 public long getNextNumber() {
71 return count.incrementAndGet();
72 }
73
74 public String getNextId() {
75 return createId(count.incrementAndGet());
76 }
77
78 /**
79 * Create an ID from this instance's prefix and zero padded specified value.
80 *
81 * Hand rolled equivalent to `String.format("ex-%010d", value)` optimized to reduce
82 * allocation and CPU overhead.
83 */
84 String createId(final long value) {
85 final String longString = Long.toString(value);
86 switch (longString.length()) {
87 case 1:
88 return prefix9 + longString;
89 case 2:
90 return prefix8 + longString;
91 case 3:
92 return prefix7 + longString;
93 case 4:
94 return prefix6 + longString;
95 case 5:
96 return prefix5 + longString;
97 case 6:
98 return prefix4 + longString;
99 case 7:
100 return prefix3 + longString;
101 case 8:
102 return prefix2 + longString;
103 case 9:
104 return prefix1 + longString;
105 default:
106 return prefix0 + longString;
107 }
108 }
109 }