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+ */
116package org .lmdbjava ;
217
318import java .nio .charset .StandardCharsets ;
@@ -35,8 +50,11 @@ public class DbiBuilder<T> {
3550 * <p>
3651 * The name will be converted into bytes using {@link StandardCharsets#UTF_8}.
3752 * </p>
53+ * @param name The name of the database or null for the unnamed database
54+ * (see also {@link DbiBuilder#withoutDbName()})
55+ * @return The next builder stage.
3856 */
39- public RequireComparator <T > withDbName (final String name ) {
57+ public DbiBuilderStage2 <T > withDbName (final String name ) {
4058 // Null name is allowed so no null check
4159 final byte [] nameBytes = name == null
4260 ? null
@@ -46,11 +64,13 @@ public RequireComparator<T> withDbName(final String name) {
4664
4765 /**
4866 * Create the {@link Dbi} with the passed name in byte[] form.
67+ * @param name The name of the database in byte form.
68+ * @return The next builder stage.
4969 */
50- public RequireComparator <T > withDbName (final byte [] name ) {
70+ public DbiBuilderStage2 <T > withDbName (final byte [] name ) {
5171 // Null name is allowed so no null check
5272 this .name = name ;
53- return new RequireComparator <>(this );
73+ return new DbiBuilderStage2 <>(this );
5474 }
5575
5676 /**
@@ -61,8 +81,9 @@ public RequireComparator<T> withDbName(final byte[] name) {
6181 * Equivalent to passing null to
6282 * {@link DbiBuilder#withDbName(String)} or {@link DbiBuilder#withDbName(byte[])}.
6383 * </p>
84+ * @return The next builder stage.
6485 */
65- public RequireComparator <T > withoutDbName () {
86+ public DbiBuilderStage2 <T > withoutDbName () {
6687 return withDbName ((byte []) null );
6788 }
6889
@@ -75,14 +96,14 @@ public RequireComparator<T> withoutDbName() {
7596 *
7697 * @param <T> buffer type
7798 */
78- public static class RequireComparator <T > {
99+ public static class DbiBuilderStage2 <T > {
79100
80101 private final DbiBuilder <T > dbiBuilder ;
81102
82103 private Comparator <T > comparator ;
83104 private boolean useNativeCallback ;
84105
85- private RequireComparator (final DbiBuilder <T > dbiBuilder ) {
106+ private DbiBuilderStage2 (final DbiBuilder <T > dbiBuilder ) {
86107 this .dbiBuilder = dbiBuilder ;
87108 }
88109
@@ -94,24 +115,24 @@ private RequireComparator(final DbiBuilder<T> dbiBuilder) {
94115 * </p>
95116 * <p>
96117 * This option may be slightly less performant than when using
97- * {@link RequireComparator#withDefaultJavaComparator ()} as it need to call down
118+ * {@link DbiBuilderStage2#withDefaultIteratorComparator ()} as it need to call down
98119 * to LMDB to perform the comparisons, however it guarantees that {@link CursorIterable}
99120 * key comparison matches LMDB key comparison.
100121 * </p>
101122 * <p>
102123 * If you do not intend to use {@link CursorIterable} then it doesn't matter whether
103- * you choose {@link RequireComparator #withNativeComparator()},
104- * {@link RequireComparator#withDefaultJavaComparator ()} or
105- * {@link RequireComparator #withIteratorComparator(Comparator)} as these comparators will
124+ * you choose {@link DbiBuilderStage2 #withNativeComparator()},
125+ * {@link DbiBuilderStage2#withDefaultIteratorComparator ()} or
126+ * {@link DbiBuilderStage2 #withIteratorComparator(Comparator)} as these comparators will
106127 * never be used.
107128 * </p>
108129 *
109- * @return this builder instance .
130+ * @return The next builder stage .
110131 */
111- public FinalStage <T > withNativeComparator () {
132+ public DbiBuilderStage3 <T > withNativeComparator () {
112133 this .comparator = null ;
113134 this .useNativeCallback = false ;
114- return new FinalStage <>(this );
135+ return new DbiBuilderStage3 <>(this );
115136 }
116137
117138 /**
@@ -121,23 +142,23 @@ public FinalStage<T> withNativeComparator() {
121142 * </p>
122143 * <p>
123144 * This option may be slightly more performant than when using
124- * {@link RequireComparator #withNativeComparator()} but it relies on the default comparator
145+ * {@link DbiBuilderStage2 #withNativeComparator()} but it relies on the default comparator
125146 * in LmdbJava behaving identically to the comparator in LMDB.
126147 * </p>
127148 * <p>
128149 * If you do not intend to use {@link CursorIterable} then it doesn't matter whether
129- * you choose {@link RequireComparator #withNativeComparator()},
130- * {@link RequireComparator#withDefaultJavaComparator ()} or
131- * {@link RequireComparator #withIteratorComparator(Comparator)} as these comparators will
150+ * you choose {@link DbiBuilderStage2 #withNativeComparator()},
151+ * {@link DbiBuilderStage2#withDefaultIteratorComparator ()} or
152+ * {@link DbiBuilderStage2 #withIteratorComparator(Comparator)} as these comparators will
132153 * never be used.
133154 * </p>
134155 *
135- * @return this builder instance .
156+ * @return The next builder stage .
136157 */
137- public FinalStage <T > withDefaultJavaComparator () {
158+ public DbiBuilderStage3 <T > withDefaultIteratorComparator () {
138159 this .comparator = dbiBuilder .proxy .getUnsignedComparator ();
139160 this .useNativeCallback = false ;
140- return new FinalStage <>(this );
161+ return new DbiBuilderStage3 <>(this );
141162 }
142163
143164 /**
@@ -151,12 +172,12 @@ public FinalStage<T> withDefaultJavaComparator() {
151172 * </p>
152173 *
153174 * @param comparator for all key comparison operations.
154- * @return this builder instance .
175+ * @return The next builder stage .
155176 */
156- public FinalStage <T > withCallbackComparator (final Comparator <T > comparator ) {
177+ public DbiBuilderStage3 <T > withCallbackIteratorComparator (final Comparator <T > comparator ) {
157178 this .comparator = Objects .requireNonNull (comparator );
158179 this .useNativeCallback = true ;
159- return new FinalStage <>(this );
180+ return new DbiBuilderStage3 <>(this );
160181 }
161182
162183 /**
@@ -171,26 +192,23 @@ public FinalStage<T> withCallbackComparator(final Comparator<T> comparator) {
171192 * differently to the comparator in LMDB that controls the insert/iteration order.
172193 * </p>
173194 * <p>
174- * This option may be slightly less performant than when using
175- * {@link RequireComparator#withDefaultJavaComparator()} as it need to call down
176- * to LMDB to perform the comparisons, however it guarantees that {@link CursorIterable}
177- * key comparison matches LMDB key comparison.
195+ * The supplied {@link Comparator} should match the behaviour of LMDB's mdb_cmp comparator.
178196 * </p>
179197 * <p>
180198 * If you do not intend to use {@link CursorIterable} then it doesn't matter whether
181- * you choose {@link RequireComparator #withNativeComparator()},
182- * {@link RequireComparator#withDefaultJavaComparator ()} or
183- * {@link RequireComparator #withIteratorComparator(Comparator)} as these comparators will
199+ * you choose {@link DbiBuilderStage2 #withNativeComparator()},
200+ * {@link DbiBuilderStage2#withDefaultIteratorComparator ()} or
201+ * {@link DbiBuilderStage2 #withIteratorComparator(Comparator)} as these comparators will
184202 * never be used.
185203 * </p>
186204 *
187205 * @param comparator The comparator to use with {@link CursorIterable}.
188- * @return this builder instance .
206+ * @return The next builder stage .
189207 */
190- public FinalStage <T > withIteratorComparator (final Comparator <T > comparator ) {
208+ public DbiBuilderStage3 <T > withIteratorComparator (final Comparator <T > comparator ) {
191209 this .comparator = Objects .requireNonNull (comparator );
192210 this .useNativeCallback = false ;
193- return new FinalStage <>(this );
211+ return new DbiBuilderStage3 <>(this );
194212 }
195213 }
196214
@@ -203,14 +221,14 @@ public FinalStage<T> withIteratorComparator(final Comparator<T> comparator) {
203221 *
204222 * @param <T> buffer type
205223 */
206- public static class FinalStage <T > {
224+ public static class DbiBuilderStage3 <T > {
207225
208- private final RequireComparator <T > requireComparator ;
226+ private final DbiBuilderStage2 <T > dbiBuilderStage2 ;
209227 private Set <DbiFlags > dbiFlags = null ;
210228 private Txn <T > txn = null ;
211229
212- private FinalStage ( RequireComparator <T > requireComparator ) {
213- this .requireComparator = requireComparator ;
230+ private DbiBuilderStage3 ( DbiBuilderStage2 <T > dbiBuilderStage2 ) {
231+ this .dbiBuilderStage2 = dbiBuilderStage2 ;
214232 }
215233
216234 private void initDbiFlags () {
@@ -225,16 +243,18 @@ private void initDbiFlags() {
225243 * </p>
226244 * <p>
227245 * Replaces any flags applies in previous calls to
228- * {@link FinalStage #withDbiFlags(Collection)}, {@link FinalStage #withDbiFlags(DbiFlags...)}
229- * or {@link FinalStage #addDbiFlag(DbiFlags)}.
246+ * {@link DbiBuilderStage3 #withDbiFlags(Collection)}, {@link DbiBuilderStage3 #withDbiFlags(DbiFlags...)}
247+ * or {@link DbiBuilderStage3 #addDbiFlag(DbiFlags)}.
230248 * </p>
231249 *
232250 * @param dbiFlags to open the database with.
233251 */
234- public FinalStage <T > withDbiFlags (final Collection <DbiFlags > dbiFlags ) {
252+ public DbiBuilderStage3 <T > withDbiFlags (final Collection <DbiFlags > dbiFlags ) {
235253 initDbiFlags ();
236254 if (dbiFlags != null ) {
237- this .dbiFlags .addAll (dbiFlags );
255+ this .dbiFlags .stream ()
256+ .filter (Objects ::nonNull )
257+ .forEach (dbiFlags ::add );
238258 }
239259 return this ;
240260 }
@@ -245,13 +265,14 @@ public FinalStage<T> withDbiFlags(final Collection<DbiFlags> dbiFlags) {
245265 * </p>
246266 * <p>
247267 * Replaces any flags applies in previous calls to
248- * {@link FinalStage #withDbiFlags(Collection)}, {@link FinalStage #withDbiFlags(DbiFlags...)}
249- * or {@link FinalStage #addDbiFlag(DbiFlags)}.
268+ * {@link DbiBuilderStage3 #withDbiFlags(Collection)}, {@link DbiBuilderStage3 #withDbiFlags(DbiFlags...)}
269+ * or {@link DbiBuilderStage3 #addDbiFlag(DbiFlags)}.
250270 * </p>
251271 *
252272 * @param dbiFlags to open the database with.
273+ * A null array is a no-op. Null items are ignored.
253274 */
254- public FinalStage <T > withDbiFlags (final DbiFlags ... dbiFlags ) {
275+ public DbiBuilderStage3 <T > withDbiFlags (final DbiFlags ... dbiFlags ) {
255276 initDbiFlags ();
256277 if (dbiFlags != null ) {
257278 Arrays .stream (dbiFlags )
@@ -262,12 +283,14 @@ public FinalStage<T> withDbiFlags(final DbiFlags... dbiFlags) {
262283 }
263284
264285 /**
265- * Adds dbiFlag to those flags already added to this builder.
286+ * Adds dbiFlag to those flags already added to this builder by
287+ * {@link DbiBuilderStage3#withDbiFlags(DbiFlags...)}, {@link DbiBuilderStage3#withDbiFlags(Collection)}
288+ * or {@link DbiBuilderStage3#addDbiFlag(DbiFlags)}.
266289 *
267- * @param dbiFlag to open the database with.
290+ * @param dbiFlag to open the database with. A null value is a no-op.
268291 * @return this builder instance.
269292 */
270- public FinalStage <T > addDbiFlag (final DbiFlags dbiFlag ) {
293+ public DbiBuilderStage3 <T > addDbiFlag (final DbiFlags dbiFlag ) {
271294 initDbiFlags ();
272295 if (dbiFlags != null ) {
273296 this .dbiFlags .add (dbiFlag );
@@ -278,14 +301,14 @@ public FinalStage<T> addDbiFlag(final DbiFlags dbiFlag) {
278301 /**
279302 * Use the supplied transaction to open the {@link Dbi}.
280303 * <p>
281- * The caller must commit the transaction after calling {@link FinalStage #open()}
304+ * The caller MUST commit the transaction after calling {@link DbiBuilderStage3 #open()},
282305 * in order to retain the <code>Dbi</code> in the <code>Env</code>.
283306 * </p>
284307 *
285308 * @param txn transaction to use (required; not closed)
286309 * @return this builder instance.
287310 */
288- public FinalStage <T > withTxn (final Txn <T > txn ) {
311+ public DbiBuilderStage3 <T > withTxn (final Txn <T > txn ) {
289312 this .txn = Objects .requireNonNull (txn );
290313 return this ;
291314 }
@@ -300,7 +323,7 @@ public FinalStage<T> withTxn(final Txn<T> txn) {
300323 * @return A newly constructed and opened {@link Dbi}.
301324 */
302325 public Dbi <T > open () {
303- final DbiBuilder <T > dbiBuilder = requireComparator .dbiBuilder ;
326+ final DbiBuilder <T > dbiBuilder = dbiBuilderStage2 .dbiBuilder ;
304327 if (txn == null ) {
305328 try (final Txn <T > txn = getTxn (dbiBuilder )) {
306329 return open (txn , dbiBuilder );
@@ -326,8 +349,8 @@ private Dbi<T> open(final Txn<T> txn,
326349 dbiBuilder .env ,
327350 txn ,
328351 dbiBuilder .name ,
329- requireComparator .comparator ,
330- requireComparator .useNativeCallback ,
352+ dbiBuilderStage2 .comparator ,
353+ dbiBuilderStage2 .useNativeCallback ,
331354 dbiBuilder .proxy ,
332355 dbiFlagsArr );
333356 }
0 commit comments