Implement wrapper for get_estimated_range_size API

This is new in 6.3.
diff --git a/c_src/main.c b/c_src/main.c
index 7750a96..8cb03b0 100644
--- a/c_src/main.c
+++ b/c_src/main.c
@@ -1144,6 +1144,57 @@
     return erlfdb_create_future(env, future, ErlFDB_FT_VALUE);
 }
 
+#if FDB_API_VERSION >= 630
+static ERL_NIF_TERM
+erlfdb_transaction_get_estimated_range_size(
+        ErlNifEnv* env,
+        int argc,
+        const ERL_NIF_TERM argv[]
+    )
+{
+    ErlFDBSt* st = (ErlFDBSt*) enif_priv_data(env);
+    ErlFDBTransaction* t;
+    ErlNifBinary skey;
+    ErlNifBinary ekey;
+    FDBFuture* future;
+    void* res;
+
+    if(st->lib_state != ErlFDB_CONNECTED) {
+        return enif_make_badarg(env);
+    }
+
+    if(argc != 3) {
+        return enif_make_badarg(env);
+    }
+
+    if(!enif_get_resource(env, argv[0], ErlFDBTransactionRes, &res)) {
+        return enif_make_badarg(env);
+    }
+    t = (ErlFDBTransaction*) res;
+
+    if(!erlfdb_transaction_is_owner(env, t)) {
+        return enif_make_badarg(env);
+    }
+
+    if(!enif_inspect_binary(env, argv[1], &skey)) {
+        return enif_make_badarg(env);
+    }
+
+    if(!enif_inspect_binary(env, argv[2], &ekey)) {
+        return enif_make_badarg(env);
+    }
+
+    future = fdb_transaction_get_estimated_range_size_bytes(
+            t->transaction,
+            (uint8_t*) skey.data,
+            skey.size,
+            (uint8_t*) ekey.data,
+            ekey.size
+        );
+
+    return erlfdb_create_future(env, future, ErlFDB_FT_INT64);
+}
+#endif
 
 static ERL_NIF_TERM
 erlfdb_transaction_get_key(
@@ -2237,6 +2288,10 @@
     NIF_FUNC(erlfdb_transaction_has_watches, 1),
     NIF_FUNC(erlfdb_transaction_get_writes_allowed, 1),
 
+    #if FDB_API_VERSION >= 630
+    NIF_FUNC(erlfdb_transaction_get_estimated_range_size, 3),
+    #endif
+
     NIF_FUNC(erlfdb_get_error, 1),
     NIF_FUNC(erlfdb_error_predicate, 2)
 };
diff --git a/src/erlfdb.erl b/src/erlfdb.erl
index d6f3be9..7c26750 100644
--- a/src/erlfdb.erl
+++ b/src/erlfdb.erl
@@ -110,8 +110,9 @@
     has_watches/1,
     get_writes_allowed/1,
 
-    % Locality
+    % Locality and Statistics
     get_addresses_for_key/2,
+    get_estimated_range_size/3,
 
     % Get conflict information
     get_conflicting_keys/1,
@@ -545,6 +546,11 @@
 get_addresses_for_key(?IS_SS = SS, Key) ->
     get_addresses_for_key(?GET_TX(SS), Key).
 
+get_estimated_range_size(?IS_TX = Tx, StartKey, EndKey) ->
+    erlfdb_nif:transaction_get_estimated_range_size(Tx, StartKey, EndKey);
+get_estimated_range_size(?IS_SS = SS, StartKey, EndKey) ->
+    erlfdb_nif:transaction_get_estimated_range_size(?GET_TX(SS), StartKey, EndKey).
+
 get_conflicting_keys(?IS_TX = Tx) ->
     StartKey = <<16#FF, 16#FF, "/transaction/conflicting_keys/">>,
     EndKey = <<16#FF, 16#FF, "/transaction/conflicting_keys/", 16#FF>>,
diff --git a/src/erlfdb_nif.erl b/src/erlfdb_nif.erl
index b8f5895..4e70303 100644
--- a/src/erlfdb_nif.erl
+++ b/src/erlfdb_nif.erl
@@ -36,6 +36,7 @@
     transaction_set_read_version/2,
     transaction_get_read_version/1,
     transaction_get/3,
+    transaction_get_estimated_range_size/3,
     transaction_get_key/3,
     transaction_get_addresses_for_key/2,
     transaction_get_range/9,
@@ -266,6 +267,14 @@
 transaction_get({erlfdb_transaction, Tx}, Key, Snapshot) ->
     erlfdb_transaction_get(Tx, Key, Snapshot).
 
+-spec transaction_get_estimated_range_size(
+    transaction(),
+    StartKey :: binary(),
+    EndKey :: binary()
+) -> future().
+transaction_get_estimated_range_size({erlfdb_transaction, Tx}, StartKey, EndKey) ->
+    erlfdb_transaction_get_estimated_range_size(Tx, StartKey, EndKey).
+
 -spec transaction_get_key(
     transaction(),
     KeySelector :: key_selector(),
@@ -511,6 +520,7 @@
 erlfdb_transaction_set_read_version(_Transaction, _Version) -> ?NOT_LOADED.
 erlfdb_transaction_get_read_version(_Transaction) -> ?NOT_LOADED.
 erlfdb_transaction_get(_Transaction, _Key, _Snapshot) -> ?NOT_LOADED.
+erlfdb_transaction_get_estimated_range_size(_Transaction, _SKey, _EKey) -> ?NOT_LOADED.
 erlfdb_transaction_get_key(_Transaction, _KeySelector, _Snapshot) -> ?NOT_LOADED.
 erlfdb_transaction_get_addresses_for_key(_Transaction, _Key) -> ?NOT_LOADED.
 erlfdb_transaction_get_range(
diff --git a/test/tester.es b/test/tester.es
index 6ebff3e..c1d3b3c 100755
--- a/test/tester.es
+++ b/test/tester.es
@@ -485,6 +485,22 @@
     end,
     St;
 
+execute(TxObj, St, <<"GET_ESTIMATED_RANGE_SIZE">>) ->
+    [StartKey, EndKey] = stack_pop(St, 2),
+    Value = case erlfdb:get_estimated_range_size(TxObj, StartKey, EndKey) of
+        {erlfdb_future, _, _} = Future ->
+            erlfdb:wait(Future);
+        Else ->
+            Else
+    end,
+    case Value of
+        Size when is_integer(Size) ->
+            stack_push(St, <<"GOT_ESTIMATED_RANGE_SIZE">>);
+        BadResult ->
+            stack_push(St, BadResult)
+    end,
+    St;
+
 execute(TxObj, St, <<"GET_KEY">>) ->
     [Key, OrEqual, Offset, Prefix] = stack_pop(St, 4),
     Selector = {Key, OrEqual, Offset},