Skip to content

Commit 6966a33

Browse files
committed
Merge branch 'gh-249-remove-unsignedkey' of github.com:lmdbjava/lmdbjava into iterator-performance
2 parents 7d04445 + 72b5234 commit 6966a33

File tree

75 files changed

+6438
-942
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+6438
-942
lines changed

pom.xml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
<agrona.version>1.22.0</agrona.version>
3030
<assertj.version>3.27.6</assertj.version>
3131
<buildnumber-maven-plugin.version>3.2.1</buildnumber-maven-plugin.version>
32-
<byteunits.version>0.9.1</byteunits.version>
3332
<central-publishing-maven-plugin.version>0.9.0</central-publishing-maven-plugin.version>
3433
<fmt-maven-plugin.version>2.29</fmt-maven-plugin.version>
3534
<google-java-format.version>1.28.0</google-java-format.version>
@@ -85,12 +84,6 @@
8584
<version>${guava.version}</version>
8685
<scope>test</scope>
8786
</dependency>
88-
<dependency>
89-
<groupId>com.jakewharton.byteunits</groupId>
90-
<artifactId>byteunits</artifactId>
91-
<version>${byteunits.version}</version>
92-
<scope>test</scope>
93-
</dependency>
9487
<dependency>
9588
<groupId>io.netty</groupId>
9689
<artifactId>netty-buffer</artifactId>
@@ -146,6 +139,7 @@
146139
<excludes>
147140
<exclude>LICENSE.txt</exclude>
148141
<exclude>**/*.md</exclude>
142+
<exclude>**/*.csv</exclude>
149143
<exclude>lmdb/**</exclude>
150144
<exclude>licenses/**</exclude>
151145
</excludes>
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/*
2+
* Copyright © 2016-2025 The LmdbJava Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.lmdbjava;
17+
18+
import java.util.Collection;
19+
import java.util.Collections;
20+
import java.util.EnumSet;
21+
import java.util.Iterator;
22+
import java.util.Objects;
23+
import java.util.Set;
24+
import java.util.function.Function;
25+
import java.util.function.Supplier;
26+
27+
/**
28+
* Encapsulates an immutable set of flags and the associated bit mask for the flags in the set.
29+
*
30+
* @param <T> The type of the flags in this set. Must extend {@link MaskedFlag} and {@link Enum<T>}.
31+
*/
32+
abstract class AbstractFlagSet<T extends Enum<T> & MaskedFlag> implements FlagSet<T> {
33+
34+
private final Set<T> flags;
35+
private final int mask;
36+
37+
protected AbstractFlagSet(final EnumSet<T> flags) {
38+
Objects.requireNonNull(flags);
39+
this.mask = MaskedFlag.mask(flags);
40+
this.flags = Collections.unmodifiableSet(Objects.requireNonNull(flags));
41+
}
42+
43+
@Override
44+
public int getMask() {
45+
return mask;
46+
}
47+
48+
@Override
49+
public Set<T> getFlags() {
50+
return flags;
51+
}
52+
53+
@Override
54+
public boolean isSet(final T flag) {
55+
// Probably cheaper to compare the masks than to use EnumSet.contains()
56+
return flag != null && MaskedFlag.isSet(mask, flag);
57+
}
58+
59+
/**
60+
* @return The number of flags in this set.
61+
*/
62+
@Override
63+
public int size() {
64+
return flags.size();
65+
}
66+
67+
/**
68+
* @return True if this set is empty.
69+
*/
70+
@Override
71+
public boolean isEmpty() {
72+
return flags.isEmpty();
73+
}
74+
75+
/**
76+
* @return The {@link Iterator} for this set.
77+
*/
78+
@Override
79+
public Iterator<T> iterator() {
80+
return flags.iterator();
81+
}
82+
83+
@Override
84+
public boolean equals(Object object) {
85+
return FlagSet.equals(this, object);
86+
}
87+
88+
@Override
89+
public int hashCode() {
90+
return Objects.hash(flags, mask);
91+
}
92+
93+
@Override
94+
public String toString() {
95+
return FlagSet.asString(this);
96+
}
97+
98+
abstract static class AbstractSingleFlagSet<T extends Enum<T> & MaskedFlag>
99+
implements FlagSet<T> {
100+
101+
private final T flag;
102+
// Only holding this for iterator() and getFlags() so make it lazy.
103+
private EnumSet<T> enumSet;
104+
105+
public AbstractSingleFlagSet(final T flag) {
106+
this.flag = Objects.requireNonNull(flag);
107+
}
108+
109+
@Override
110+
public int getMask() {
111+
return flag.getMask();
112+
}
113+
114+
@Override
115+
public Set<T> getFlags() {
116+
if (enumSet == null) {
117+
return initSet();
118+
} else {
119+
return this.enumSet;
120+
}
121+
}
122+
123+
@Override
124+
public boolean isSet(final T flag) {
125+
return this.flag == flag;
126+
}
127+
128+
@Override
129+
public boolean areAnySet(FlagSet<T> flags) {
130+
if (flags == null) {
131+
return false;
132+
} else {
133+
return flags.isSet(this.flag);
134+
}
135+
}
136+
137+
@Override
138+
public int size() {
139+
return 1;
140+
}
141+
142+
@Override
143+
public boolean isEmpty() {
144+
return false;
145+
}
146+
147+
@Override
148+
public Iterator<T> iterator() {
149+
if (enumSet == null) {
150+
return initSet().iterator();
151+
} else {
152+
return this.enumSet.iterator();
153+
}
154+
}
155+
156+
@Override
157+
public String toString() {
158+
return FlagSet.asString(this);
159+
}
160+
161+
@Override
162+
public int hashCode() {
163+
return Objects.hash(flag, getFlags());
164+
}
165+
166+
private Set<T> initSet() {
167+
final EnumSet<T> set = EnumSet.of(this.flag);
168+
this.enumSet = set;
169+
return set;
170+
}
171+
}
172+
173+
static class AbstractEmptyFlagSet<T extends MaskedFlag> implements FlagSet<T> {
174+
175+
@Override
176+
public int getMask() {
177+
return MaskedFlag.EMPTY_MASK;
178+
}
179+
180+
@Override
181+
public Set<T> getFlags() {
182+
return Collections.emptySet();
183+
}
184+
185+
@Override
186+
public boolean isSet(final T flag) {
187+
return false;
188+
}
189+
190+
@Override
191+
public boolean areAnySet(final FlagSet<T> flags) {
192+
return false;
193+
}
194+
195+
@Override
196+
public int size() {
197+
return 0;
198+
}
199+
200+
@Override
201+
public boolean isEmpty() {
202+
return true;
203+
}
204+
205+
@Override
206+
public Iterator<T> iterator() {
207+
return Collections.emptyIterator();
208+
}
209+
210+
@Override
211+
public String toString() {
212+
return FlagSet.asString(this);
213+
}
214+
215+
@Override
216+
public boolean equals(Object object) {
217+
return FlagSet.equals(this, object);
218+
}
219+
220+
@Override
221+
public int hashCode() {
222+
return Objects.hash(getMask(), getFlags());
223+
}
224+
}
225+
226+
/**
227+
* A builder for creating a {@link AbstractFlagSet}.
228+
*
229+
* @param <E> The type of flag to be held in the {@link AbstractFlagSet}
230+
* @param <S> The type of the {@link AbstractFlagSet} implementation.
231+
*/
232+
public static final class Builder<E extends Enum<E> & MaskedFlag, S extends FlagSet<E>> {
233+
234+
final Class<E> type;
235+
final EnumSet<E> enumSet;
236+
final Function<EnumSet<E>, S> constructor;
237+
final Function<E, S> singletonSetConstructor;
238+
final Supplier<S> emptySetSupplier;
239+
240+
Builder(
241+
final Class<E> type,
242+
final Function<EnumSet<E>, S> constructor,
243+
final Function<E, S> singletonSetConstructor,
244+
final Supplier<S> emptySetSupplier) {
245+
this.type = type;
246+
this.enumSet = EnumSet.noneOf(type);
247+
this.constructor = Objects.requireNonNull(constructor);
248+
this.singletonSetConstructor = Objects.requireNonNull(singletonSetConstructor);
249+
this.emptySetSupplier = Objects.requireNonNull(emptySetSupplier);
250+
}
251+
252+
/**
253+
* Replaces any flags already set in the builder with the contents of the passed flags {@link
254+
* Collection}
255+
*
256+
* @param flags The flags to set in the builder.
257+
* @return this builder instance.
258+
*/
259+
public Builder<E, S> setFlags(final Collection<E> flags) {
260+
clear();
261+
if (flags != null) {
262+
for (E flag : flags) {
263+
if (flag != null) {
264+
enumSet.add(flag);
265+
}
266+
}
267+
}
268+
return this;
269+
}
270+
271+
/**
272+
* Replaces any flags already set in the builder with the passed flags.
273+
*
274+
* @param flags The flags to set in the builder.
275+
* @return this builder instance.
276+
*/
277+
@SafeVarargs
278+
public final Builder<E, S> setFlags(final E... flags) {
279+
clear();
280+
if (flags != null) {
281+
for (E flag : flags) {
282+
if (flag != null) {
283+
if (!type.equals(flag.getClass())) {
284+
throw new IllegalArgumentException("Unexpected type " + flag.getClass());
285+
}
286+
enumSet.add(flag);
287+
}
288+
}
289+
}
290+
return this;
291+
}
292+
293+
/**
294+
* Adds a single flag in the builder.
295+
*
296+
* @param flag The flag to set in the builder.
297+
* @return this builder instance.
298+
*/
299+
public Builder<E, S> addFlag(final E flag) {
300+
if (flag != null) {
301+
enumSet.add(flag);
302+
}
303+
return this;
304+
}
305+
306+
/**
307+
* Adds multiple flag in the builder.
308+
*
309+
* @param flags The flags to set in the builder.
310+
* @return this builder instance.
311+
*/
312+
public Builder<E, S> addFlags(final Collection<E> flags) {
313+
if (flags != null) {
314+
enumSet.addAll(flags);
315+
}
316+
return this;
317+
}
318+
319+
/**
320+
* Clears any flags already set in this {@link Builder}
321+
*
322+
* @return this builder instance.
323+
*/
324+
public Builder<E, S> clear() {
325+
enumSet.clear();
326+
return this;
327+
}
328+
329+
/**
330+
* Build the {@link DbiFlagSet}
331+
*
332+
* @return A
333+
*/
334+
public S build() {
335+
final int size = enumSet.size();
336+
if (size == 0) {
337+
return emptySetSupplier.get();
338+
} else if (size == 1) {
339+
return singletonSetConstructor.apply(enumSet.stream().findFirst().get());
340+
} else {
341+
return constructor.apply(enumSet);
342+
}
343+
}
344+
}
345+
}

0 commit comments

Comments
 (0)