envio 2.29.2 → 2.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/evm.schema.json +18 -0
- package/package.json +5 -5
- package/src/Address.res +23 -0
- package/src/Address.res.js +14 -0
- package/src/Batch.res +103 -90
- package/src/Batch.res.js +81 -101
- package/src/FetchState.res +73 -129
- package/src/FetchState.res.js +87 -149
- package/src/Hasura.res +178 -124
- package/src/Hasura.res.js +115 -54
- package/src/Persistence.res +1 -13
- package/src/Persistence.res.js +1 -7
- package/src/PgStorage.res +0 -7
- package/src/PgStorage.res.js +1 -5
- package/src/Utils.res +10 -0
- package/src/Utils.res.js +5 -0
- package/src/bindings/Ethers.res +35 -11
- package/src/bindings/Ethers.res.js +21 -1
- package/src/bindings/PromClient.res +10 -0
- package/src/db/InternalTable.res +1 -59
- package/src/db/InternalTable.res.js +2 -34
- package/src/sources/HyperSyncClient.res +8 -2
- package/src/sources/HyperSyncClient.res.js +3 -2
- package/src/sources/HyperSyncSource.res +8 -1
- package/src/sources/HyperSyncSource.res.js +7 -2
- package/src/sources/RpcSource.res +153 -3
- package/src/sources/RpcSource.res.js +195 -73
package/evm.schema.json
CHANGED
|
@@ -113,6 +113,17 @@
|
|
|
113
113
|
"boolean",
|
|
114
114
|
"null"
|
|
115
115
|
]
|
|
116
|
+
},
|
|
117
|
+
"address_format": {
|
|
118
|
+
"description": "Address format for Ethereum addresses: 'checksum' or 'lowercase' (default: checksum)",
|
|
119
|
+
"anyOf": [
|
|
120
|
+
{
|
|
121
|
+
"$ref": "#/$defs/AddressFormat"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"type": "null"
|
|
125
|
+
}
|
|
126
|
+
]
|
|
116
127
|
}
|
|
117
128
|
},
|
|
118
129
|
"additionalProperties": false,
|
|
@@ -653,6 +664,13 @@
|
|
|
653
664
|
"viem",
|
|
654
665
|
"hypersync-client"
|
|
655
666
|
]
|
|
667
|
+
},
|
|
668
|
+
"AddressFormat": {
|
|
669
|
+
"type": "string",
|
|
670
|
+
"enum": [
|
|
671
|
+
"checksum",
|
|
672
|
+
"lowercase"
|
|
673
|
+
]
|
|
656
674
|
}
|
|
657
675
|
}
|
|
658
676
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v2.
|
|
3
|
+
"version": "v2.30.0",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://envio.dev",
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"envio-linux-x64": "v2.
|
|
29
|
-
"envio-linux-arm64": "v2.
|
|
30
|
-
"envio-darwin-x64": "v2.
|
|
31
|
-
"envio-darwin-arm64": "v2.
|
|
28
|
+
"envio-linux-x64": "v2.30.0",
|
|
29
|
+
"envio-linux-arm64": "v2.30.0",
|
|
30
|
+
"envio-darwin-x64": "v2.30.0",
|
|
31
|
+
"envio-darwin-arm64": "v2.30.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@envio-dev/hypersync-client": "0.6.6",
|
package/src/Address.res
CHANGED
|
@@ -10,6 +10,29 @@ external unsafeFromString: string => t = "%identity"
|
|
|
10
10
|
module Evm = {
|
|
11
11
|
@module("viem")
|
|
12
12
|
external fromStringOrThrow: string => t = "getAddress"
|
|
13
|
+
|
|
14
|
+
// NOTE: the function is named to be overshadowed by the one below, so that we don't have to import viem in the handler code
|
|
15
|
+
@module("viem")
|
|
16
|
+
external fromStringLowercaseOrThrow: string => bool = "isAddress"
|
|
17
|
+
|
|
18
|
+
// Reassign since the function might be used in the handler code
|
|
19
|
+
// and we don't want to have a "viem" import there. It's needed to keep "viem" a dependency
|
|
20
|
+
// of generated code instead of adding it to the indexer project dependencies.
|
|
21
|
+
// Also, we want a custom error message, which is searchable in our codebase.
|
|
22
|
+
// Validate that the string is a proper address but return a lowercased value
|
|
23
|
+
let fromStringLowercaseOrThrow = string => {
|
|
24
|
+
if fromStringLowercaseOrThrow(string) {
|
|
25
|
+
unsafeFromString(string->Js.String2.toLowerCase)
|
|
26
|
+
} else {
|
|
27
|
+
Js.Exn.raiseError(
|
|
28
|
+
`Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`,
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let fromAddressLowercaseOrThrow = address =>
|
|
34
|
+
address->toString->Js.String2.toLowerCase->(Utils.magic: string => t)
|
|
35
|
+
|
|
13
36
|
// Reassign since the function might be used in the handler code
|
|
14
37
|
// and we don't want to have a "viem" import there. It's needed to keep "viem" a dependency
|
|
15
38
|
// of generated code instead of adding it to the indexer project dependencies.
|
package/src/Address.res.js
CHANGED
|
@@ -7,6 +7,18 @@ var S$RescriptSchema = require("rescript-schema/src/S.res.js");
|
|
|
7
7
|
|
|
8
8
|
var schema = S$RescriptSchema.setName(S$RescriptSchema.string, "Address");
|
|
9
9
|
|
|
10
|
+
function fromStringLowercaseOrThrow(string) {
|
|
11
|
+
if (Viem.isAddress(string)) {
|
|
12
|
+
return string.toLowerCase();
|
|
13
|
+
} else {
|
|
14
|
+
return Js_exn.raiseError("Address \"" + string + "\" is invalid. Expected a 20-byte hex string starting with 0x.");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function fromAddressLowercaseOrThrow(address) {
|
|
19
|
+
return address.toLowerCase();
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
function fromStringOrThrow(string) {
|
|
11
23
|
try {
|
|
12
24
|
return Viem.getAddress(string);
|
|
@@ -21,6 +33,8 @@ function fromAddressOrThrow(address) {
|
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
var Evm = {
|
|
36
|
+
fromStringLowercaseOrThrow: fromStringLowercaseOrThrow,
|
|
37
|
+
fromAddressLowercaseOrThrow: fromAddressLowercaseOrThrow,
|
|
24
38
|
fromStringOrThrow: fromStringOrThrow,
|
|
25
39
|
fromAddressOrThrow: fromAddressOrThrow
|
|
26
40
|
};
|
package/src/Batch.res
CHANGED
|
@@ -2,146 +2,159 @@ type progressedChain = {
|
|
|
2
2
|
chainId: int,
|
|
3
3
|
batchSize: int,
|
|
4
4
|
progressBlockNumber: int,
|
|
5
|
-
|
|
5
|
+
isProgressAtHead: bool,
|
|
6
6
|
totalEventsProcessed: int,
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
type t = {
|
|
10
10
|
items: array<Internal.item>,
|
|
11
11
|
progressedChains: array<progressedChain>,
|
|
12
|
-
|
|
12
|
+
updatedFetchStates: ChainMap.t<FetchState.t>,
|
|
13
13
|
dcsToStoreByChainId: dict<array<FetchState.indexingContract>>,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
type multiChainEventComparitor = {
|
|
17
|
-
chain: ChainMap.Chain.t,
|
|
18
|
-
earliestEvent: FetchState.queueItem,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let getQueueItemComparitor = (earliestQueueItem: FetchState.queueItem, ~chain) => {
|
|
22
|
-
switch earliestQueueItem {
|
|
23
|
-
| Item({item}) => item->EventUtils.getOrderedBatchItemComparator
|
|
24
|
-
| NoItem({latestFetchedBlock: {blockTimestamp, blockNumber}}) => (
|
|
25
|
-
blockTimestamp,
|
|
26
|
-
chain->ChainMap.Chain.toChainId,
|
|
27
|
-
blockNumber,
|
|
28
|
-
0,
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let isQueueItemEarlier = (a: multiChainEventComparitor, b: multiChainEventComparitor): bool => {
|
|
34
|
-
a.earliestEvent->getQueueItemComparitor(~chain=a.chain) <
|
|
35
|
-
b.earliestEvent->getQueueItemComparitor(~chain=b.chain)
|
|
14
|
+
creationTimeMs: int,
|
|
36
15
|
}
|
|
37
16
|
|
|
38
17
|
/**
|
|
39
18
|
It either returnes an earliest item among all chains, or None if no chains are actively indexing
|
|
40
19
|
*/
|
|
41
|
-
let
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
fetchStates
|
|
45
|
-
->
|
|
46
|
-
|
|
47
|
-
|
|
20
|
+
let getOrderedNextChain = (fetchStates: ChainMap.t<FetchState.t>, ~batchSizePerChain) => {
|
|
21
|
+
let earliestChain: ref<option<FetchState.t>> = ref(None)
|
|
22
|
+
let earliestChainTimestamp = ref(0)
|
|
23
|
+
let chainKeys = fetchStates->ChainMap.keys
|
|
24
|
+
for idx in 0 to chainKeys->Array.length - 1 {
|
|
25
|
+
let chain = chainKeys->Array.get(idx)
|
|
26
|
+
let fetchState = fetchStates->ChainMap.get(chain)
|
|
48
27
|
if fetchState->FetchState.isActivelyIndexing {
|
|
49
|
-
let
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
28
|
+
let timestamp = fetchState->FetchState.getTimestampAt(
|
|
29
|
+
~index=switch batchSizePerChain->Utils.Dict.dangerouslyGetByIntNonOption(
|
|
30
|
+
chain->ChainMap.Chain.toChainId,
|
|
31
|
+
) {
|
|
32
|
+
| Some(batchSize) => batchSize
|
|
33
|
+
| None => 0
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
switch earliestChain.contents {
|
|
37
|
+
| Some(earliestChain)
|
|
38
|
+
if timestamp > earliestChainTimestamp.contents ||
|
|
39
|
+
(timestamp === earliestChainTimestamp.contents &&
|
|
40
|
+
chain->ChainMap.Chain.toChainId > earliestChain.chainId) => ()
|
|
41
|
+
| _ => {
|
|
42
|
+
earliestChain := Some(fetchState)
|
|
43
|
+
earliestChainTimestamp := timestamp
|
|
44
|
+
}
|
|
54
45
|
}
|
|
55
|
-
} else {
|
|
56
|
-
accum
|
|
57
46
|
}
|
|
58
|
-
}
|
|
47
|
+
}
|
|
48
|
+
earliestChain.contents
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Save overhead of recreating the dict every time
|
|
52
|
+
let immutableEmptyBatchSizePerChain: dict<int> = Js.Dict.empty()
|
|
53
|
+
let hasOrderedReadyItem = (fetchStates: ChainMap.t<FetchState.t>) => {
|
|
54
|
+
switch fetchStates->getOrderedNextChain(~batchSizePerChain=immutableEmptyBatchSizePerChain) {
|
|
55
|
+
| Some(fetchState) => fetchState->FetchState.hasReadyItem
|
|
56
|
+
| None => false
|
|
57
|
+
}
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
let
|
|
60
|
+
let hasUnorderedReadyItem = (fetchStates: ChainMap.t<FetchState.t>) => {
|
|
62
61
|
fetchStates
|
|
63
62
|
->ChainMap.values
|
|
64
63
|
->Js.Array2.some(fetchState => {
|
|
65
|
-
fetchState->FetchState.isActivelyIndexing &&
|
|
66
|
-
switch fetchState->FetchState.getEarliestEvent {
|
|
67
|
-
| Item(_) => true
|
|
68
|
-
| NoItem(_) => false
|
|
69
|
-
}
|
|
64
|
+
fetchState->FetchState.isActivelyIndexing && fetchState->FetchState.hasReadyItem
|
|
70
65
|
})
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
let
|
|
74
|
-
|
|
68
|
+
let hasMultichainReadyItem = (
|
|
69
|
+
fetchStates: ChainMap.t<FetchState.t>,
|
|
70
|
+
~multichain: InternalConfig.multichain,
|
|
71
|
+
) => {
|
|
72
|
+
switch multichain {
|
|
73
|
+
| Ordered => hasOrderedReadyItem(fetchStates)
|
|
74
|
+
| Unordered => hasUnorderedReadyItem(fetchStates)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let prepareOrderedBatch = (
|
|
79
|
+
~batchSizeTarget,
|
|
75
80
|
~fetchStates: ChainMap.t<FetchState.t>,
|
|
76
|
-
~
|
|
81
|
+
~mutBatchSizePerChain: dict<int>,
|
|
77
82
|
) => {
|
|
83
|
+
let batchSize = ref(0)
|
|
84
|
+
let isFinished = ref(false)
|
|
78
85
|
let items = []
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
while batchSize.contents < batchSizeTarget && !isFinished.contents {
|
|
88
|
+
switch fetchStates->getOrderedNextChain(~batchSizePerChain=mutBatchSizePerChain) {
|
|
89
|
+
| Some(fetchState) => {
|
|
90
|
+
let itemsCountBefore = switch mutBatchSizePerChain->Utils.Dict.dangerouslyGetByIntNonOption(
|
|
91
|
+
fetchState.chainId,
|
|
92
|
+
) {
|
|
93
|
+
| Some(batchSize) => batchSize
|
|
94
|
+
| None => 0
|
|
95
|
+
}
|
|
96
|
+
let newItemsCount =
|
|
97
|
+
fetchState->FetchState.getReadyItemsCount(
|
|
98
|
+
~targetSize=batchSizeTarget - batchSize.contents,
|
|
99
|
+
~fromItem=itemsCountBefore,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if newItemsCount > 0 {
|
|
103
|
+
for idx in itemsCountBefore to itemsCountBefore + newItemsCount - 1 {
|
|
104
|
+
items->Js.Array2.push(fetchState.buffer->Belt.Array.getUnsafe(idx))->ignore
|
|
91
105
|
}
|
|
106
|
+
batchSize := batchSize.contents + newItemsCount
|
|
107
|
+
mutBatchSizePerChain->Utils.Dict.setByInt(
|
|
108
|
+
fetchState.chainId,
|
|
109
|
+
itemsCountBefore + newItemsCount,
|
|
110
|
+
)
|
|
111
|
+
} else {
|
|
112
|
+
isFinished := true
|
|
92
113
|
}
|
|
93
|
-
| _ => ()
|
|
94
114
|
}
|
|
115
|
+
|
|
116
|
+
| None => isFinished := true
|
|
95
117
|
}
|
|
96
|
-
|
|
118
|
+
}
|
|
97
119
|
|
|
98
120
|
items
|
|
99
121
|
}
|
|
100
122
|
|
|
101
|
-
let
|
|
102
|
-
~
|
|
123
|
+
let prepareUnorderedBatch = (
|
|
124
|
+
~batchSizeTarget,
|
|
103
125
|
~fetchStates: ChainMap.t<FetchState.t>,
|
|
104
|
-
~
|
|
126
|
+
~mutBatchSizePerChain: dict<int>,
|
|
105
127
|
) => {
|
|
106
|
-
let items = []
|
|
107
|
-
|
|
108
128
|
let preparedFetchStates =
|
|
109
129
|
fetchStates
|
|
110
130
|
->ChainMap.values
|
|
111
|
-
->FetchState.filterAndSortForUnorderedBatch(~
|
|
131
|
+
->FetchState.filterAndSortForUnorderedBatch(~batchSizeTarget)
|
|
112
132
|
|
|
113
|
-
let
|
|
133
|
+
let chainIdx = ref(0)
|
|
114
134
|
let preparedNumber = preparedFetchStates->Array.length
|
|
115
135
|
let batchSize = ref(0)
|
|
116
136
|
|
|
137
|
+
let items = []
|
|
138
|
+
|
|
117
139
|
// Accumulate items for all actively indexing chains
|
|
118
140
|
// the way to group as many items from a single chain as possible
|
|
119
141
|
// This way the loaders optimisations will hit more often
|
|
120
|
-
while batchSize.contents <
|
|
121
|
-
let fetchState = preparedFetchStates->Js.Array2.unsafe_get(
|
|
122
|
-
let
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
switch earliestEvent {
|
|
128
|
-
| NoItem(_) => ()
|
|
129
|
-
| Item({item, popItemOffQueue}) => {
|
|
130
|
-
popItemOffQueue()
|
|
131
|
-
items->Js.Array2.push(item)->ignore
|
|
132
|
-
batchSize := batchSize.contents + 1
|
|
133
|
-
loop()
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
loop()
|
|
138
|
-
|
|
139
|
-
let chainBatchSize = batchSize.contents - batchSizeBeforeTheChain
|
|
142
|
+
while batchSize.contents < batchSizeTarget && chainIdx.contents < preparedNumber {
|
|
143
|
+
let fetchState = preparedFetchStates->Js.Array2.unsafe_get(chainIdx.contents)
|
|
144
|
+
let chainBatchSize =
|
|
145
|
+
fetchState->FetchState.getReadyItemsCount(
|
|
146
|
+
~targetSize=batchSizeTarget - batchSize.contents,
|
|
147
|
+
~fromItem=0,
|
|
148
|
+
)
|
|
140
149
|
if chainBatchSize > 0 {
|
|
141
|
-
|
|
150
|
+
for idx in 0 to chainBatchSize - 1 {
|
|
151
|
+
items->Js.Array2.push(fetchState.buffer->Belt.Array.getUnsafe(idx))->ignore
|
|
152
|
+
}
|
|
153
|
+
batchSize := batchSize.contents + chainBatchSize
|
|
154
|
+
mutBatchSizePerChain->Utils.Dict.setByInt(fetchState.chainId, chainBatchSize)
|
|
142
155
|
}
|
|
143
156
|
|
|
144
|
-
|
|
157
|
+
chainIdx := chainIdx.contents + 1
|
|
145
158
|
}
|
|
146
159
|
|
|
147
160
|
items
|
package/src/Batch.res.js
CHANGED
|
@@ -1,133 +1,113 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var Utils = require("./Utils.res.js");
|
|
5
|
-
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
6
4
|
var ChainMap = require("./ChainMap.res.js");
|
|
7
|
-
var
|
|
8
|
-
var EventUtils = require("./EventUtils.res.js");
|
|
5
|
+
var Caml_array = require("rescript/lib/js/caml_array.js");
|
|
9
6
|
var FetchState = require("./FetchState.res.js");
|
|
10
7
|
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
function getOrderedNextChain(fetchStates, batchSizePerChain) {
|
|
9
|
+
var earliestChain;
|
|
10
|
+
var earliestChainTimestamp = 0;
|
|
11
|
+
var chainKeys = ChainMap.keys(fetchStates);
|
|
12
|
+
for(var idx = 0 ,idx_finish = chainKeys.length; idx < idx_finish; ++idx){
|
|
13
|
+
var chain = Caml_array.get(chainKeys, idx);
|
|
14
|
+
var fetchState = ChainMap.get(fetchStates, chain);
|
|
15
|
+
if (FetchState.isActivelyIndexing(fetchState)) {
|
|
16
|
+
var batchSize = batchSizePerChain[chain];
|
|
17
|
+
var timestamp = FetchState.getTimestampAt(fetchState, batchSize !== undefined ? batchSize : 0);
|
|
18
|
+
var earliestChain$1 = earliestChain;
|
|
19
|
+
if (!(earliestChain$1 !== undefined && (timestamp > earliestChainTimestamp || timestamp === earliestChainTimestamp && chain > earliestChain$1.chainId))) {
|
|
20
|
+
earliestChain = fetchState;
|
|
21
|
+
earliestChainTimestamp = timestamp;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
}
|
|
15
|
-
|
|
16
|
-
return [
|
|
17
|
-
match.blockTimestamp,
|
|
18
|
-
chain,
|
|
19
|
-
match.blockNumber,
|
|
20
|
-
0
|
|
21
|
-
];
|
|
27
|
+
return earliestChain;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
return Caml_obj.lessthan(getQueueItemComparitor(a.earliestEvent, a.chain), getQueueItemComparitor(b.earliestEvent, b.chain));
|
|
26
|
-
}
|
|
30
|
+
var immutableEmptyBatchSizePerChain = {};
|
|
27
31
|
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var current_chain = param[0];
|
|
36
|
-
var current = {
|
|
37
|
-
chain: current_chain,
|
|
38
|
-
earliestEvent: earliestEvent
|
|
39
|
-
};
|
|
40
|
-
if (accum !== undefined && isQueueItemEarlier(accum, current)) {
|
|
41
|
-
return accum;
|
|
42
|
-
} else {
|
|
43
|
-
return current;
|
|
44
|
-
}
|
|
45
|
-
}));
|
|
32
|
+
function hasOrderedReadyItem(fetchStates) {
|
|
33
|
+
var fetchState = getOrderedNextChain(fetchStates, immutableEmptyBatchSizePerChain);
|
|
34
|
+
if (fetchState !== undefined) {
|
|
35
|
+
return FetchState.hasReadyItem(fetchState);
|
|
36
|
+
} else {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
function
|
|
41
|
+
function hasUnorderedReadyItem(fetchStates) {
|
|
49
42
|
return ChainMap.values(fetchStates).some(function (fetchState) {
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
var match = FetchState.getEarliestEvent(fetchState);
|
|
54
|
-
if (match.TAG === "Item") {
|
|
55
|
-
return true;
|
|
43
|
+
if (FetchState.isActivelyIndexing(fetchState)) {
|
|
44
|
+
return FetchState.hasReadyItem(fetchState);
|
|
56
45
|
} else {
|
|
57
46
|
return false;
|
|
58
47
|
}
|
|
59
48
|
});
|
|
60
49
|
}
|
|
61
50
|
|
|
62
|
-
function
|
|
51
|
+
function hasMultichainReadyItem(fetchStates, multichain) {
|
|
52
|
+
if (multichain === "ordered") {
|
|
53
|
+
return hasOrderedReadyItem(fetchStates);
|
|
54
|
+
} else {
|
|
55
|
+
return hasUnorderedReadyItem(fetchStates);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function prepareOrderedBatch(batchSizeTarget, fetchStates, mutBatchSizePerChain) {
|
|
60
|
+
var batchSize = 0;
|
|
61
|
+
var isFinished = false;
|
|
63
62
|
var items = [];
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
var
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
while(batchSize < batchSizeTarget && !isFinished) {
|
|
64
|
+
var fetchState = getOrderedNextChain(fetchStates, mutBatchSizePerChain);
|
|
65
|
+
if (fetchState !== undefined) {
|
|
66
|
+
var batchSize$1 = mutBatchSizePerChain[fetchState.chainId];
|
|
67
|
+
var itemsCountBefore = batchSize$1 !== undefined ? batchSize$1 : 0;
|
|
68
|
+
var newItemsCount = FetchState.getReadyItemsCount(fetchState, batchSizeTarget - batchSize | 0, itemsCountBefore);
|
|
69
|
+
if (newItemsCount > 0) {
|
|
70
|
+
for(var idx = itemsCountBefore ,idx_finish = itemsCountBefore + newItemsCount | 0; idx < idx_finish; ++idx){
|
|
71
|
+
items.push(fetchState.buffer[idx]);
|
|
72
|
+
}
|
|
73
|
+
batchSize = batchSize + newItemsCount | 0;
|
|
74
|
+
mutBatchSizePerChain[fetchState.chainId] = itemsCountBefore + newItemsCount | 0;
|
|
75
|
+
} else {
|
|
76
|
+
isFinished = true;
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Utils.Dict.incrementByInt(sizePerChain, match.chain);
|
|
81
|
-
continue ;
|
|
82
|
-
};
|
|
78
|
+
} else {
|
|
79
|
+
isFinished = true;
|
|
80
|
+
}
|
|
83
81
|
};
|
|
84
|
-
loop();
|
|
85
82
|
return items;
|
|
86
83
|
}
|
|
87
84
|
|
|
88
|
-
function
|
|
89
|
-
var
|
|
90
|
-
var
|
|
91
|
-
var idx = 0;
|
|
85
|
+
function prepareUnorderedBatch(batchSizeTarget, fetchStates, mutBatchSizePerChain) {
|
|
86
|
+
var preparedFetchStates = FetchState.filterAndSortForUnorderedBatch(ChainMap.values(fetchStates), batchSizeTarget);
|
|
87
|
+
var chainIdx = 0;
|
|
92
88
|
var preparedNumber = preparedFetchStates.length;
|
|
93
|
-
var batchSize =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
var
|
|
98
|
-
var batchSizeBeforeTheChain = batchSize.contents;
|
|
99
|
-
var loop = (function(fetchState){
|
|
100
|
-
return function loop() {
|
|
101
|
-
while(true) {
|
|
102
|
-
if (batchSize.contents >= maxBatchSize) {
|
|
103
|
-
return ;
|
|
104
|
-
}
|
|
105
|
-
var earliestEvent = FetchState.getEarliestEvent(fetchState);
|
|
106
|
-
if (earliestEvent.TAG !== "Item") {
|
|
107
|
-
return ;
|
|
108
|
-
}
|
|
109
|
-
var match = earliestEvent._0;
|
|
110
|
-
match.popItemOffQueue();
|
|
111
|
-
items.push(match.item);
|
|
112
|
-
batchSize.contents = batchSize.contents + 1 | 0;
|
|
113
|
-
continue ;
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
}(fetchState));
|
|
117
|
-
loop();
|
|
118
|
-
var chainBatchSize = batchSize.contents - batchSizeBeforeTheChain | 0;
|
|
89
|
+
var batchSize = 0;
|
|
90
|
+
var items = [];
|
|
91
|
+
while(batchSize < batchSizeTarget && chainIdx < preparedNumber) {
|
|
92
|
+
var fetchState = preparedFetchStates[chainIdx];
|
|
93
|
+
var chainBatchSize = FetchState.getReadyItemsCount(fetchState, batchSizeTarget - batchSize | 0, 0);
|
|
119
94
|
if (chainBatchSize > 0) {
|
|
120
|
-
|
|
95
|
+
for(var idx = 0; idx < chainBatchSize; ++idx){
|
|
96
|
+
items.push(fetchState.buffer[idx]);
|
|
97
|
+
}
|
|
98
|
+
batchSize = batchSize + chainBatchSize | 0;
|
|
99
|
+
mutBatchSizePerChain[fetchState.chainId] = chainBatchSize;
|
|
121
100
|
}
|
|
122
|
-
|
|
101
|
+
chainIdx = chainIdx + 1 | 0;
|
|
123
102
|
};
|
|
124
103
|
return items;
|
|
125
104
|
}
|
|
126
105
|
|
|
127
|
-
exports.
|
|
128
|
-
exports.
|
|
129
|
-
exports.
|
|
130
|
-
exports.
|
|
131
|
-
exports.
|
|
132
|
-
exports.
|
|
133
|
-
|
|
106
|
+
exports.getOrderedNextChain = getOrderedNextChain;
|
|
107
|
+
exports.immutableEmptyBatchSizePerChain = immutableEmptyBatchSizePerChain;
|
|
108
|
+
exports.hasOrderedReadyItem = hasOrderedReadyItem;
|
|
109
|
+
exports.hasUnorderedReadyItem = hasUnorderedReadyItem;
|
|
110
|
+
exports.hasMultichainReadyItem = hasMultichainReadyItem;
|
|
111
|
+
exports.prepareOrderedBatch = prepareOrderedBatch;
|
|
112
|
+
exports.prepareUnorderedBatch = prepareUnorderedBatch;
|
|
113
|
+
/* ChainMap Not a pure module */
|