1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.value; |
7 | |
8 | import java.sql.PreparedStatement; |
9 | import java.sql.SQLException; |
10 | |
11 | import org.h2.api.ErrorCode; |
12 | import org.h2.message.DbException; |
13 | import org.h2.util.MathUtils; |
14 | |
15 | /** |
16 | * Implementation of the INT data type. |
17 | */ |
18 | public class ValueInt extends Value { |
19 | |
20 | /** |
21 | * The precision in digits. |
22 | */ |
23 | public static final int PRECISION = 10; |
24 | |
25 | /** |
26 | * The maximum display size of an int. |
27 | * Example: -2147483648 |
28 | */ |
29 | public static final int DISPLAY_SIZE = 11; |
30 | |
31 | private static final int STATIC_SIZE = 128; |
32 | // must be a power of 2 |
33 | private static final int DYNAMIC_SIZE = 256; |
34 | private static final ValueInt[] STATIC_CACHE = new ValueInt[STATIC_SIZE]; |
35 | private static final ValueInt[] DYNAMIC_CACHE = new ValueInt[DYNAMIC_SIZE]; |
36 | |
37 | private final int value; |
38 | |
39 | static { |
40 | for (int i = 0; i < STATIC_SIZE; i++) { |
41 | STATIC_CACHE[i] = new ValueInt(i); |
42 | } |
43 | } |
44 | |
45 | private ValueInt(int value) { |
46 | this.value = value; |
47 | } |
48 | |
49 | /** |
50 | * Get or create an int value for the given int. |
51 | * |
52 | * @param i the int |
53 | * @return the value |
54 | */ |
55 | public static ValueInt get(int i) { |
56 | if (i >= 0 && i < STATIC_SIZE) { |
57 | return STATIC_CACHE[i]; |
58 | } |
59 | ValueInt v = DYNAMIC_CACHE[i & (DYNAMIC_SIZE - 1)]; |
60 | if (v == null || v.value != i) { |
61 | v = new ValueInt(i); |
62 | DYNAMIC_CACHE[i & (DYNAMIC_SIZE - 1)] = v; |
63 | } |
64 | return v; |
65 | } |
66 | |
67 | @Override |
68 | public Value add(Value v) { |
69 | ValueInt other = (ValueInt) v; |
70 | return checkRange((long) value + (long) other.value); |
71 | } |
72 | |
73 | private static ValueInt checkRange(long x) { |
74 | if (x < Integer.MIN_VALUE || x > Integer.MAX_VALUE) { |
75 | throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Long.toString(x)); |
76 | } |
77 | return ValueInt.get((int) x); |
78 | } |
79 | |
80 | @Override |
81 | public int getSignum() { |
82 | return Integer.signum(value); |
83 | } |
84 | |
85 | @Override |
86 | public Value negate() { |
87 | return checkRange(-(long) value); |
88 | } |
89 | |
90 | @Override |
91 | public Value subtract(Value v) { |
92 | ValueInt other = (ValueInt) v; |
93 | return checkRange((long) value - (long) other.value); |
94 | } |
95 | |
96 | @Override |
97 | public Value multiply(Value v) { |
98 | ValueInt other = (ValueInt) v; |
99 | return checkRange((long) value * (long) other.value); |
100 | } |
101 | |
102 | @Override |
103 | public Value divide(Value v) { |
104 | ValueInt other = (ValueInt) v; |
105 | if (other.value == 0) { |
106 | throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); |
107 | } |
108 | return ValueInt.get(value / other.value); |
109 | } |
110 | |
111 | @Override |
112 | public Value modulus(Value v) { |
113 | ValueInt other = (ValueInt) v; |
114 | if (other.value == 0) { |
115 | throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL()); |
116 | } |
117 | return ValueInt.get(value % other.value); |
118 | } |
119 | |
120 | @Override |
121 | public String getSQL() { |
122 | return getString(); |
123 | } |
124 | |
125 | @Override |
126 | public int getType() { |
127 | return Value.INT; |
128 | } |
129 | |
130 | @Override |
131 | public int getInt() { |
132 | return value; |
133 | } |
134 | |
135 | @Override |
136 | public long getLong() { |
137 | return value; |
138 | } |
139 | |
140 | @Override |
141 | protected int compareSecure(Value o, CompareMode mode) { |
142 | ValueInt v = (ValueInt) o; |
143 | return MathUtils.compareInt(value, v.value); |
144 | } |
145 | |
146 | @Override |
147 | public String getString() { |
148 | return String.valueOf(value); |
149 | } |
150 | |
151 | @Override |
152 | public long getPrecision() { |
153 | return PRECISION; |
154 | } |
155 | |
156 | @Override |
157 | public int hashCode() { |
158 | return value; |
159 | } |
160 | |
161 | @Override |
162 | public Object getObject() { |
163 | return value; |
164 | } |
165 | |
166 | @Override |
167 | public void set(PreparedStatement prep, int parameterIndex) |
168 | throws SQLException { |
169 | prep.setInt(parameterIndex, value); |
170 | } |
171 | |
172 | @Override |
173 | public int getDisplaySize() { |
174 | return DISPLAY_SIZE; |
175 | } |
176 | |
177 | @Override |
178 | public boolean equals(Object other) { |
179 | return other instanceof ValueInt && value == ((ValueInt) other).value; |
180 | } |
181 | |
182 | } |