Merge 4df706b842 into release/next-js

This commit is contained in:
janeway-bot 2021-04-02 04:53:04 +04:00 committed by GitHub
commit df3ec7bfca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 769 additions and 15224 deletions

View File

@ -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
];
});
}

View File

@ -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"

View 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();
}
}

View File

@ -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]])
--

View File

@ -1,12 +0,0 @@
dist
cabal-dev
*.o
*.hi
*.chi
*.chs.h
.virtualenv
.hsenv
.cabal-sandbox/
cabal.sandbox.config
cabal.config
*~

View File

@ -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.

View File

@ -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
```

View File

@ -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

View File

@ -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 */
/** @} */
/** @} */

View File

@ -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

View File

@ -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

View File

@ -1,7 +1,6 @@
resolver: lts-16.15
packages:
- lmdb-static
- natpmp-static
- proto
- racquire

View File

@ -20,7 +20,7 @@ dependencies:
- rio
- vector
- bytestring
- lmdb-static
- lmdb
- conduit
- racquire
- urbit-noun-core

View File

@ -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

View File

@ -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

View File

@ -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 ->

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 "~"

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View 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)));
}

View 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)));
}

View File

@ -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",

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -1 +1 @@
1.2
1.3

View File

@ -33,7 +33,6 @@ in pkgsLocal.hs.shellFor {
# dependencies available in the shell.
packages = ps:
with ps; [
lmdb-static
racquire
terminal-progress-bar
urbit-atom