mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-12 15:01:38 +03:00
Merge 4df706b842
into release/next-js
This commit is contained in:
commit
df3ec7bfca
@ -25,4 +25,11 @@ in {
|
||||
ldapSupport = false;
|
||||
brotliSupport = false;
|
||||
};
|
||||
|
||||
lmdb = prev.lmdb.overrideAttrs (attrs: {
|
||||
patches =
|
||||
optionalList attrs.patches ++ prev.lib.optional prev.stdenv.isDarwin [
|
||||
../pkgs/lmdb/darwin-fsync.patch
|
||||
];
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ lib, stdenv, darwin, haskell-nix, gmp, zlib, libffi, brass
|
||||
{ lib, stdenv, darwin, haskell-nix, lmdb, gmp, zlib, libffi, brass
|
||||
, enableStatic ? stdenv.hostPlatform.isStatic }:
|
||||
|
||||
haskell-nix.stackProject {
|
||||
@ -65,6 +65,7 @@ haskell-nix.stackProject {
|
||||
enableShared = !enableStatic;
|
||||
|
||||
configureFlags = lib.optionals enableStatic [
|
||||
"--ghc-option=-optl=-L${lmdb}/lib"
|
||||
"--ghc-option=-optl=-L${gmp}/lib"
|
||||
"--ghc-option=-optl=-L${libffi}/lib"
|
||||
"--ghc-option=-optl=-L${zlib}/lib"
|
||||
|
13
nix/pkgs/lmdb/darwin-fsync.patch
Normal file
13
nix/pkgs/lmdb/darwin-fsync.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
|
||||
index fe65e30..0070215 100644
|
||||
--- a/libraries/liblmdb/mdb.c
|
||||
+++ b/libraries/liblmdb/mdb.c
|
||||
@@ -2526,7 +2526,7 @@ mdb_env_sync(MDB_env *env, int force)
|
||||
rc = ErrCode();
|
||||
} else
|
||||
#endif
|
||||
- if (MDB_FDATASYNC(env->me_fd))
|
||||
+ if (fcntl(env->me_fd, F_FULLFSYNC, 0))
|
||||
rc = ErrCode();
|
||||
}
|
||||
}
|
@ -29,4 +29,10 @@
|
||||
%- expect-fail
|
||||
|. .*(~ [%6 [%1 2] [%1 42] %1 43])
|
||||
==
|
||||
:: nock 9 should support axis 1
|
||||
::
|
||||
++ test-call-one
|
||||
%+ expect-eq
|
||||
!> 0
|
||||
!> .*([3 0 1] [9 1 [0 1]])
|
||||
--
|
12
pkg/hs/lmdb-static/.gitignore
vendored
12
pkg/hs/lmdb-static/.gitignore
vendored
@ -1,12 +0,0 @@
|
||||
dist
|
||||
cabal-dev
|
||||
*.o
|
||||
*.hi
|
||||
*.chi
|
||||
*.chs.h
|
||||
.virtualenv
|
||||
.hsenv
|
||||
.cabal-sandbox/
|
||||
cabal.sandbox.config
|
||||
cabal.config
|
||||
*~
|
@ -1,24 +0,0 @@
|
||||
Copyright (c) 2014, David Barbour
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@ -1,13 +0,0 @@
|
||||
This is a hack to avoid dynamic depencency on lmdb:
|
||||
|
||||
This is a vendoring of `haskell-lmdb` and `lmdb` modified to include
|
||||
the c-build of `lmdb` statically into `haskell-lmdb`.
|
||||
|
||||
```
|
||||
haskell-lmdb:
|
||||
repo: https://github.com/dmbarbour/haskell-lmdb.git
|
||||
hash: 1e562429874919d445576c87cf118d7de5112b5b
|
||||
lmdb:
|
||||
repo: https://github.com/LMDB/lmdb.git
|
||||
hash: c3e6b4209eed13af4a3670e5f04f42169c08e5c6
|
||||
```
|
@ -1,3 +0,0 @@
|
||||
import Distribution.Simple
|
||||
main = defaultMain
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,421 +0,0 @@
|
||||
/** @file midl.c
|
||||
* @brief ldap bdb back-end ID List functions */
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2000-2019 The OpenLDAP Foundation.
|
||||
* Portions Copyright 2001-2018 Howard Chu, Symas Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include "midl.h"
|
||||
|
||||
/** @defgroup internal LMDB Internals
|
||||
* @{
|
||||
*/
|
||||
/** @defgroup idls ID List Management
|
||||
* @{
|
||||
*/
|
||||
#define CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) )
|
||||
|
||||
unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id )
|
||||
{
|
||||
/*
|
||||
* binary search of id in ids
|
||||
* if found, returns position of id
|
||||
* if not found, returns first position greater than id
|
||||
*/
|
||||
unsigned base = 0;
|
||||
unsigned cursor = 1;
|
||||
int val = 0;
|
||||
unsigned n = ids[0];
|
||||
|
||||
while( 0 < n ) {
|
||||
unsigned pivot = n >> 1;
|
||||
cursor = base + pivot + 1;
|
||||
val = CMP( ids[cursor], id );
|
||||
|
||||
if( val < 0 ) {
|
||||
n = pivot;
|
||||
|
||||
} else if ( val > 0 ) {
|
||||
base = cursor;
|
||||
n -= pivot + 1;
|
||||
|
||||
} else {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
if( val > 0 ) {
|
||||
++cursor;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
#if 0 /* superseded by append/sort */
|
||||
int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
|
||||
{
|
||||
unsigned x, i;
|
||||
|
||||
x = mdb_midl_search( ids, id );
|
||||
assert( x > 0 );
|
||||
|
||||
if( x < 1 ) {
|
||||
/* internal error */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ( x <= ids[0] && ids[x] == id ) {
|
||||
/* duplicate */
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ++ids[0] >= MDB_IDL_DB_MAX ) {
|
||||
/* no room */
|
||||
--ids[0];
|
||||
return -2;
|
||||
|
||||
} else {
|
||||
/* insert id */
|
||||
for (i=ids[0]; i>x; i--)
|
||||
ids[i] = ids[i-1];
|
||||
ids[x] = id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
MDB_IDL mdb_midl_alloc(int num)
|
||||
{
|
||||
MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
|
||||
if (ids) {
|
||||
*ids++ = num;
|
||||
*ids = 0;
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void mdb_midl_free(MDB_IDL ids)
|
||||
{
|
||||
if (ids)
|
||||
free(ids-1);
|
||||
}
|
||||
|
||||
void mdb_midl_shrink( MDB_IDL *idp )
|
||||
{
|
||||
MDB_IDL ids = *idp;
|
||||
if (*(--ids) > MDB_IDL_UM_MAX &&
|
||||
(ids = realloc(ids, (MDB_IDL_UM_MAX+2) * sizeof(MDB_ID))))
|
||||
{
|
||||
*ids++ = MDB_IDL_UM_MAX;
|
||||
*idp = ids;
|
||||
}
|
||||
}
|
||||
|
||||
static int mdb_midl_grow( MDB_IDL *idp, int num )
|
||||
{
|
||||
MDB_IDL idn = *idp-1;
|
||||
/* grow it */
|
||||
idn = realloc(idn, (*idn + num + 2) * sizeof(MDB_ID));
|
||||
if (!idn)
|
||||
return ENOMEM;
|
||||
*idn++ += num;
|
||||
*idp = idn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdb_midl_need( MDB_IDL *idp, unsigned num )
|
||||
{
|
||||
MDB_IDL ids = *idp;
|
||||
num += ids[0];
|
||||
if (num > ids[-1]) {
|
||||
num = (num + num/4 + (256 + 2)) & -256;
|
||||
if (!(ids = realloc(ids-1, num * sizeof(MDB_ID))))
|
||||
return ENOMEM;
|
||||
*ids++ = num - 2;
|
||||
*idp = ids;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
|
||||
{
|
||||
MDB_IDL ids = *idp;
|
||||
/* Too big? */
|
||||
if (ids[0] >= ids[-1]) {
|
||||
if (mdb_midl_grow(idp, MDB_IDL_UM_MAX))
|
||||
return ENOMEM;
|
||||
ids = *idp;
|
||||
}
|
||||
ids[0]++;
|
||||
ids[ids[0]] = id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app )
|
||||
{
|
||||
MDB_IDL ids = *idp;
|
||||
/* Too big? */
|
||||
if (ids[0] + app[0] >= ids[-1]) {
|
||||
if (mdb_midl_grow(idp, app[0]))
|
||||
return ENOMEM;
|
||||
ids = *idp;
|
||||
}
|
||||
memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID));
|
||||
ids[0] += app[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n )
|
||||
{
|
||||
MDB_ID *ids = *idp, len = ids[0];
|
||||
/* Too big? */
|
||||
if (len + n > ids[-1]) {
|
||||
if (mdb_midl_grow(idp, n | MDB_IDL_UM_MAX))
|
||||
return ENOMEM;
|
||||
ids = *idp;
|
||||
}
|
||||
ids[0] = len + n;
|
||||
ids += len;
|
||||
while (n)
|
||||
ids[n--] = id++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge )
|
||||
{
|
||||
MDB_ID old_id, merge_id, i = merge[0], j = idl[0], k = i+j, total = k;
|
||||
idl[0] = (MDB_ID)-1; /* delimiter for idl scan below */
|
||||
old_id = idl[j];
|
||||
while (i) {
|
||||
merge_id = merge[i--];
|
||||
for (; old_id < merge_id; old_id = idl[--j])
|
||||
idl[k--] = old_id;
|
||||
idl[k--] = merge_id;
|
||||
}
|
||||
idl[0] = total;
|
||||
}
|
||||
|
||||
/* Quicksort + Insertion sort for small arrays */
|
||||
|
||||
#define SMALL 8
|
||||
#define MIDL_SWAP(a,b) { itmp=(a); (a)=(b); (b)=itmp; }
|
||||
|
||||
void
|
||||
mdb_midl_sort( MDB_IDL ids )
|
||||
{
|
||||
/* Max possible depth of int-indexed tree * 2 items/level */
|
||||
int istack[sizeof(int)*CHAR_BIT * 2];
|
||||
int i,j,k,l,ir,jstack;
|
||||
MDB_ID a, itmp;
|
||||
|
||||
ir = (int)ids[0];
|
||||
l = 1;
|
||||
jstack = 0;
|
||||
for(;;) {
|
||||
if (ir - l < SMALL) { /* Insertion sort */
|
||||
for (j=l+1;j<=ir;j++) {
|
||||
a = ids[j];
|
||||
for (i=j-1;i>=1;i--) {
|
||||
if (ids[i] >= a) break;
|
||||
ids[i+1] = ids[i];
|
||||
}
|
||||
ids[i+1] = a;
|
||||
}
|
||||
if (jstack == 0) break;
|
||||
ir = istack[jstack--];
|
||||
l = istack[jstack--];
|
||||
} else {
|
||||
k = (l + ir) >> 1; /* Choose median of left, center, right */
|
||||
MIDL_SWAP(ids[k], ids[l+1]);
|
||||
if (ids[l] < ids[ir]) {
|
||||
MIDL_SWAP(ids[l], ids[ir]);
|
||||
}
|
||||
if (ids[l+1] < ids[ir]) {
|
||||
MIDL_SWAP(ids[l+1], ids[ir]);
|
||||
}
|
||||
if (ids[l] < ids[l+1]) {
|
||||
MIDL_SWAP(ids[l], ids[l+1]);
|
||||
}
|
||||
i = l+1;
|
||||
j = ir;
|
||||
a = ids[l+1];
|
||||
for(;;) {
|
||||
do i++; while(ids[i] > a);
|
||||
do j--; while(ids[j] < a);
|
||||
if (j < i) break;
|
||||
MIDL_SWAP(ids[i],ids[j]);
|
||||
}
|
||||
ids[l+1] = ids[j];
|
||||
ids[j] = a;
|
||||
jstack += 2;
|
||||
if (ir-i+1 >= j-l) {
|
||||
istack[jstack] = ir;
|
||||
istack[jstack-1] = i;
|
||||
ir = j-1;
|
||||
} else {
|
||||
istack[jstack] = j-1;
|
||||
istack[jstack-1] = l;
|
||||
l = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id )
|
||||
{
|
||||
/*
|
||||
* binary search of id in ids
|
||||
* if found, returns position of id
|
||||
* if not found, returns first position greater than id
|
||||
*/
|
||||
unsigned base = 0;
|
||||
unsigned cursor = 1;
|
||||
int val = 0;
|
||||
unsigned n = (unsigned)ids[0].mid;
|
||||
|
||||
while( 0 < n ) {
|
||||
unsigned pivot = n >> 1;
|
||||
cursor = base + pivot + 1;
|
||||
val = CMP( id, ids[cursor].mid );
|
||||
|
||||
if( val < 0 ) {
|
||||
n = pivot;
|
||||
|
||||
} else if ( val > 0 ) {
|
||||
base = cursor;
|
||||
n -= pivot + 1;
|
||||
|
||||
} else {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
if( val > 0 ) {
|
||||
++cursor;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id )
|
||||
{
|
||||
unsigned x, i;
|
||||
|
||||
x = mdb_mid2l_search( ids, id->mid );
|
||||
|
||||
if( x < 1 ) {
|
||||
/* internal error */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ( x <= ids[0].mid && ids[x].mid == id->mid ) {
|
||||
/* duplicate */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ids[0].mid >= MDB_IDL_UM_MAX ) {
|
||||
/* too big */
|
||||
return -2;
|
||||
|
||||
} else {
|
||||
/* insert id */
|
||||
ids[0].mid++;
|
||||
for (i=(unsigned)ids[0].mid; i>x; i--)
|
||||
ids[i] = ids[i-1];
|
||||
ids[x] = *id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id )
|
||||
{
|
||||
/* Too big? */
|
||||
if (ids[0].mid >= MDB_IDL_UM_MAX) {
|
||||
return -2;
|
||||
}
|
||||
ids[0].mid++;
|
||||
ids[ids[0].mid] = *id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MDB_VL32
|
||||
unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id )
|
||||
{
|
||||
/*
|
||||
* binary search of id in ids
|
||||
* if found, returns position of id
|
||||
* if not found, returns first position greater than id
|
||||
*/
|
||||
unsigned base = 0;
|
||||
unsigned cursor = 1;
|
||||
int val = 0;
|
||||
unsigned n = (unsigned)ids[0].mid;
|
||||
|
||||
while( 0 < n ) {
|
||||
unsigned pivot = n >> 1;
|
||||
cursor = base + pivot + 1;
|
||||
val = CMP( id, ids[cursor].mid );
|
||||
|
||||
if( val < 0 ) {
|
||||
n = pivot;
|
||||
|
||||
} else if ( val > 0 ) {
|
||||
base = cursor;
|
||||
n -= pivot + 1;
|
||||
|
||||
} else {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
if( val > 0 ) {
|
||||
++cursor;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
int mdb_mid3l_insert( MDB_ID3L ids, MDB_ID3 *id )
|
||||
{
|
||||
unsigned x, i;
|
||||
|
||||
x = mdb_mid3l_search( ids, id->mid );
|
||||
|
||||
if( x < 1 ) {
|
||||
/* internal error */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ( x <= ids[0].mid && ids[x].mid == id->mid ) {
|
||||
/* duplicate */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* insert id */
|
||||
ids[0].mid++;
|
||||
for (i=(unsigned)ids[0].mid; i>x; i--)
|
||||
ids[i] = ids[i-1];
|
||||
ids[x] = *id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MDB_VL32 */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
@ -1,200 +0,0 @@
|
||||
/** @file midl.h
|
||||
* @brief LMDB ID List header file.
|
||||
*
|
||||
* This file was originally part of back-bdb but has been
|
||||
* modified for use in libmdb. Most of the macros defined
|
||||
* in this file are unused, just left over from the original.
|
||||
*
|
||||
* This file is only used internally in libmdb and its definitions
|
||||
* are not exposed publicly.
|
||||
*/
|
||||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 2000-2019 The OpenLDAP Foundation.
|
||||
* Portions Copyright 2001-2019 Howard Chu, Symas Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_MIDL_H_
|
||||
#define _MDB_MIDL_H_
|
||||
|
||||
#include "lmdb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup internal LMDB Internals
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup idls ID List Management
|
||||
* @{
|
||||
*/
|
||||
/** A generic unsigned ID number. These were entryIDs in back-bdb.
|
||||
* Preferably it should have the same size as a pointer.
|
||||
*/
|
||||
typedef mdb_size_t MDB_ID;
|
||||
|
||||
/** An IDL is an ID List, a sorted array of IDs. The first
|
||||
* element of the array is a counter for how many actual
|
||||
* IDs are in the list. In the original back-bdb code, IDLs are
|
||||
* sorted in ascending order. For libmdb IDLs are sorted in
|
||||
* descending order.
|
||||
*/
|
||||
typedef MDB_ID *MDB_IDL;
|
||||
|
||||
/* IDL sizes - likely should be even bigger
|
||||
* limiting factors: sizeof(ID), thread stack size
|
||||
*/
|
||||
#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
|
||||
#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)
|
||||
#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))
|
||||
|
||||
#define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1)
|
||||
#define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1)
|
||||
|
||||
#define MDB_IDL_SIZEOF(ids) (((ids)[0]+1) * sizeof(MDB_ID))
|
||||
#define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 )
|
||||
#define MDB_IDL_CPY( dst, src ) (memcpy( dst, src, MDB_IDL_SIZEOF( src ) ))
|
||||
#define MDB_IDL_FIRST( ids ) ( (ids)[1] )
|
||||
#define MDB_IDL_LAST( ids ) ( (ids)[(ids)[0]] )
|
||||
|
||||
/** Current max length of an #mdb_midl_alloc()ed IDL */
|
||||
#define MDB_IDL_ALLOCLEN( ids ) ( (ids)[-1] )
|
||||
|
||||
/** Append ID to IDL. The IDL must be big enough. */
|
||||
#define mdb_midl_xappend(idl, id) do { \
|
||||
MDB_ID *xidl = (idl), xlen = ++(xidl[0]); \
|
||||
xidl[xlen] = (id); \
|
||||
} while (0)
|
||||
|
||||
/** Search for an ID in an IDL.
|
||||
* @param[in] ids The IDL to search.
|
||||
* @param[in] id The ID to search for.
|
||||
* @return The index of the first ID greater than or equal to \b id.
|
||||
*/
|
||||
unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id );
|
||||
|
||||
/** Allocate an IDL.
|
||||
* Allocates memory for an IDL of the given size.
|
||||
* @return IDL on success, NULL on failure.
|
||||
*/
|
||||
MDB_IDL mdb_midl_alloc(int num);
|
||||
|
||||
/** Free an IDL.
|
||||
* @param[in] ids The IDL to free.
|
||||
*/
|
||||
void mdb_midl_free(MDB_IDL ids);
|
||||
|
||||
/** Shrink an IDL.
|
||||
* Return the IDL to the default size if it has grown larger.
|
||||
* @param[in,out] idp Address of the IDL to shrink.
|
||||
*/
|
||||
void mdb_midl_shrink(MDB_IDL *idp);
|
||||
|
||||
/** Make room for num additional elements in an IDL.
|
||||
* @param[in,out] idp Address of the IDL.
|
||||
* @param[in] num Number of elements to make room for.
|
||||
* @return 0 on success, ENOMEM on failure.
|
||||
*/
|
||||
int mdb_midl_need(MDB_IDL *idp, unsigned num);
|
||||
|
||||
/** Append an ID onto an IDL.
|
||||
* @param[in,out] idp Address of the IDL to append to.
|
||||
* @param[in] id The ID to append.
|
||||
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||
*/
|
||||
int mdb_midl_append( MDB_IDL *idp, MDB_ID id );
|
||||
|
||||
/** Append an IDL onto an IDL.
|
||||
* @param[in,out] idp Address of the IDL to append to.
|
||||
* @param[in] app The IDL to append.
|
||||
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||
*/
|
||||
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app );
|
||||
|
||||
/** Append an ID range onto an IDL.
|
||||
* @param[in,out] idp Address of the IDL to append to.
|
||||
* @param[in] id The lowest ID to append.
|
||||
* @param[in] n Number of IDs to append.
|
||||
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||
*/
|
||||
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n );
|
||||
|
||||
/** Merge an IDL onto an IDL. The destination IDL must be big enough.
|
||||
* @param[in] idl The IDL to merge into.
|
||||
* @param[in] merge The IDL to merge.
|
||||
*/
|
||||
void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge );
|
||||
|
||||
/** Sort an IDL.
|
||||
* @param[in,out] ids The IDL to sort.
|
||||
*/
|
||||
void mdb_midl_sort( MDB_IDL ids );
|
||||
|
||||
/** An ID2 is an ID/pointer pair.
|
||||
*/
|
||||
typedef struct MDB_ID2 {
|
||||
MDB_ID mid; /**< The ID */
|
||||
void *mptr; /**< The pointer */
|
||||
} MDB_ID2;
|
||||
|
||||
/** An ID2L is an ID2 List, a sorted array of ID2s.
|
||||
* The first element's \b mid member is a count of how many actual
|
||||
* elements are in the array. The \b mptr member of the first element is unused.
|
||||
* The array is sorted in ascending order by \b mid.
|
||||
*/
|
||||
typedef MDB_ID2 *MDB_ID2L;
|
||||
|
||||
/** Search for an ID in an ID2L.
|
||||
* @param[in] ids The ID2L to search.
|
||||
* @param[in] id The ID to search for.
|
||||
* @return The index of the first ID2 whose \b mid member is greater than or equal to \b id.
|
||||
*/
|
||||
unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id );
|
||||
|
||||
|
||||
/** Insert an ID2 into a ID2L.
|
||||
* @param[in,out] ids The ID2L to insert into.
|
||||
* @param[in] id The ID2 to insert.
|
||||
* @return 0 on success, -1 if the ID was already present in the ID2L.
|
||||
*/
|
||||
int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id );
|
||||
|
||||
/** Append an ID2 into a ID2L.
|
||||
* @param[in,out] ids The ID2L to append into.
|
||||
* @param[in] id The ID2 to append.
|
||||
* @return 0 on success, -2 if the ID2L is too big.
|
||||
*/
|
||||
int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id );
|
||||
|
||||
#ifdef MDB_VL32
|
||||
typedef struct MDB_ID3 {
|
||||
MDB_ID mid; /**< The ID */
|
||||
void *mptr; /**< The pointer */
|
||||
unsigned int mcnt; /**< Number of pages */
|
||||
unsigned int mref; /**< Refcounter */
|
||||
} MDB_ID3;
|
||||
|
||||
typedef MDB_ID3 *MDB_ID3L;
|
||||
|
||||
unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id );
|
||||
int mdb_mid3l_insert( MDB_ID3L ids, MDB_ID3 *id );
|
||||
|
||||
#endif /* MDB_VL32 */
|
||||
/** @} */
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _MDB_MIDL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +0,0 @@
|
||||
Name: lmdb-static
|
||||
Version: 0.2.5
|
||||
Synopsis: Lightning MDB bindings
|
||||
Category: Database
|
||||
Description:
|
||||
LMDB is a read-optimized Berkeley DB replacement developed by Symas
|
||||
for the OpenLDAP project. LMDB has impressive performance characteristics
|
||||
and a friendly BSD-style OpenLDAP license. See <http://symas.com/mdb/>.
|
||||
.
|
||||
This library has Haskell bindings to the LMDB library. You must install
|
||||
the lmdb development files before installing this library,
|
||||
e.g. `sudo apt-get install liblmdb-dev` works for Ubuntu 14.04.
|
||||
.
|
||||
For now, only a low level interface is provided, and the author is moving
|
||||
on to use LMDB rather than further develop its bindings. If a higher level
|
||||
API is desired, please consider contributing, or develop a separate package.
|
||||
|
||||
Author: David Barbour
|
||||
Maintainer: dmbarbour@gmail.com
|
||||
Homepage: http://github.com/dmbarbour/haskell-lmdb
|
||||
|
||||
Package-Url:
|
||||
Copyright: (c) 2014 by David Barbour
|
||||
License: BSD2
|
||||
license-file: LICENSE
|
||||
Stability: experimental
|
||||
build-type: Simple
|
||||
cabal-version: >= 1.16.0.3
|
||||
|
||||
Source-repository head
|
||||
type: git
|
||||
location: http://github.com/dmbarbour/haskell-lmdb.git
|
||||
|
||||
Library
|
||||
hs-Source-Dirs: hsrc_lib
|
||||
default-language: Haskell2010
|
||||
Build-Depends: base (>= 4.6 && < 5), array
|
||||
Build-Tools: hsc2hs
|
||||
|
||||
Exposed-Modules:
|
||||
Database.LMDB.Raw
|
||||
|
||||
Include-dirs: cbits
|
||||
Includes: lmdb.h midl.h
|
||||
C-Sources: cbits/mdb.c cbits/midl.c
|
||||
cc-options: -Wall -O2 -g -pthread -fPIC
|
||||
ghc-options: -Wall -fprof-auto -fPIC
|
||||
|
||||
default-extensions: ApplicativeDo
|
||||
, BangPatterns
|
||||
, BlockArguments
|
||||
, DataKinds
|
||||
, DefaultSignatures
|
||||
, DeriveAnyClass
|
||||
, DeriveDataTypeable
|
||||
, DeriveFoldable
|
||||
, DeriveGeneric
|
||||
, DeriveTraversable
|
||||
, DerivingStrategies
|
||||
, EmptyCase
|
||||
, EmptyDataDecls
|
||||
, FlexibleContexts
|
||||
, FlexibleInstances
|
||||
, FunctionalDependencies
|
||||
, GADTs
|
||||
, GeneralizedNewtypeDeriving
|
||||
, LambdaCase
|
||||
, MagicHash
|
||||
, MultiParamTypeClasses
|
||||
, NamedFieldPuns
|
||||
, NoImplicitPrelude
|
||||
, NumericUnderscores
|
||||
, OverloadedStrings
|
||||
, PartialTypeSignatures
|
||||
, PatternSynonyms
|
||||
, QuasiQuotes
|
||||
, Rank2Types
|
||||
, RankNTypes
|
||||
, RecordWildCards
|
||||
, ScopedTypeVariables
|
||||
, StandaloneDeriving
|
||||
, TemplateHaskell
|
||||
, TupleSections
|
||||
, TypeApplications
|
||||
, TypeFamilies
|
||||
, TypeOperators
|
||||
, UnboxedTuples
|
||||
, UnicodeSyntax
|
||||
, ViewPatterns
|
@ -1,7 +1,6 @@
|
||||
resolver: lts-16.15
|
||||
|
||||
packages:
|
||||
- lmdb-static
|
||||
- natpmp-static
|
||||
- proto
|
||||
- racquire
|
||||
|
@ -20,7 +20,7 @@ dependencies:
|
||||
- rio
|
||||
- vector
|
||||
- bytestring
|
||||
- lmdb-static
|
||||
- lmdb
|
||||
- conduit
|
||||
- racquire
|
||||
- urbit-noun-core
|
||||
|
@ -99,6 +99,7 @@ import qualified Data.Set as Set
|
||||
import qualified Data.Text as T
|
||||
import qualified Network.HTTP.Client as C
|
||||
import qualified System.Posix.Signals as Sys
|
||||
import qualified System.Posix.Resource as Sys
|
||||
import qualified System.ProgressBar as PB
|
||||
import qualified System.Random as Sys
|
||||
import qualified Urbit.EventLog.LMDB as Log
|
||||
@ -460,6 +461,13 @@ pillFrom = \case
|
||||
noun <- cueBS body & either throwIO pure
|
||||
fromNounErr noun & either (throwIO . uncurry ParseErr) pure
|
||||
|
||||
multiOnFatal :: HasKingEnv e => e -> IO ()
|
||||
multiOnFatal env = runRIO env $ do
|
||||
(view stderrLogFuncL >>=) $ flip runRIO $ logError
|
||||
("Urbit is shutting down because of a problem with the HTTP server.\n"
|
||||
<> "Please restart it at your leisure.")
|
||||
view killKingActionL >>= atomically
|
||||
|
||||
newShip :: CLI.New -> CLI.Opts -> RIO KingEnv ()
|
||||
newShip CLI.New{..} opts = do
|
||||
{-
|
||||
@ -472,7 +480,8 @@ newShip CLI.New{..} opts = do
|
||||
"run ship" flow, and possibly sequence them from the outside if
|
||||
that's really needed.
|
||||
-}
|
||||
multi <- multiEyre (MultiEyreConf Nothing Nothing True)
|
||||
env <- ask
|
||||
multi <- multiEyre (multiOnFatal env) (MultiEyreConf Nothing Nothing True)
|
||||
|
||||
-- TODO: We hit the same problem as above: we need a host env to boot a ship
|
||||
-- because it may autostart the ship, so build an inactive port configuration.
|
||||
@ -660,6 +669,7 @@ main = do
|
||||
|
||||
hSetBuffering stdout NoBuffering
|
||||
setupSignalHandlers
|
||||
setRLimits
|
||||
|
||||
runKingEnv args log $ case args of
|
||||
CLI.CmdRun ko ships -> runShips ko ships
|
||||
@ -693,6 +703,15 @@ main = do
|
||||
for_ [Sys.sigTERM, Sys.sigINT] $ \sig -> do
|
||||
Sys.installHandler sig (Sys.Catch onKillSig) Nothing
|
||||
|
||||
setRLimits = do
|
||||
openFiles <- Sys.getResourceLimit Sys.ResourceOpenFiles
|
||||
let soft = case Sys.hardLimit openFiles of
|
||||
Sys.ResourceLimit lim -> Sys.ResourceLimit lim
|
||||
Sys.ResourceLimitInfinity -> Sys.ResourceLimit 10240 -- macOS
|
||||
Sys.ResourceLimitUnknown -> Sys.ResourceLimit 10240
|
||||
Sys.setResourceLimit Sys.ResourceOpenFiles
|
||||
openFiles { Sys.softLimit = soft }
|
||||
|
||||
verboseLogging :: CLI.Cmd -> Bool
|
||||
verboseLogging = \case
|
||||
CLI.CmdRun ko ships -> any CLI.oVerbose (ships <&> \(_, o, _) -> o)
|
||||
@ -716,7 +735,6 @@ main = do
|
||||
CLI.CmdRun ko _ -> CLI.LogStderr
|
||||
_ -> CLI.LogStderr
|
||||
|
||||
|
||||
{-
|
||||
Runs a ship but restarts it if it crashes or shuts down on it's own.
|
||||
|
||||
@ -792,7 +810,8 @@ runShips CLI.Host {..} ships = do
|
||||
-- a king-wide option.
|
||||
}
|
||||
|
||||
multi <- multiEyre meConf
|
||||
env <- ask
|
||||
multi <- multiEyre (multiOnFatal env) meConf
|
||||
|
||||
ports <- buildPortHandler hUseNatPmp
|
||||
|
||||
|
@ -11,7 +11,11 @@ where
|
||||
import Urbit.Prelude hiding (Builder)
|
||||
|
||||
import Urbit.Arvo hiding (ServerId, reqUrl)
|
||||
import Urbit.King.App (HasKingId(..), HasMultiEyreApi(..), HasPierEnv(..))
|
||||
import Urbit.King.App ( killKingActionL
|
||||
, HasKingId(..)
|
||||
, HasMultiEyreApi(..)
|
||||
, HasPierEnv(..)
|
||||
)
|
||||
import Urbit.King.Config
|
||||
import Urbit.Vere.Eyre.Multi
|
||||
import Urbit.Vere.Eyre.PortsFile
|
||||
@ -177,9 +181,10 @@ startServ
|
||||
-> HttpServerConf
|
||||
-> (EvErr -> STM ())
|
||||
-> (Text -> RIO e ())
|
||||
-> IO ()
|
||||
-> KingSubsite
|
||||
-> RIO e Serv
|
||||
startServ who isFake conf plan stderr sub = do
|
||||
startServ who isFake conf plan stderr onFatal sub = do
|
||||
logInfo (displayShow ("EYRE", "startServ"))
|
||||
|
||||
multi <- view multiEyreApiL
|
||||
@ -228,7 +233,7 @@ startServ who isFake conf plan stderr sub = do
|
||||
atomically (joinMultiEyre multi who mCre onReq onKilReq sub)
|
||||
|
||||
logInfo $ displayShow ("EYRE", "Starting loopback server")
|
||||
lop <- serv vLive $ ServConf
|
||||
lop <- serv vLive onFatal $ ServConf
|
||||
{ scHost = soHost (pttLop ptt)
|
||||
, scPort = soWhich (pttLop ptt)
|
||||
, scRedi = Nothing
|
||||
@ -240,7 +245,7 @@ startServ who isFake conf plan stderr sub = do
|
||||
}
|
||||
|
||||
logInfo $ displayShow ("EYRE", "Starting insecure server")
|
||||
ins <- serv vLive $ ServConf
|
||||
ins <- serv vLive onFatal $ ServConf
|
||||
{ scHost = soHost (pttIns ptt)
|
||||
, scPort = soWhich (pttIns ptt)
|
||||
, scRedi = secRedi
|
||||
@ -253,7 +258,7 @@ startServ who isFake conf plan stderr sub = do
|
||||
|
||||
mSec <- for mTls $ \tls -> do
|
||||
logInfo "Starting secure server"
|
||||
serv vLive $ ServConf
|
||||
serv vLive onFatal $ ServConf
|
||||
{ scHost = soHost (pttSec ptt)
|
||||
, scPort = soWhich (pttSec ptt)
|
||||
, scRedi = Nothing
|
||||
@ -356,7 +361,11 @@ eyre env who plan isFake stderr sub = (initialEvents, runHttpServer)
|
||||
restart :: Drv -> HttpServerConf -> RIO e Serv
|
||||
restart (Drv var) conf = do
|
||||
logInfo "Restarting http server"
|
||||
let startAct = startServ who isFake conf plan stderr sub
|
||||
let onFatal = runRIO env $ do
|
||||
-- XX instead maybe restart following logic under HSESetConfig below
|
||||
stderr "A web server problem has occurred. Please restart your ship."
|
||||
view killKingActionL >>= atomically
|
||||
let startAct = startServ who isFake conf plan stderr onFatal sub
|
||||
res <- fromEither =<< restartService var startAct kill
|
||||
logInfo "Done restating http server"
|
||||
pure res
|
||||
|
@ -116,7 +116,7 @@ kingSubsite who scry stat func = do
|
||||
=> Text
|
||||
-> RIO e (Maybe Bool)
|
||||
scryAuth cookie =
|
||||
scryNow scry "ex" "" ["authenticated", "cookie", textAsTa cookie]
|
||||
scryNow scry "ex" "" ["authenticated", "cookie", textAsT cookie]
|
||||
|
||||
fourOhFourSubsite :: Ship -> KingSubsite
|
||||
fourOhFourSubsite who = KS $ \req respond ->
|
||||
|
@ -75,8 +75,8 @@ leaveMultiEyre MultiEyreApi {..} who = do
|
||||
modifyTVar' meaTlsC (deleteMap who)
|
||||
modifyTVar' meaSite (deleteMap who)
|
||||
|
||||
multiEyre :: HasLogFunc e => MultiEyreConf -> RIO e MultiEyreApi
|
||||
multiEyre conf@MultiEyreConf {..} = do
|
||||
multiEyre :: HasLogFunc e => IO () -> MultiEyreConf -> RIO e MultiEyreApi
|
||||
multiEyre onFatal conf@MultiEyreConf {..} = do
|
||||
logInfo (displayShow ("EYRE", "MULTI", conf))
|
||||
|
||||
vLive <- io emptyLiveReqs >>= newTVarIO
|
||||
@ -108,7 +108,7 @@ multiEyre conf@MultiEyreConf {..} = do
|
||||
|
||||
mIns <- for mecHttpPort $ \por -> do
|
||||
logInfo (displayShow ("EYRE", "MULTI", "HTTP", por))
|
||||
serv vLive $ ServConf
|
||||
serv vLive onFatal $ ServConf
|
||||
{ scHost = host
|
||||
, scPort = SPChoices $ singleton $ fromIntegral por
|
||||
, scRedi = Nothing -- TODO
|
||||
@ -121,7 +121,7 @@ multiEyre conf@MultiEyreConf {..} = do
|
||||
|
||||
mSec <- for mecHttpsPort $ \por -> do
|
||||
logInfo (displayShow ("EYRE", "MULTI", "HTTPS", por))
|
||||
serv vLive $ ServConf
|
||||
serv vLive onFatal $ ServConf
|
||||
{ scHost = host
|
||||
, scPort = SPChoices $ singleton $ fromIntegral por
|
||||
, scRedi = Nothing
|
||||
|
@ -35,6 +35,7 @@ import Urbit.Prelude hiding (Builder)
|
||||
|
||||
import Data.Default (def)
|
||||
import Data.List.NonEmpty (NonEmpty((:|)))
|
||||
import GHC.IO.Exception (IOException(..), IOErrorType(..))
|
||||
import Network.TLS ( Credential
|
||||
, Credentials(..)
|
||||
, ServerHooks(..)
|
||||
@ -254,19 +255,38 @@ startServer
|
||||
-> Net.Socket
|
||||
-> Maybe W.Port
|
||||
-> TVar E.LiveReqs
|
||||
-> IO ()
|
||||
-> RIO e ()
|
||||
startServer typ hos por sok red vLive = do
|
||||
startServer typ hos por sok red vLive onFatal = do
|
||||
envir <- ask
|
||||
|
||||
let host = case hos of
|
||||
SHLocalhost -> "127.0.0.1"
|
||||
SHAnyHostOk -> "*"
|
||||
|
||||
let handler r e = do
|
||||
when (isFatal e) $ do
|
||||
runRIO envir $ logError $ display $ msg r e
|
||||
onFatal
|
||||
when (W.defaultShouldDisplayException e) $ do
|
||||
runRIO envir $ logWarn $ display $ msg r e
|
||||
|
||||
isFatal e
|
||||
| Just (IOError {ioe_type = ResourceExhausted}) <- fromException e
|
||||
= True
|
||||
| otherwise = False
|
||||
|
||||
msg r e = case r of
|
||||
Just r -> "eyre: failed request from " <> (tshow $ W.remoteHost r)
|
||||
<> " for " <> (tshow $ W.rawPathInfo r) <> ": " <> tshow e
|
||||
Nothing -> "eyre: server exception: " <> tshow e
|
||||
|
||||
let opts =
|
||||
W.defaultSettings
|
||||
& W.setHost host
|
||||
& W.setPort (fromIntegral por)
|
||||
& W.setTimeout (5 * 60)
|
||||
& W.setTimeout 30
|
||||
& W.setOnException handler
|
||||
|
||||
-- TODO build Eyre.Site.app in pier, thread through here
|
||||
let runAppl who = E.app envir who vLive
|
||||
@ -338,8 +358,9 @@ getFirstTlsConfig (MTC var) = do
|
||||
[] -> STM.retry
|
||||
x:_ -> pure (fst x)
|
||||
|
||||
realServ :: HasLogFunc e => TVar E.LiveReqs -> ServConf -> RIO e ServApi
|
||||
realServ vLive conf@ServConf {..} = do
|
||||
realServ :: HasLogFunc e
|
||||
=> TVar E.LiveReqs -> IO () -> ServConf -> RIO e ServApi
|
||||
realServ vLive onFatal conf@ServConf {..} = do
|
||||
logInfo (displayShow ("EYRE", "SERV", "Running Real Server"))
|
||||
por <- newEmptyTMVarIO
|
||||
|
||||
@ -354,10 +375,10 @@ realServ vLive conf@ServConf {..} = do
|
||||
logInfo (displayShow ("EYRE", "SERV", "runServ"))
|
||||
rwith (forceOpenSocket scHost scPort) $ \(por, sok) -> do
|
||||
atomically (putTMVar vPort por)
|
||||
startServer scType scHost por sok scRedi vLive
|
||||
startServer scType scHost por sok scRedi vLive onFatal
|
||||
|
||||
serv :: HasLogFunc e => TVar E.LiveReqs -> ServConf -> RIO e ServApi
|
||||
serv vLive conf = do
|
||||
serv :: HasLogFunc e => TVar E.LiveReqs -> IO () -> ServConf -> RIO e ServApi
|
||||
serv vLive onFatal conf = do
|
||||
if scFake conf
|
||||
then fakeServ conf
|
||||
else realServ vLive conf
|
||||
else realServ vLive onFatal conf
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
module Urbit.Vere.Http.Client where
|
||||
|
||||
import Urbit.Prelude hiding (Builder)
|
||||
import Urbit.Prelude hiding (Builder, finally)
|
||||
|
||||
import Urbit.Vere.Http
|
||||
import Urbit.Vere.Pier.Types
|
||||
@ -16,6 +16,8 @@ import Urbit.King.App
|
||||
import Urbit.Arvo (BlipEv(..), Ev(..), HttpClientEf(..), HttpClientEv(..),
|
||||
HttpClientReq(..), HttpEvent(..), KingId, ResponseHeader(..))
|
||||
|
||||
import RIO.Orphans ()
|
||||
import Control.Monad.Catch (finally)
|
||||
|
||||
import qualified Data.Map.Strict as M
|
||||
import qualified Network.HTTP.Client as H
|
||||
@ -126,7 +128,11 @@ client env plan = (initialEvents, runHttpClient)
|
||||
newReq :: HttpClientDrv -> ReqId -> HttpClientReq -> RIO e ()
|
||||
newReq drv id req = do
|
||||
async <- runReq drv id req
|
||||
atomically $ modifyTVar' (hcdLive drv) (insertMap id async)
|
||||
-- If the async has somehow already completed, don't put it in the map,
|
||||
-- because then it might never get out.
|
||||
atomically $ pollSTM async >>= \case
|
||||
Nothing -> modifyTVar' (hcdLive drv) (insertMap id async)
|
||||
Just _ -> pure ()
|
||||
|
||||
-- The problem with the original http client code was that it was written
|
||||
-- to the idea of what the events "should have" been instead of what they
|
||||
@ -137,7 +143,7 @@ client env plan = (initialEvents, runHttpClient)
|
||||
-- Continue (with File) event, and the Continue (completed) event are three
|
||||
-- separate things.
|
||||
runReq :: HttpClientDrv -> ReqId -> HttpClientReq -> RIO e (Async ())
|
||||
runReq HttpClientDrv{..} id req = async $
|
||||
runReq HttpClientDrv{..} id req = async $ flip finally aftr $
|
||||
case cvtReq req of
|
||||
Nothing -> do
|
||||
logInfo $ displayShow ("(malformed http client request)", id, req)
|
||||
@ -147,6 +153,11 @@ client env plan = (initialEvents, runHttpClient)
|
||||
withRunInIO $ \run ->
|
||||
H.withResponse r hcdManager $ \x -> run (exec x)
|
||||
where
|
||||
-- Make sure to remove our entry from hcdLive after we're done so the
|
||||
-- map doesn't grow without bound.
|
||||
aftr :: RIO e ()
|
||||
aftr = atomically $ modifyTVar' hcdLive (deleteMap id)
|
||||
|
||||
recv :: H.BodyReader -> RIO e (Maybe ByteString)
|
||||
recv read = io $ read <&> \case chunk | null chunk -> Nothing
|
||||
| otherwise -> Just chunk
|
||||
|
@ -522,10 +522,13 @@ run serf maxBatchSize getLastEvInLog onInput sendOn spin = topLoop
|
||||
que <- newTBMQueueIO 1
|
||||
() <- atomically (writeTBMQueue que firstWorkErr)
|
||||
tWork <- async (processWork serf maxBatchSize que onWorkResp spin)
|
||||
flip onException (cancel tWork) $ do
|
||||
-- Avoid wrapping all subsequent runs of the event loop in an exception
|
||||
-- handler which retains tWork.
|
||||
nexSt <- flip onException (cancel tWork) $ do
|
||||
nexSt <- workLoop que
|
||||
wait tWork
|
||||
nexSt
|
||||
pure nexSt
|
||||
nexSt
|
||||
|
||||
workLoop :: TBMQueue EvErr -> IO (IO ())
|
||||
workLoop que = atomically onInput >>= \case
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: urbit-king
|
||||
version: 1.2
|
||||
version: 1.3
|
||||
license: MIT
|
||||
license-file: LICENSE
|
||||
data-files:
|
||||
@ -65,7 +65,6 @@ dependencies:
|
||||
- iproute
|
||||
- largeword
|
||||
- lens
|
||||
- lmdb-static
|
||||
- lock-file
|
||||
- megaparsec
|
||||
- memory
|
||||
@ -86,6 +85,7 @@ dependencies:
|
||||
- regex-tdfa
|
||||
- resourcet
|
||||
- rio
|
||||
- rio-orphans
|
||||
- semigroups
|
||||
- smallcheck
|
||||
- stm
|
||||
|
@ -13,7 +13,7 @@ module Urbit.Noun.Conversions
|
||||
, Path(..), EvilPath(..), Ship(..)
|
||||
, Lenient(..), pathToFilePath, filePathToPath
|
||||
, showUD, tshowUD
|
||||
, textAsTa
|
||||
, textAsT
|
||||
) where
|
||||
|
||||
import ClassyPrelude hiding (hash)
|
||||
@ -556,13 +556,13 @@ instance FromNoun Knot where
|
||||
else fail ("Non-ASCII chars in knot: " <> unpack txt)
|
||||
|
||||
-- equivalent of (cury scot %t)
|
||||
textAsTa :: Text -> Text
|
||||
textAsTa = ("~~" <>) . concatMap \case
|
||||
textAsT :: Text -> Text
|
||||
textAsT = ("~~" <>) . concatMap \case
|
||||
' ' -> "."
|
||||
'.' -> "~."
|
||||
'~' -> "~~"
|
||||
c ->
|
||||
if C.isAlphaNum c || (c == '-') then
|
||||
if (C.isAlphaNum c && not (C.isUpper c)) || (c == '-') then
|
||||
T.singleton c
|
||||
else
|
||||
if C.ord c < 0x10 then "~0" else "~"
|
||||
|
@ -17,22 +17,22 @@ import Data.Time.Clock.System (systemToUTCTime, utcToSystemTime)
|
||||
import Data.Time.LocalTime (TimeOfDay(..), timeToTimeOfDay)
|
||||
import Data.Word (Word64)
|
||||
import Text.Printf (printf)
|
||||
import Urbit.Noun (FromNoun, ToNoun)
|
||||
import Urbit.Noun (deriveToNoun, FromNoun, ToNoun(..))
|
||||
|
||||
|
||||
-- Types -----------------------------------------------------------------------
|
||||
|
||||
newtype Gap = Gap { _fractoSecs :: Integer }
|
||||
deriving newtype (Eq, Ord, Show, Num, ToNoun, FromNoun)
|
||||
deriving newtype (Eq, Ord, Show, Num, FromNoun)
|
||||
|
||||
newtype Unix = Unix { _sinceUnixEpoch :: Gap }
|
||||
deriving newtype (Eq, Ord, Show, ToNoun, FromNoun)
|
||||
deriving newtype (Eq, Ord, Show, FromNoun)
|
||||
|
||||
newtype Wen = Wen { _sinceUrbitEpoch :: Gap }
|
||||
deriving newtype (Eq, Ord, Show, Num, ToNoun, FromNoun)
|
||||
deriving newtype (Eq, Ord, Show, Num, FromNoun)
|
||||
|
||||
newtype Date = MkDate { _dateWen :: Wen }
|
||||
deriving newtype (Eq, Ord, Num, ToNoun, FromNoun)
|
||||
deriving newtype (Eq, Ord, Num, FromNoun)
|
||||
|
||||
|
||||
-- Record Lenses ---------------------------------------------------------------
|
||||
@ -45,6 +45,20 @@ makeLenses ''Date
|
||||
|
||||
-- Instances -------------------------------------------------------------------
|
||||
|
||||
instance ToNoun Gap where
|
||||
toNoun (reducePrecision -> Gap fs) = toNoun fs
|
||||
|
||||
-- | Produce a Gap with fewer digits after the binary point, more
|
||||
-- appropriately capturing the precision our clock gives us.
|
||||
reducePrecision :: Gap -> Gap
|
||||
reducePrecision (Gap fs) = Gap (chop fs)
|
||||
where
|
||||
chop fs = shiftL (shiftR fs 32) 32
|
||||
|
||||
deriveToNoun ''Unix
|
||||
deriveToNoun ''Wen
|
||||
deriveToNoun ''Date
|
||||
|
||||
instance Show Date where
|
||||
show (MkDate wen) = if fs == 0
|
||||
then printf "~%i.%u.%u..%02u.%02u.%02u" y m d h min s
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
#include <vere/db/lmdb.h>
|
||||
|
||||
#include "ca-bundle.h"
|
||||
|
||||
/* Require unsigned char
|
||||
@ -97,7 +99,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
u3_Host.ops_u.kno_w = DefaultKernel;
|
||||
|
||||
while ( -1 != (ch_i=getopt(argc, argv,
|
||||
"X:Y:G:J:B:K:A:H:I:C:w:u:e:F:k:n:p:r:i:Z:LljacdgqstvxPDRS")) )
|
||||
"X:Y:G:J:B:b:K:A:H:I:C:w:u:e:F:k:n:p:r:i:Z:LljacdgqstvxPDRS")) )
|
||||
{
|
||||
switch ( ch_i ) {
|
||||
case 'X': {
|
||||
@ -120,6 +122,10 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
u3_Host.ops_u.pil_c = strdup(optarg);
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
u3_Host.ops_u.bin_c = strdup(optarg);
|
||||
break;
|
||||
}
|
||||
case 'G': {
|
||||
u3_Host.ops_u.gen_c = strdup(optarg);
|
||||
break;
|
||||
@ -300,6 +306,12 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
return c3n;
|
||||
}
|
||||
|
||||
struct sockaddr_in t;
|
||||
if ( u3_Host.ops_u.bin_c != 0 && inet_aton(u3_Host.ops_u.bin_c, &t.sin_addr) == 0 ) {
|
||||
fprintf(stderr, "-b invalid IP address\n");
|
||||
return c3n;
|
||||
}
|
||||
|
||||
if ( u3_Host.ops_u.nuu != c3y && u3_Host.ops_u.dns_c != 0) {
|
||||
fprintf(stderr, "-H only makes sense when bootstrapping a new instance\n");
|
||||
return c3n;
|
||||
@ -400,6 +412,7 @@ u3_ve_usage(c3_i argc, c3_c** argv)
|
||||
"\n",
|
||||
"-A dir Use dir for initial clay sync\n",
|
||||
"-B pill Bootstrap from this pill\n",
|
||||
"-b ip Bind HTTP server to this IP address\n",
|
||||
"-C limit Set memo cache max size; 0 means uncapped\n",
|
||||
"-c pier Create a new urbit in pier/\n",
|
||||
"-D Recompute from events\n",
|
||||
@ -602,6 +615,32 @@ _stop_on_boot_completed_cb()
|
||||
u3_king_exit();
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_debug_db_stats(const c3_c* dir_c)
|
||||
{
|
||||
#if defined(U3_CPU_aarch64) && defined(U3_OS_linux)
|
||||
const size_t siz_i = 64424509440;
|
||||
#else
|
||||
const size_t siz_i = 1099511627776;
|
||||
#endif
|
||||
|
||||
c3_c* log_c = c3_malloc(10 + strlen(dir_c));
|
||||
|
||||
strcpy(log_c, dir_c);
|
||||
strcat(log_c, "/.urb/log");
|
||||
|
||||
MDB_env* mdb_u = u3_lmdb_init(log_c, siz_i);
|
||||
|
||||
if ( mdb_u ) {
|
||||
u3_lmdb_stat(mdb_u, stdout);
|
||||
u3_lmdb_exit(mdb_u);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
c3_i
|
||||
main(c3_i argc,
|
||||
c3_c** argv)
|
||||
@ -609,6 +648,12 @@ main(c3_i argc,
|
||||
// Parse options.
|
||||
//
|
||||
if ( c3n == _main_getopt(argc, argv) ) {
|
||||
if ( (3 == argc)
|
||||
&& (0 == strcmp("db-info", argv[1])) )
|
||||
{
|
||||
return _debug_db_stats(argv[2]);
|
||||
}
|
||||
|
||||
u3_ve_usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
@ -150,6 +150,9 @@
|
||||
u3_noun u3qe_shal(u3_atom, u3_atom);
|
||||
u3_noun u3qe_sha1(u3_atom, u3_atom);
|
||||
|
||||
u3_atom u3qe_fein_ob(u3_atom pyn);
|
||||
u3_atom u3qe_fynd_ob(u3_atom pyn);
|
||||
|
||||
u3_noun u3qe_hmac(u3_noun, u3_atom, u3_atom,
|
||||
u3_atom, u3_atom, u3_atom, u3_atom);
|
||||
|
||||
|
@ -175,6 +175,9 @@
|
||||
u3_noun u3we_shal(u3_noun);
|
||||
u3_noun u3we_sha1(u3_noun);
|
||||
|
||||
u3_noun u3we_fein_ob(u3_noun);
|
||||
u3_noun u3we_fynd_ob(u3_noun);
|
||||
|
||||
u3_noun u3weo_raw(u3_noun);
|
||||
|
||||
u3_noun u3wee_puck(u3_noun);
|
||||
|
@ -16,6 +16,12 @@
|
||||
void
|
||||
u3_lmdb_exit(MDB_env* env_u);
|
||||
|
||||
|
||||
/* u3_lmdb_stat(): print env stats.
|
||||
*/
|
||||
void
|
||||
u3_lmdb_stat(MDB_env* env_u, FILE* fil_u);
|
||||
|
||||
/* u3_lmdb_gulf(): read first and last event numbers.
|
||||
*/
|
||||
c3_o
|
||||
|
@ -256,6 +256,7 @@
|
||||
c3_c* arv_c; // -A, initial sync from
|
||||
c3_o abo; // -a, abort aggressively
|
||||
c3_c* pil_c; // -B, bootstrap from
|
||||
c3_c* bin_c; // -b, http server bind ip
|
||||
c3_o nuu; // -c, new pier
|
||||
c3_o dry; // -D, dry compute, no checkpoint
|
||||
c3_o dem; // -d, daemon
|
||||
|
@ -3,15 +3,24 @@
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
u3_noun
|
||||
u3qa_gte(u3_atom a, u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a >= b);
|
||||
}
|
||||
else if ( 0 == a ) {
|
||||
return c3n;
|
||||
}
|
||||
else if ( 0 == b ) {
|
||||
return c3y;
|
||||
}
|
||||
else {
|
||||
c3_w a_w = u3r_met(0, a);
|
||||
c3_w b_w = u3r_met(0, b);
|
||||
|
||||
/* functions
|
||||
*/
|
||||
u3_noun
|
||||
u3qa_gte(u3_atom a,
|
||||
u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a >= b);
|
||||
if ( a_w != b_w ) {
|
||||
return __(a_w >= b_w);
|
||||
}
|
||||
else {
|
||||
mpz_t a_mp, b_mp;
|
||||
@ -28,17 +37,20 @@
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
u3_noun
|
||||
u3wa_gte(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
}
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ||
|
||||
(c3n == u3ud(a)) ||
|
||||
(c3n == u3ud(b)) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
} else {
|
||||
return u3qa_gte(a, b);
|
||||
}
|
||||
u3_noun
|
||||
u3wa_gte(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0))
|
||||
|| (c3n == u3ud(b) && 0 != a)
|
||||
|| (c3n == u3ud(a) && 0 != b) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
else {
|
||||
return u3qa_gte(a, b);
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,24 @@
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
u3_noun
|
||||
u3qa_gth(u3_atom a, u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a > b);
|
||||
}
|
||||
else if ( 0 == a ) {
|
||||
return c3n;
|
||||
}
|
||||
else if ( 0 == b ) {
|
||||
return c3y;
|
||||
}
|
||||
else {
|
||||
c3_w a_w = u3r_met(0, a);
|
||||
c3_w b_w = u3r_met(0, b);
|
||||
|
||||
/* functions
|
||||
*/
|
||||
u3_noun
|
||||
u3qa_gth(u3_atom a,
|
||||
u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a > b);
|
||||
if ( a_w != b_w ) {
|
||||
return __(a_w > b_w);
|
||||
}
|
||||
else {
|
||||
mpz_t a_mp, b_mp;
|
||||
@ -28,27 +37,28 @@
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
u3_noun
|
||||
u3wa_gth(u3_noun cor)
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3wa_gth(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0))
|
||||
|| (c3n == u3ud(b) && 0 != a)
|
||||
|| (c3n == u3ud(a) && 0 != b) )
|
||||
{
|
||||
u3_noun a, b;
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ||
|
||||
(c3n == u3ud(a)) ||
|
||||
(c3n == u3ud(b)) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
} else {
|
||||
return u3qa_gth(a, b);
|
||||
}
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3ka_gth(u3_noun a,
|
||||
u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_gth(a, b);
|
||||
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
else {
|
||||
return u3qa_gth(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3ka_gth(u3_noun a, u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_gth(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
}
|
||||
|
@ -3,15 +3,24 @@
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
u3_noun
|
||||
u3qa_lte(u3_atom a, u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a <= b);
|
||||
}
|
||||
else if ( 0 == a ) {
|
||||
return c3y;
|
||||
}
|
||||
else if ( 0 == b ) {
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
c3_w a_w = u3r_met(0, a);
|
||||
c3_w b_w = u3r_met(0, b);
|
||||
|
||||
/* functions
|
||||
*/
|
||||
u3_noun
|
||||
u3qa_lte(u3_atom a,
|
||||
u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a <= b);
|
||||
if ( a_w != b_w ) {
|
||||
return __(a_w <= b_w);
|
||||
}
|
||||
else {
|
||||
mpz_t a_mp, b_mp;
|
||||
@ -28,26 +37,28 @@
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
u3_noun
|
||||
u3wa_lte(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
}
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ||
|
||||
(c3n == u3ud(a)) ||
|
||||
(c3n == u3ud(b)) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
} else {
|
||||
return u3qa_lte(a, b);
|
||||
}
|
||||
}
|
||||
u3_noun
|
||||
u3ka_lte(u3_noun a,
|
||||
u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_lte(a, b);
|
||||
u3_noun
|
||||
u3wa_lte(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0))
|
||||
|| (c3n == u3ud(b) && 0 != a)
|
||||
|| (c3n == u3ud(a) && 0 != b) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
else {
|
||||
return u3qa_lte(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3ka_lte(u3_noun a, u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_lte(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
}
|
||||
|
@ -3,21 +3,24 @@
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
u3_noun
|
||||
u3qa_lth(u3_atom a, u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a < b);
|
||||
}
|
||||
else if ( 0 == a ) {
|
||||
return c3y;
|
||||
}
|
||||
else if ( 0 == b ) {
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
c3_w a_w = u3r_met(0, a);
|
||||
c3_w b_w = u3r_met(0, b);
|
||||
|
||||
/* functions
|
||||
*/
|
||||
u3_noun
|
||||
u3qa_lth(u3_atom a,
|
||||
u3_atom b)
|
||||
{
|
||||
if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return __(a < b);
|
||||
}
|
||||
else if ( 0 == a ) {
|
||||
return c3y;
|
||||
}
|
||||
else if ( 0 == b ) {
|
||||
return c3n;
|
||||
if ( a_w != b_w ) {
|
||||
return __(a_w < b_w);
|
||||
}
|
||||
else {
|
||||
mpz_t a_mp, b_mp;
|
||||
@ -34,17 +37,20 @@
|
||||
return cmp;
|
||||
}
|
||||
}
|
||||
u3_noun
|
||||
u3wa_lth(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
}
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0)) ||
|
||||
(c3n == u3ud(b) && a != 0) ||
|
||||
(c3n == u3ud(a) && b != 0) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
} else {
|
||||
return u3qa_lth(a, b);
|
||||
}
|
||||
u3_noun
|
||||
u3wa_lth(u3_noun cor)
|
||||
{
|
||||
u3_noun a, b;
|
||||
|
||||
if ( (c3n == u3r_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0))
|
||||
|| (c3n == u3ud(b) && 0 != a)
|
||||
|| (c3n == u3ud(a) && 0 != b) )
|
||||
{
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
else {
|
||||
return u3qa_lth(a, b);
|
||||
}
|
||||
}
|
||||
|
88
pkg/urbit/jets/e/fein_ob.c
Normal file
88
pkg/urbit/jets/e/fein_ob.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* j/3/fein.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include <murmur3.h>
|
||||
|
||||
// +feis:ob constant parameters to +fe:ob
|
||||
//
|
||||
static const c3_w a_w = 0xffff;
|
||||
static const c3_w b_w = 0x10000;
|
||||
static const c3_w k_w = 0xffff0000;
|
||||
|
||||
// +raku:ob
|
||||
//
|
||||
static const c3_w rak_w[4] = { 0xb76d5eed, 0xee281300, 0x85bcae01, 0x4b387af7 };
|
||||
|
||||
/* _fe_ob(): +fe:ob, with constant parameters factored out.
|
||||
** correct over the domain [0x0, 0xfffe.ffff]
|
||||
*/
|
||||
static c3_w
|
||||
_fe_ob(c3_w m_w)
|
||||
{
|
||||
c3_w l_w = m_w % a_w;
|
||||
c3_w r_w = m_w / a_w;
|
||||
c3_w f_w, t_w;
|
||||
c3_y j_y, k_y[2];
|
||||
|
||||
for ( j_y = 0; j_y < 4; j_y++ ) {
|
||||
k_y[0] = r_w & 0xff;
|
||||
k_y[1] = (r_w >> 8) & 0xff;
|
||||
|
||||
MurmurHash3_x86_32(k_y, 2, rak_w[j_y], &f_w);
|
||||
|
||||
// NB: this addition can overflow a c3_w (before mod)
|
||||
//
|
||||
t_w = ((c3_d)f_w + l_w) % (!(j_y & 1) ? a_w : b_w);
|
||||
l_w = r_w;
|
||||
r_w = t_w;
|
||||
}
|
||||
|
||||
// legendary @max19
|
||||
//
|
||||
return ( a_w == r_w )
|
||||
? (r_w * a_w) + l_w
|
||||
: (l_w * a_w) + r_w;
|
||||
}
|
||||
|
||||
/* _feis_ob(): +feis:ob, also offsetting by 0x1.000 (as in +fein:ob).
|
||||
** correct over the domain [0x1.0000, 0xffff.ffff]
|
||||
*/
|
||||
static c3_w
|
||||
_feis_ob(c3_w m_w)
|
||||
{
|
||||
c3_w c_w = _fe_ob(m_w - b_w);
|
||||
return b_w + (( c_w < k_w ) ? c_w : _fe_ob(c_w));
|
||||
}
|
||||
|
||||
u3_atom
|
||||
u3qe_fein_ob(u3_atom pyn)
|
||||
{
|
||||
c3_w sor_w = u3r_met(4, pyn);
|
||||
|
||||
if ( (sor_w < 2) || (sor_w > 4) ) {
|
||||
return u3k(pyn);
|
||||
}
|
||||
|
||||
if ( 2 == sor_w ) {
|
||||
return u3i_word(_feis_ob(u3r_word(0, pyn)));
|
||||
}
|
||||
else {
|
||||
c3_w pyn_w[2];
|
||||
u3r_words(0, 2, pyn_w, pyn);
|
||||
|
||||
if ( pyn_w[0] < b_w ) {
|
||||
return u3k(pyn);
|
||||
}
|
||||
else {
|
||||
pyn_w[0] = _feis_ob(pyn_w[0]);
|
||||
return u3i_words(2, pyn_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_fein_ob(u3_noun cor)
|
||||
{
|
||||
return u3qe_fein_ob(u3x_atom(u3x_at(u3x_sam, cor)));
|
||||
}
|
92
pkg/urbit/jets/e/fynd_ob.c
Normal file
92
pkg/urbit/jets/e/fynd_ob.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* j/3/fein.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include <murmur3.h>
|
||||
|
||||
// +tail:ob constant parameters to +fe:ob
|
||||
//
|
||||
static const c3_w a_w = 0xffff;
|
||||
static const c3_w b_w = 0x10000;
|
||||
static const c3_w k_w = 0xffff0000;
|
||||
|
||||
// (flop raku:ob)
|
||||
//
|
||||
static const c3_w kar_w[4] = { 0x4b387af7, 0x85bcae01, 0xee281300, 0xb76d5eed };
|
||||
|
||||
/* _fen_ob(): +fen:ob, with constant parameters factored out.
|
||||
** correct over the domain [0x0 ... 0xfffe.ffff]
|
||||
*/
|
||||
static c3_w
|
||||
_fen_ob(c3_w m_w)
|
||||
{
|
||||
c3_w l_w = m_w / a_w;
|
||||
c3_w r_w = m_w % a_w;
|
||||
c3_w f_w, t_w;
|
||||
c3_y j_y, k_y[2];
|
||||
|
||||
// legendary @max19
|
||||
//
|
||||
if ( a_w == l_w ) {
|
||||
t_w = l_w;
|
||||
l_w = r_w;
|
||||
r_w = t_w;
|
||||
}
|
||||
|
||||
for ( j_y = 0; j_y < 4; j_y++ ) {
|
||||
k_y[0] = l_w & 0xff;
|
||||
k_y[1] = (l_w >> 8) & 0xff;
|
||||
|
||||
MurmurHash3_x86_32(k_y, 2, kar_w[j_y], &f_w);
|
||||
|
||||
t_w = ( j_y & 1 )
|
||||
? ((r_w + a_w) - (f_w % a_w)) % a_w
|
||||
: ((r_w + b_w) - (f_w % b_w)) % b_w;
|
||||
r_w = l_w;
|
||||
l_w = t_w;
|
||||
}
|
||||
|
||||
return (r_w * a_w) + l_w;
|
||||
}
|
||||
|
||||
/* _tail_ob(): +feis:ob, also offsetting by 0x1.000 (as in +fynd:ob).
|
||||
** correct over the domain [0x1.0000, 0xffff.ffff]
|
||||
*/
|
||||
static c3_w
|
||||
_tail_ob(c3_w m_w)
|
||||
{
|
||||
c3_w c_w = _fen_ob(m_w - b_w);
|
||||
return b_w + (( c_w < k_w ) ? c_w : _fen_ob(c_w));
|
||||
}
|
||||
|
||||
u3_atom
|
||||
u3qe_fynd_ob(u3_atom pyn)
|
||||
{
|
||||
c3_w sor_w = u3r_met(4, pyn);
|
||||
|
||||
if ( (sor_w < 2) || (sor_w > 4) ) {
|
||||
return u3k(pyn);
|
||||
}
|
||||
|
||||
if ( 2 == sor_w ) {
|
||||
return u3i_word(_tail_ob(u3r_word(0, pyn)));
|
||||
}
|
||||
else {
|
||||
c3_w pyn_w[2];
|
||||
u3r_words(0, 2, pyn_w, pyn);
|
||||
|
||||
if ( pyn_w[0] < b_w ) {
|
||||
return u3k(pyn);
|
||||
}
|
||||
else {
|
||||
pyn_w[0] = _tail_ob(pyn_w[0]);
|
||||
return u3i_words(2, pyn_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_fynd_ob(u3_noun cor)
|
||||
{
|
||||
return u3qe_fynd_ob(u3x_atom(u3x_at(u3x_sam, cor)));
|
||||
}
|
@ -1389,8 +1389,21 @@ static c3_c* _140_tri_shal_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_core _140_ob_d[] =
|
||||
{ {}
|
||||
static u3j_harm _140_ob_fein_a[] = {{".2", u3we_fein_ob}, {}};
|
||||
static c3_c* _140_ob_fein_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_harm _140_ob_fynd_a[] = {{".2", u3we_fynd_ob}, {}};
|
||||
static c3_c* _140_ob_fynd_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static u3j_core _140_ob_d[] = {
|
||||
{ "fein", 7, _140_ob_fein_a, 0, _140_ob_fein_ha },
|
||||
{ "fynd", 7, _140_ob_fynd_a, 0, _140_ob_fynd_ha },
|
||||
{}
|
||||
};
|
||||
static c3_c* _140_ob_ha[] = {
|
||||
"13ebfbdee69396bc1d980fc4dcbcdaa9cc3fb9c011e6cf188e71311a8bffc8e6",
|
||||
|
@ -918,12 +918,11 @@ _cj_kick_z(u3_noun cor, u3j_core* cop_u, u3j_harm* ham_u, u3_atom axe)
|
||||
u3r_mug(pro));
|
||||
ham_u->liv = c3n;
|
||||
|
||||
c3_assert(0);
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
u3l_log("test: %s %s\r\n",
|
||||
cop_u->cos_c,
|
||||
(!strcmp(".2", ham_u->fcs_c)) ? "$" : ham_u->fcs_c);
|
||||
|
@ -1382,7 +1382,7 @@ _n_comp(u3_noun* ops, u3_noun fol, c3_o los_o, c3_o tel_o)
|
||||
|
||||
case 9:
|
||||
u3x_cell(arg, &hed, &tel);
|
||||
if ( 3 == u3qc_cap(hed) ) {
|
||||
if ( (1 == hed) || (3 == u3qc_cap(hed)) ) {
|
||||
u3_noun mac = u3nq(7, u3k(tel), 2, u3nt(u3nc(0, 1), 0, u3k(hed)));
|
||||
tot_w += _n_comp(ops, mac, los_o, tel_o);
|
||||
u3z(mac);
|
||||
|
@ -401,13 +401,16 @@ _cu_realloc(FILE* fil_u, ur_root_t** tor_u, ur_nvec_t* doc_u)
|
||||
//
|
||||
_cu_all_to_loom(rot_u, ken, &cod_u);
|
||||
|
||||
// allocate new hot jet state
|
||||
//
|
||||
u3j_boot(c3y);
|
||||
|
||||
// establish correct refcounts via tracing
|
||||
//
|
||||
u3m_grab(u3_none);
|
||||
|
||||
// allocate new hot jet state; re-establish warm
|
||||
// re-establish warm jet state
|
||||
//
|
||||
u3j_boot(c3y);
|
||||
u3j_ream();
|
||||
|
||||
// restore event number
|
||||
|
@ -245,6 +245,156 @@ _test_base16(void)
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_w
|
||||
_fein_ob_w(c3_w inp_w)
|
||||
{
|
||||
u3_atom inp = u3i_word(inp_w);
|
||||
u3_atom act = u3qe_fein_ob(inp);
|
||||
c3_w act_w = u3r_word(0, act);
|
||||
u3z(inp); u3z(act);
|
||||
return act_w;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_expect_fein_ob_w(c3_w inp_w, c3_w exp_w)
|
||||
{
|
||||
c3_w act_w = _fein_ob_w(inp_w);
|
||||
|
||||
if ( act_w != exp_w ) {
|
||||
fprintf(stderr, "fein: inp=0x%08x exp=0x%08x act=0x%08x\n",
|
||||
inp_w, exp_w, act_w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_fein_ob(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
ret_i &= _expect_fein_ob_w(0, 0);
|
||||
ret_i &= _expect_fein_ob_w(0xffff, 0xffff);
|
||||
ret_i &= _expect_fein_ob_w(0x1b08f, 0x76b920e5);
|
||||
ret_i &= _expect_fein_ob_w(0x10000, 0x423e60bf);
|
||||
ret_i &= _expect_fein_ob_w(0x10001, 0xd4400acb);
|
||||
ret_i &= _expect_fein_ob_w(0x10002, 0xf429043);
|
||||
ret_i &= _expect_fein_ob_w(0x10000000, 0xa04bc7fa);
|
||||
ret_i &= _expect_fein_ob_w(0x1234abcd, 0x686f6c25);
|
||||
ret_i &= _expect_fein_ob_w(0xabcd1234, 0x4a220c8);
|
||||
ret_i &= _expect_fein_ob_w(0xdeadbeef, 0x909bc4a9);
|
||||
ret_i &= _expect_fein_ob_w(0xfffff, 0x6746b96b);
|
||||
ret_i &= _expect_fein_ob_w(0xffffffff, 0xbba4dcce);
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_w
|
||||
_fynd_ob_w(c3_w inp_w)
|
||||
{
|
||||
u3_atom inp = u3i_word(inp_w);
|
||||
u3_atom act = u3qe_fynd_ob(inp);
|
||||
c3_w act_w = u3r_word(0, act);
|
||||
u3z(inp); u3z(act);
|
||||
return act_w;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_expect_fynd_ob_w(c3_w exp_w, c3_w inp_w)
|
||||
{
|
||||
c3_w act_w = _fynd_ob_w(inp_w);
|
||||
|
||||
if ( act_w != exp_w ) {
|
||||
fprintf(stderr, "fynd: inp=0x%08x exp=0x%08x act=0x%08x\n",
|
||||
inp_w, exp_w, act_w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_fynd_ob(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
|
||||
ret_i &= _expect_fynd_ob_w(0, 0);
|
||||
ret_i &= _expect_fynd_ob_w(0xffff, 0xffff);
|
||||
ret_i &= _expect_fynd_ob_w(0x10000, 0x423e60bf);
|
||||
ret_i &= _expect_fynd_ob_w(0x10001, 0xd4400acb);
|
||||
ret_i &= _expect_fynd_ob_w(0x10002, 0xf429043);
|
||||
ret_i &= _expect_fynd_ob_w(0x10000000, 0xa04bc7fa);
|
||||
ret_i &= _expect_fynd_ob_w(0x1234abcd, 0x686f6c25);
|
||||
ret_i &= _expect_fynd_ob_w(0xabcd1234, 0x4a220c8);
|
||||
ret_i &= _expect_fynd_ob_w(0xdeadbeef, 0x909bc4a9);
|
||||
ret_i &= _expect_fynd_ob_w(0xfffff, 0x6746b96b);
|
||||
ret_i &= _expect_fynd_ob_w(0xffffffff, 0xbba4dcce);
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_exhaust_roundtrip_fein_fynd_ob(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
c3_w fyn_w, i_w;
|
||||
|
||||
{
|
||||
u3_atom fen, fyn;
|
||||
|
||||
for ( i_w = 0x10000; i_w < 0x80000000; i_w++ ) {
|
||||
fen = u3qe_fein_ob(i_w);
|
||||
fyn = u3qe_fynd_ob(fen);
|
||||
fyn_w = u3r_word(0, fyn);
|
||||
|
||||
if ( i_w != fyn_w ) {
|
||||
fprintf(stderr, "fein/fynd: inp=0x%08x fein=0x%08x fynd=0x%08x\n",
|
||||
i_w, u3r_word(0, fen), fyn_w);
|
||||
ret_i = 0;
|
||||
}
|
||||
u3z(fen); u3z(fyn);
|
||||
|
||||
if ( !(i_w % 0x1000000) ) {
|
||||
fprintf(stderr, "fein/fynd: 0x%x done\n", i_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
c3_w fen_w;
|
||||
|
||||
do {
|
||||
fen_w = _fein_ob_w(i_w);
|
||||
fyn_w = _fynd_ob_w(fen_w);
|
||||
if ( i_w != fyn_w ) {
|
||||
fprintf(stderr, "fein/fynd: inp=0x%08x fein=0x%08x fynd=0x%08x\n",
|
||||
i_w, fen_w, fyn_w);
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( !(i_w % 0x1000000) ) {
|
||||
fprintf(stderr, "fein/fynd: 0x%x done\n", i_w);
|
||||
}
|
||||
}
|
||||
while ( ++i_w );
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_ob(void)
|
||||
{
|
||||
c3_i ret_i = 1;
|
||||
ret_i &= _test_fein_ob();
|
||||
ret_i &= _test_fynd_ob();
|
||||
// disabled, takes almost ~m15
|
||||
//
|
||||
// ret_i &= _exhaust_roundtrip_fein_fynd_ob();
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
static c3_i
|
||||
_test_jets(void)
|
||||
{
|
||||
@ -255,6 +405,11 @@ _test_jets(void)
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
if ( !_test_ob() ) {
|
||||
fprintf(stderr, "test jets: ob: failed\r\n");
|
||||
ret_i = 0;
|
||||
}
|
||||
|
||||
return ret_i;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
/* vere/db/lmdb.c
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lmdb.h>
|
||||
|
||||
#include "c/portable.h"
|
||||
@ -79,6 +83,49 @@ u3_lmdb_exit(MDB_env* env_u)
|
||||
mdb_env_close(env_u);
|
||||
}
|
||||
|
||||
/* u3_lmdb_stat(): print env stats.
|
||||
*/
|
||||
void
|
||||
u3_lmdb_stat(MDB_env* env_u, FILE* fil_u)
|
||||
{
|
||||
size_t siz_i;
|
||||
|
||||
fprintf(fil_u, "lmdb info:\n");
|
||||
|
||||
{
|
||||
MDB_stat mst_u;
|
||||
MDB_envinfo mei_u;
|
||||
|
||||
(void)mdb_env_stat(env_u, &mst_u);
|
||||
(void)mdb_env_info(env_u, &mei_u);
|
||||
|
||||
fprintf(fil_u, " map size: %zu\n", mei_u.me_mapsize);
|
||||
fprintf(fil_u, " page size: %u\n", mst_u.ms_psize);
|
||||
fprintf(fil_u, " max pages: %zu\n", mei_u.me_mapsize / mst_u.ms_psize);
|
||||
fprintf(fil_u, " number of pages used: %zu\n", mei_u.me_last_pgno+1);
|
||||
fprintf(fil_u, " last transaction ID: %zu\n", mei_u.me_last_txnid);
|
||||
fprintf(fil_u, " max readers: %u\n", mei_u.me_maxreaders);
|
||||
fprintf(fil_u, " number of readers used: %u\n", mei_u.me_numreaders);
|
||||
|
||||
siz_i = mst_u.ms_psize * (mei_u.me_last_pgno+1);
|
||||
}
|
||||
|
||||
{
|
||||
c3_i fid_i;
|
||||
struct stat sat_u;
|
||||
|
||||
mdb_env_get_fd(env_u, &fid_i);
|
||||
fstat(fid_i, &sat_u);
|
||||
|
||||
if ( siz_i != sat_u.st_size ) {
|
||||
fprintf(fil_u, "MISMATCH:\n");
|
||||
}
|
||||
|
||||
fprintf(fil_u, " file size (page): %zu\n", siz_i);
|
||||
fprintf(fil_u, " file size (stat): %jd\n", (intmax_t)sat_u.st_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_lmdb_gulf(): read first and last event numbers.
|
||||
*/
|
||||
c3_o
|
||||
|
@ -1467,6 +1467,10 @@ _http_serv_start(u3_http* htp_u)
|
||||
htonl(INADDR_LOOPBACK) :
|
||||
INADDR_ANY;
|
||||
|
||||
if ( 0 != u3_Host.ops_u.bin_c && c3n == htp_u->lop ) {
|
||||
inet_aton(u3_Host.ops_u.bin_c, &adr_u.sin_addr);
|
||||
}
|
||||
|
||||
uv_tcp_init(u3L, &htp_u->wax_u);
|
||||
|
||||
/* Try ascending ports.
|
||||
@ -1480,6 +1484,10 @@ _http_serv_start(u3_http* htp_u)
|
||||
(const struct sockaddr*)&adr_u, 0)) ||
|
||||
0 != (sas_i = uv_listen((uv_stream_t*)&htp_u->wax_u,
|
||||
TCP_BACKLOG, _http_serv_listen_cb)) ) {
|
||||
if ( UV_EADDRNOTAVAIL == sas_i ) {
|
||||
u3l_log("http: ip address not available\n");
|
||||
u3_king_bail();
|
||||
}
|
||||
if ( (UV_EADDRINUSE == sas_i) || (UV_EACCES == sas_i) ) {
|
||||
if ( (c3y == htp_u->sec) && (443 == htp_u->por_s) ) {
|
||||
htp_u->por_s = 8443;
|
||||
|
@ -35,7 +35,6 @@ struct _u3_ufil;
|
||||
c3_c* pax_c; // absolute path
|
||||
struct _u3_udir* par_u; // parent
|
||||
struct _u3_unod* nex_u; // internal list
|
||||
c3_w mug_w; // mug of last %into
|
||||
c3_w gum_w; // mug of last %ergo
|
||||
} u3_ufil;
|
||||
|
||||
@ -626,7 +625,6 @@ _unix_watch_file(u3_unix* unx_u, u3_ufil* fil_u, u3_udir* par_u, c3_c* pax_c)
|
||||
strcpy(fil_u->pax_c, pax_c);
|
||||
fil_u->par_u = par_u;
|
||||
fil_u->nex_u = NULL;
|
||||
fil_u->mug_w = 0;
|
||||
fil_u->gum_w = 0;
|
||||
|
||||
if ( par_u ) {
|
||||
@ -685,8 +683,8 @@ static u3_noun _unix_update_node(u3_unix* unx_u, u3_unod* nod_u);
|
||||
* when scanning through files, if dry, do nothing. otherwise, mark as
|
||||
* dry, then check if file exists. if not, remove self from node list
|
||||
* and add path plus sig to %into event. otherwise, read the file and
|
||||
* get a mug checksum. if same as mug_w, move on. otherwise, overwrite
|
||||
* mug_w with new mug and add path plus data to %into event.
|
||||
* get a mug checksum. if same as gum_w, move on. otherwise, overwrite
|
||||
* add path plus data to %into event.
|
||||
*/
|
||||
static u3_noun
|
||||
_unix_update_file(u3_unix* unx_u, u3_ufil* fil_u)
|
||||
@ -739,18 +737,11 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u)
|
||||
}
|
||||
else {
|
||||
c3_w mug_w = u3r_mug_bytes(dat_y, len_ws);
|
||||
if ( mug_w == fil_u->mug_w ) {
|
||||
c3_free(dat_y);
|
||||
return u3_nul;
|
||||
}
|
||||
else if ( mug_w == fil_u->gum_w ) {
|
||||
fil_u->mug_w = mug_w;
|
||||
if ( mug_w == fil_u->gum_w ) {
|
||||
c3_free(dat_y);
|
||||
return u3_nul;
|
||||
}
|
||||
else {
|
||||
fil_u->mug_w = mug_w;
|
||||
|
||||
u3_noun pax = _unix_string_to_path(unx_u, fil_u->pax_c);
|
||||
u3_noun mim = u3nt(c3__text, u3i_string("plain"), u3_nul);
|
||||
u3_noun dat = u3nt(mim, len_ws, u3i_bytes(len_ws, dat_y));
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
#include <vere/db/lmdb.h>
|
||||
|
||||
#define PIER_READ_BATCH 1000ULL
|
||||
#define PIER_PLAY_BATCH 500ULL
|
||||
#define PIER_WORK_BATCH 10ULL
|
||||
@ -1623,6 +1625,12 @@ u3_pier_stay(c3_w wag_w, u3_noun pax)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( c3y == u3_Host.ops_u.veb ) {
|
||||
FILE* fil_u = u3_term_io_hija();
|
||||
u3_lmdb_stat(pir_u->log_u->mdb_u, fil_u);
|
||||
u3_term_io_loja(1 );
|
||||
}
|
||||
|
||||
u3z(pax);
|
||||
|
||||
return pir_u;
|
||||
|
@ -1 +1 @@
|
||||
1.2
|
||||
1.3
|
Loading…
Reference in New Issue
Block a user