1616
1717import static org .lwjgl .system .MemoryStack .stackPush ;
1818import static org .lwjgl .system .MemoryUtil .NULL ;
19+ import static org .lwjgl .util .lmdb .LMDB .MDB_KEYEXIST ;
1920import static org .lwjgl .util .lmdb .LMDB .MDB_NOTFOUND ;
2021import static org .lwjgl .util .lmdb .LMDB .MDB_RDONLY ;
2122import static org .lwjgl .util .lmdb .LMDB .MDB_SUCCESS ;
3031import java .nio .ByteBuffer ;
3132import java .nio .IntBuffer ;
3233import java .util .Comparator ;
34+ import java .util .concurrent .ConcurrentHashMap ;
3335
3436import org .lwjgl .PointerBuffer ;
3537import org .lwjgl .system .MemoryStack ;
@@ -48,11 +50,17 @@ final class LmdbUtil {
4850 */
4951 static final long MIN_FREE_SPACE = 524_288 ; // 512 KiB
5052
53+ /**
54+ * Percentage free space in an LMDB db before automatically resizing the map. Default is 80%.
55+ */
56+ @ SuppressWarnings ("StaticNonFinalField" )
57+ public static int PERCENTAGE_FULL_TRIGGERS_RESIZE = 80 ;
58+
5159 private LmdbUtil () {
5260 }
5361
5462 static int E (int rc ) throws IOException {
55- if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND ) {
63+ if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND && rc != MDB_KEYEXIST ) {
5664 throw new IOException (mdb_strerror (rc ));
5765 }
5866 return rc ;
@@ -97,7 +105,7 @@ static <T> T transaction(long env, Transaction<T> transaction) throws IOExceptio
97105 int err ;
98106 try {
99107 ret = transaction .exec (stack , txn );
100- err = mdb_txn_commit (txn );
108+ err = E ( mdb_txn_commit (txn ) );
101109 } catch (Throwable t ) {
102110 mdb_txn_abort (txn );
103111 throw t ;
@@ -156,6 +164,11 @@ private static long mdbTxnMtNextPgno(long txn) {
156164 */
157165 static boolean requiresResize (long mapSize , long pageSize , long txn , long requiredSize ) {
158166 long nextPageNo = mdbTxnMtNextPgno (txn );
167+ double percentageUsed = (100.0 / mapSize ) * (nextPageNo * pageSize );
168+ if (percentageUsed > PERCENTAGE_FULL_TRIGGERS_RESIZE ) {
169+ return true ;
170+ }
171+
159172 return mapSize - nextPageNo * pageSize < Math .max (requiredSize , MIN_FREE_SPACE );
160173 }
161174
@@ -173,6 +186,11 @@ static long autoGrowMapSize(long mapSize, long pageSize, long requiredSize) {
173186 return mapSize % pageSize == 0 ? mapSize : mapSize + (mapSize / pageSize + 1 ) * pageSize ;
174187 }
175188
189+ public static long getNewSize (int pageSize , long txn , long requiredSize ) {
190+ long nextPgno = mdbTxnMtNextPgno (txn );
191+ return (nextPgno * pageSize ) + requiredSize ;
192+ }
193+
176194 @ FunctionalInterface
177195 interface Transaction <T > {
178196
0 commit comments