1 | /*
|
---|
2 | * Copyright (C) 1997 Pharos IP Pty Ltd
|
---|
3 | * $Id: GdbmFile.java 30401 2016-03-13 21:33:13Z davidb $
|
---|
4 | *
|
---|
5 | * This program is free software; you can redistribute it and/or modify
|
---|
6 | * it under the terms of the GNU General Public License as published by
|
---|
7 | * the Free Software Foundation; either version 2 of the License, or
|
---|
8 | * (at your option) any later version.
|
---|
9 | *
|
---|
10 | * This program is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | * GNU General Public License for more details.
|
---|
14 | *
|
---|
15 | * You should have received a copy of the GNU General Public License
|
---|
16 | * along with this program; if not, write to the Free Software
|
---|
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
18 | */
|
---|
19 |
|
---|
20 | package au.com.pharos.gdbm;
|
---|
21 |
|
---|
22 | import java.util.Enumeration;
|
---|
23 | import java.util.NoSuchElementException;
|
---|
24 |
|
---|
25 | import au.com.pharos.packing.Packing;
|
---|
26 | import au.com.pharos.packing.RawPacking;
|
---|
27 |
|
---|
28 | /** Java interface to a GDBM database table.
|
---|
29 | *
|
---|
30 | * <P>This database is a simple on-disk hash table.
|
---|
31 | *
|
---|
32 | * <P>Both the hash keys and values
|
---|
33 | * are binary strings of any length. They are converted to and
|
---|
34 | * from Java objects using customizable packing strategies.
|
---|
35 | *
|
---|
36 | * <P>The implementation of this class consists of two levels: a
|
---|
37 | * Java-level interface, and a set of private native functions
|
---|
38 | * implemented in C. As much functionality as possible is implemented
|
---|
39 | * in Java: the C functions generally just marshal the information for
|
---|
40 | * presentation to the native GDBM library.
|
---|
41 | *
|
---|
42 | * <P>The native library <CODE>gdbmjava</CODE> must be available
|
---|
43 | * for dynamic loading in a system-dependant manner.
|
---|
44 | *
|
---|
45 | * <p>See the GDBM documentation file, and the
|
---|
46 | * <A HREF="http://www.pharos.com.au/gdbm/">JavaGDBM home page</A>
|
---|
47 | * for more information.
|
---|
48 | *
|
---|
49 | * @see au.com.pharos.packing.Packing
|
---|
50 | * @see au.com.pharos.gdbm.GdbmTest
|
---|
51 | * @see au.com.pharos.gdbm.GdbmDictionary
|
---|
52 | *
|
---|
53 | * @author Martin Pool
|
---|
54 | * @version $Revision: 30401 $
|
---|
55 | **/
|
---|
56 |
|
---|
57 | public class GdbmFile implements Closeable {
|
---|
58 | /** The GDBM handle for the database file, or 0 if the database has
|
---|
59 | * been closed. Java doesn't understand it, but it stores it and
|
---|
60 | * passes it to the C routines. */
|
---|
61 | private transient volatile long dbf;
|
---|
62 |
|
---|
63 | // Remember the parameters used to open the database
|
---|
64 | private int openFlags;
|
---|
65 | private String dbFilename;
|
---|
66 |
|
---|
67 | // -----------------------------------------------------------------
|
---|
68 | // Constructors
|
---|
69 |
|
---|
70 | // Values must match those from gdbm.h !
|
---|
71 | /** Indicates that the caller will just read the database. Many
|
---|
72 | * readers may share a database. */
|
---|
73 | public final static int READER = 0;
|
---|
74 |
|
---|
75 | /** The caller wants read/write access to an existing database and
|
---|
76 | * requires exclusive access. */
|
---|
77 | public final static int WRITER = 1;
|
---|
78 |
|
---|
79 | /** The caller wants exclusive read/write access, and the database
|
---|
80 | * should be created if it does not already exist. */
|
---|
81 | public final static int WRCREAT = 2;
|
---|
82 |
|
---|
83 | /** The caller wants exclusive read/write access, and the database
|
---|
84 | * should be replaced if it already exists. */
|
---|
85 | public final static int NEWDB = 3;
|
---|
86 |
|
---|
87 | /** Flag indicating GDBM should write to the database without disc
|
---|
88 | * synchronization. This allows faster writes, but may produce an
|
---|
89 | * inconsistent database in the event of abnormal termination of
|
---|
90 | * the writer. */
|
---|
91 | public final static int FAST = 16;
|
---|
92 |
|
---|
93 | // TODO: Allow FAST mode to be toggled
|
---|
94 |
|
---|
95 | /** Creates a new GdbmFile object representing an disk database. The
|
---|
96 | * database is opened or created on disk.
|
---|
97 | *
|
---|
98 | * <P>Both key and value strategies default to
|
---|
99 | * RawPacking, meaning that the database will use raw byte arrays
|
---|
100 | * for both key and value.
|
---|
101 | *
|
---|
102 | * <P>TODO: Allow the caller to specify the block size and/or
|
---|
103 | * cache size.
|
---|
104 | *
|
---|
105 | * @param fileName the disk filename in which the data will be stored.
|
---|
106 | *
|
---|
107 | * @param flags any of READER, WRITER, WRCREAT, and NEWDB, optionally
|
---|
108 | * ORed with FAST
|
---|
109 | *
|
---|
110 | * @exception GdbmException if the database cannot be opened or
|
---|
111 | * created.
|
---|
112 | *
|
---|
113 | * @see GdbmFile#READER
|
---|
114 | * @see GdbmFile#WRITER
|
---|
115 | * @see GdbmFile#WRCREAT
|
---|
116 | * @see GdbmFile#NEWDB
|
---|
117 | * @see GdbmFile#FAST
|
---|
118 | */
|
---|
119 | public GdbmFile(String fileName, int flags)
|
---|
120 | throws GdbmException
|
---|
121 | {
|
---|
122 | openFlags = flags;
|
---|
123 | dbFilename = fileName;
|
---|
124 | keyPacking = new RawPacking();
|
---|
125 | valuePacking = new RawPacking();
|
---|
126 | dbf = gdbm_open(fileName, flags);
|
---|
127 | }
|
---|
128 |
|
---|
129 | /** Close the database file if it is still open.
|
---|
130 | *
|
---|
131 | * <P><B>Note</B> that the disk file is locked against access from
|
---|
132 | * other processes while it is open. To prevent contention, it
|
---|
133 | * may be useful to explicitly close the file rather than waiting
|
---|
134 | * for the garbage-collector.
|
---|
135 | *
|
---|
136 | * @see GdbmFile#isOpen()
|
---|
137 | **/
|
---|
138 | public synchronized void close() throws GdbmException
|
---|
139 | {
|
---|
140 | if (dbf != 0)
|
---|
141 | gdbm_close(dbf);
|
---|
142 | dbf = 0; // No longer connected
|
---|
143 | }
|
---|
144 |
|
---|
145 | /** Close the database when the GdbmFile is garbage-collected.
|
---|
146 | *
|
---|
147 | * @see GdbmFile#close()
|
---|
148 | */
|
---|
149 | public void finalize() throws GdbmException
|
---|
150 | {
|
---|
151 | close();
|
---|
152 | }
|
---|
153 |
|
---|
154 | /* The Gdbm file is unlocked when the process terminates, but
|
---|
155 | * nevertheless it would be good to close it in finalization, in
|
---|
156 | * case the OS process continues after the JVM terminates.
|
---|
157 | *
|
---|
158 | * XXX: Unfortunately, anybody else can turn this off again: it
|
---|
159 | * would be nice if there was a way to avoid this. */
|
---|
160 | static {
|
---|
161 | System.runFinalizersOnExit(true);
|
---|
162 | }
|
---|
163 |
|
---|
164 |
|
---|
165 |
|
---|
166 | // -----------------------------------------------------------------
|
---|
167 | // Packing strategies
|
---|
168 | private Packing keyPacking, valuePacking;
|
---|
169 |
|
---|
170 | /** Set the object to be used as the packing strategy for
|
---|
171 | * converting key objects to and from the byte arrays stored in
|
---|
172 | * the database.
|
---|
173 | *
|
---|
174 | * <P>Depending on the class of Java object used as the key of your
|
---|
175 | * database, it may be appropriate to use a packing strategy from
|
---|
176 | * the
|
---|
177 | * <A HREF="Package-au.com.pharos.packing.html"><CODE>au.com.pharos.packing</CODE></A>
|
---|
178 | * package, or to define a new subclass of one of those strategies.
|
---|
179 | *
|
---|
180 | * @see au.com.pharos.packing.Packing
|
---|
181 | * @see GdbmFile#setValuePacking(au.com.pharos.packing.Packing)
|
---|
182 | **/
|
---|
183 | public void setKeyPacking(Packing newPacking) {
|
---|
184 | keyPacking = newPacking;
|
---|
185 | }
|
---|
186 |
|
---|
187 | /** Set the object to be used as the packing strategy for
|
---|
188 | * converting value objects to and from the byte arrays stored
|
---|
189 | * in the database.
|
---|
190 | *
|
---|
191 | * <P>Depending on the class of Java object used as the key of your
|
---|
192 | * database, it may be appropriate to use a packing strategy from
|
---|
193 | * the
|
---|
194 | * <A HREF="Package-au.com.pharos.packing.html"><CODE>au.com.pharos.packing</CODE></A>
|
---|
195 | * package, or to define a new subclass of one of those strategies.
|
---|
196 | *
|
---|
197 | * @see au.com.pharos.packing.Packing
|
---|
198 | * @see GdbmFile#setKeyPacking(au.com.pharos.packing.Packing )
|
---|
199 | **/
|
---|
200 | public void setValuePacking(Packing newPacking) {
|
---|
201 | valuePacking = newPacking;
|
---|
202 | }
|
---|
203 |
|
---|
204 | // -----------------------------------------------------------------
|
---|
205 |
|
---|
206 | /** Returns a string indicating the version of the underlying GDBM
|
---|
207 | * library.
|
---|
208 | *
|
---|
209 | * @return the version of the native GDBM library.
|
---|
210 | **/
|
---|
211 | public static String getLibraryVersion()
|
---|
212 | {
|
---|
213 | return gdbm_getversion();
|
---|
214 | }
|
---|
215 |
|
---|
216 | /** Return a string indicating the version of the JavaGDBM library
|
---|
217 | * wrapper.
|
---|
218 | *
|
---|
219 | * <P>The most current release is available from the
|
---|
220 | * <A HREF="http://www.pharos.com.au/javagdbm/">JavaGDBM home page</A>.
|
---|
221 | *
|
---|
222 | * @return the release number of the JavaGDBM library
|
---|
223 | **/
|
---|
224 | public static String getWrapperVersion()
|
---|
225 | {
|
---|
226 | return gdbm_wrapperVersion();
|
---|
227 | }
|
---|
228 |
|
---|
229 | /** Indicate whether the database is writable.
|
---|
230 | *
|
---|
231 | * <P>Databases are opened in either read-write or read-only mode,
|
---|
232 | * and remain in that mode until they are closed.
|
---|
233 | *
|
---|
234 | * @return true if the database may be written; otherwise false.
|
---|
235 | *
|
---|
236 | * @see GdbmFile#GdbmFile(java.lang.String, int)
|
---|
237 | **/
|
---|
238 | public boolean isWritable()
|
---|
239 | {
|
---|
240 | return (openFlags & 0x03) != READER;
|
---|
241 | }
|
---|
242 |
|
---|
243 | /** Indicate whether the database is open or not.
|
---|
244 | *
|
---|
245 | * <P>A database is open from the point of creation until close()
|
---|
246 | * is called, if ever, after which it is closed.
|
---|
247 | *
|
---|
248 | * @return false if the database has been closed; otherwise true.
|
---|
249 | *
|
---|
250 | * @see GdbmFile#close()
|
---|
251 | **/
|
---|
252 | public boolean isOpen()
|
---|
253 | {
|
---|
254 | return dbf != 0;
|
---|
255 | }
|
---|
256 |
|
---|
257 |
|
---|
258 | /** Compact the database file.
|
---|
259 | *
|
---|
260 | * <P>If you have had a lot of deletions and would like to shrink the
|
---|
261 | * space used by the GDBM file, this function will reorganize the
|
---|
262 | * database. GDBM will not shorten the length of a GDBM file
|
---|
263 | * (deleted file space will be reused) except by using this
|
---|
264 | * reorganization, though it will reuse the vacant space.
|
---|
265 | *
|
---|
266 | * <P>The database must be writable.
|
---|
267 | */
|
---|
268 | public void reorganize()
|
---|
269 | throws GdbmException
|
---|
270 | {
|
---|
271 | gdbm_reorganize(dbf);
|
---|
272 | }
|
---|
273 |
|
---|
274 |
|
---|
275 | /** Flush changes to disk.
|
---|
276 | *
|
---|
277 | * <P>This function is only required when the database is
|
---|
278 | * opened with the FAST flag set. By default, changes are
|
---|
279 | * flushed to disk after every update.
|
---|
280 | *
|
---|
281 | * <P>The database must be writable.
|
---|
282 | *
|
---|
283 | * @see GdbmFile#FAST
|
---|
284 | **/
|
---|
285 | public void sync()
|
---|
286 | throws GdbmException
|
---|
287 | {
|
---|
288 | gdbm_sync(dbf);
|
---|
289 | }
|
---|
290 |
|
---|
291 |
|
---|
292 |
|
---|
293 | /** Retrieve the value corresponding to a particular key.
|
---|
294 | *
|
---|
295 | * @param key the key of the record to be retrieved
|
---|
296 | *
|
---|
297 | * @return the value of the record with the specified key; or
|
---|
298 | * null if the key is not present in the database.
|
---|
299 | */
|
---|
300 | public Object fetch(Object key) throws GdbmException
|
---|
301 | {
|
---|
302 | byte[] keyBytes = keyPacking.toBytes(key);
|
---|
303 | return valuePacking.fromBytes(gdbm_fetch(dbf, keyBytes));
|
---|
304 | }
|
---|
305 |
|
---|
306 |
|
---|
307 | /** Indicate whether the specified key is in the database,
|
---|
308 | * without returning the value.
|
---|
309 | *
|
---|
310 | * @param key the key of the record to be retrieved
|
---|
311 | *
|
---|
312 | * @return true if a record with the specified key is present;
|
---|
313 | * otherwise false.
|
---|
314 | */
|
---|
315 | public boolean exists(Object key) throws GdbmException
|
---|
316 | {
|
---|
317 | byte[] keyBytes = keyPacking.toBytes(key);
|
---|
318 | return gdbm_exists(dbf, keyBytes);
|
---|
319 | }
|
---|
320 |
|
---|
321 |
|
---|
322 |
|
---|
323 | /** Store a value in the database, replacing any existing value
|
---|
324 | * with the same key.
|
---|
325 | *
|
---|
326 | * @param key key under which to store the value
|
---|
327 | *
|
---|
328 | * @param value value to be stored
|
---|
329 | *
|
---|
330 | * @exception GdbmException if the object is a reader; or
|
---|
331 | * if an IO error occurs
|
---|
332 | **/
|
---|
333 | public void store(Object key, Object value)
|
---|
334 | throws GdbmException
|
---|
335 | {
|
---|
336 | byte[] keyBytes = keyPacking.toBytes(key);
|
---|
337 | byte[] valueBytes = valuePacking.toBytes(value);
|
---|
338 | gdbm_store(dbf, keyBytes, valueBytes, true);
|
---|
339 | }
|
---|
340 |
|
---|
341 |
|
---|
342 |
|
---|
343 | /** Store a value in the database, unless a record with the same
|
---|
344 | * key already exists.
|
---|
345 | *
|
---|
346 | * @param key key under which to store the value.
|
---|
347 | *
|
---|
348 | * @param value value to be stored.
|
---|
349 | *
|
---|
350 | * @exception GdbmException if a record with the specified key
|
---|
351 | * already exists; or if the object is a reader; or
|
---|
352 | * if an IO error occurs
|
---|
353 | */
|
---|
354 | public void storeNoReplace(Object key, Object value)
|
---|
355 | throws GdbmException
|
---|
356 | {
|
---|
357 | byte[] keyBytes = keyPacking.toBytes(key);
|
---|
358 | byte[] valueBytes = valuePacking.toBytes(value);
|
---|
359 | gdbm_store(dbf, keyBytes, valueBytes, false);
|
---|
360 | }
|
---|
361 |
|
---|
362 |
|
---|
363 |
|
---|
364 | /** Remove a record from the database.
|
---|
365 | *
|
---|
366 | * @param key key of the record to be removed
|
---|
367 | *
|
---|
368 | * @exception GdbmException if there is no record with the
|
---|
369 | * specified key; or if the object is a reader; or if an IO error
|
---|
370 | * occurs.
|
---|
371 | **/
|
---|
372 | public void delete(Object key)
|
---|
373 | throws GdbmException
|
---|
374 | {
|
---|
375 | byte[] keyBytes = keyPacking.toBytes(key);
|
---|
376 | gdbm_delete(dbf, keyBytes);
|
---|
377 | }
|
---|
378 |
|
---|
379 |
|
---|
380 |
|
---|
381 |
|
---|
382 |
|
---|
383 | // -----------------------------------------------------------------
|
---|
384 | // Iterator support
|
---|
385 |
|
---|
386 | // TODO: Use a flag/timestamp approach to throw an exception if
|
---|
387 | // somebody modifies the database while they're trying to iterate
|
---|
388 | // over it? Approach suggested by Doug Lea's Collections API. --
|
---|
389 | // mbp
|
---|
390 |
|
---|
391 | /** Return an enumeration which will return all of the keys for the
|
---|
392 | * database of the file in (apparently) random order.
|
---|
393 | *
|
---|
394 | * <P><B>Caution:</B> If the database is modified while
|
---|
395 | * an enumeration is in progress,
|
---|
396 | * then changes in the hash table may cause the enumeration to
|
---|
397 | * miss some records.
|
---|
398 | *
|
---|
399 | * @see java.util.Enumeration
|
---|
400 | **/
|
---|
401 | public Enumeration keys() throws GdbmException
|
---|
402 | {
|
---|
403 | // Return an inner class which will do the iteration in the
|
---|
404 | // context of this GdbmFile object.
|
---|
405 | return new KeyEnumeration();
|
---|
406 | }
|
---|
407 |
|
---|
408 | // Synchronization is performed in the GdbmFile's methods
|
---|
409 | class KeyEnumeration implements Enumeration {
|
---|
410 | private byte[] currKey, nextKey;
|
---|
411 |
|
---|
412 | KeyEnumeration() throws GdbmException {
|
---|
413 | currKey = null;
|
---|
414 | nextKey = getFirstKeyRaw();
|
---|
415 | }
|
---|
416 |
|
---|
417 | public boolean hasMoreElements() {
|
---|
418 | return nextKey != null;
|
---|
419 | }
|
---|
420 |
|
---|
421 | public Object nextElement() throws NoSuchElementException {
|
---|
422 | try {
|
---|
423 | currKey = nextKey;
|
---|
424 | if (currKey == null)
|
---|
425 | throw new NoSuchElementException();
|
---|
426 | else
|
---|
427 | nextKey = getNextKeyRaw(currKey);
|
---|
428 | return keyPacking.fromBytes(currKey);
|
---|
429 | } catch ( GdbmException e ) {
|
---|
430 | // Can't propagate this through java.util.Enumeration, dammit
|
---|
431 | throw new NoSuchElementException();
|
---|
432 | }
|
---|
433 | }
|
---|
434 | }
|
---|
435 |
|
---|
436 | /** Start a visit to all keys in the hashtable, using raw data values.
|
---|
437 | *
|
---|
438 | * @return the first key in the hash table as a byte array; or null if
|
---|
439 | * the database is empty. */
|
---|
440 | byte[] getFirstKeyRaw() throws GdbmException
|
---|
441 | {
|
---|
442 | return gdbm_firstkey(dbf);
|
---|
443 | }
|
---|
444 |
|
---|
445 | /** Return the first record in the hashtable.
|
---|
446 | *
|
---|
447 | * <P>Note that the database
|
---|
448 | * is not ordered, so the key returned is simply the first in the
|
---|
449 | * hashtable and effectively randomly selected.
|
---|
450 | *
|
---|
451 | * @return the first key in the hash table; or null if
|
---|
452 | * the database is empty.
|
---|
453 | *
|
---|
454 | * @see GdbmFile#getNextKey(java.lang.Object)
|
---|
455 | * @see GdbmFile#keys()
|
---|
456 | **/
|
---|
457 | Object getFirstKey() throws GdbmException
|
---|
458 | {
|
---|
459 | return keyPacking.fromBytes(getFirstKeyRaw());
|
---|
460 | }
|
---|
461 |
|
---|
462 |
|
---|
463 | /** Find and read the next key in the hashtable.
|
---|
464 | *
|
---|
465 | * @return the next key; or null if <EM>keyBytes</EM> is the last key
|
---|
466 | * in the hashtable.
|
---|
467 | **/
|
---|
468 | byte[] getNextKeyRaw(byte[] keyBytes) throws GdbmException
|
---|
469 | {
|
---|
470 | return gdbm_nextkey(dbf, keyBytes);
|
---|
471 | }
|
---|
472 |
|
---|
473 |
|
---|
474 | /** Check whether the database is empty.
|
---|
475 | *
|
---|
476 | * @return true if the database contains no records; otherwise
|
---|
477 | * false.
|
---|
478 | **/
|
---|
479 | public boolean isEmpty() throws GdbmException
|
---|
480 | {
|
---|
481 | return getFirstKeyRaw() == null;
|
---|
482 | }
|
---|
483 |
|
---|
484 |
|
---|
485 | /** Count the records in the database.
|
---|
486 | *
|
---|
487 | * <P>This is implemented by iterating over the database, and so is
|
---|
488 | * a fairly expensive operation.
|
---|
489 | *
|
---|
490 | * <P>This method locks the database to make sure the count is
|
---|
491 | * accurate.
|
---|
492 | *
|
---|
493 | * @return the number of records in the database
|
---|
494 | * @see GdbmFile#isEmpty()
|
---|
495 | **/
|
---|
496 | public synchronized int size() throws GdbmException
|
---|
497 | {
|
---|
498 | int s = 0;
|
---|
499 | byte[] key = getFirstKeyRaw();
|
---|
500 | while (key != null) {
|
---|
501 | s++;
|
---|
502 | key = getNextKeyRaw(key);
|
---|
503 | }
|
---|
504 | return s;
|
---|
505 | }
|
---|
506 |
|
---|
507 |
|
---|
508 | static {
|
---|
509 | String libraryFile = System.getProperty
|
---|
510 | ("au.com.pharos.gdbm.libraryFile");
|
---|
511 |
|
---|
512 | if (libraryFile != null) {
|
---|
513 | System.load(libraryFile);
|
---|
514 | } else {
|
---|
515 |
|
---|
516 | String gsdlos = System.getenv("GSDLOS");
|
---|
517 | if (gsdlos!=null && gsdlos.equals("darwin")) {
|
---|
518 | // As of MacOX 10.11 (El Capitan), effectivly supresses DYLD_LIBRARY_PATH (does
|
---|
519 | // not propagate it to child processes). This is a result of changes to their
|
---|
520 | // security model, and seems to come into effect for 'untrusted' executables.
|
---|
521 | // Greenstone run as a regular user, is 'unstrusted'. It is possible, with
|
---|
522 | // admin rights, to override this, however that is not really a viable solution
|
---|
523 | // for our project. Hence the change here to use Systen.load() with an
|
---|
524 | // absolute pathname, rather than rely of System.loadLibrary().
|
---|
525 |
|
---|
526 | String gsdl3srchome = System.getenv("GSDL3SRCHOME");
|
---|
527 | String full_jni_library = gsdl3srchome + "/lib/jni/libgdbmjava.jnilib";
|
---|
528 | System.load(full_jni_library);
|
---|
529 | }
|
---|
530 | else {
|
---|
531 |
|
---|
532 | System.loadLibrary("gdbmjava");
|
---|
533 | }
|
---|
534 | }
|
---|
535 | }
|
---|
536 |
|
---|
537 | private synchronized native long
|
---|
538 | gdbm_open(String fileName, int flags)
|
---|
539 | throws GdbmException;
|
---|
540 |
|
---|
541 | private synchronized native void
|
---|
542 | gdbm_close(long dbf);
|
---|
543 |
|
---|
544 | private synchronized native void
|
---|
545 | gdbm_store(long dbf,
|
---|
546 | byte[] key,
|
---|
547 | byte[] content,
|
---|
548 | boolean replace);
|
---|
549 |
|
---|
550 | private synchronized native byte[]
|
---|
551 | gdbm_fetch(long dbf,
|
---|
552 | byte[] key);
|
---|
553 |
|
---|
554 | private synchronized native boolean
|
---|
555 | gdbm_exists(long dbf,
|
---|
556 | byte[] key);
|
---|
557 |
|
---|
558 | private synchronized native void
|
---|
559 | gdbm_delete(long dbf,
|
---|
560 | byte[] key);
|
---|
561 |
|
---|
562 | private synchronized native byte[]
|
---|
563 | gdbm_firstkey(long dbf)
|
---|
564 | throws GdbmException;
|
---|
565 |
|
---|
566 | private synchronized native byte[]
|
---|
567 | gdbm_nextkey(long dbf, byte[] key)
|
---|
568 | throws GdbmException;
|
---|
569 |
|
---|
570 | private synchronized static native String
|
---|
571 | gdbm_getversion();
|
---|
572 |
|
---|
573 | private synchronized static native String
|
---|
574 | gdbm_wrapperVersion();
|
---|
575 |
|
---|
576 | private synchronized native void
|
---|
577 | gdbm_reorganize(long dbf);
|
---|
578 |
|
---|
579 | private synchronized native void
|
---|
580 | gdbm_sync(long dbf);
|
---|
581 | }
|
---|