functionalscript 0.0.278 → 0.0.282
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/package.json +1 -1
- package/test.js +1 -0
- package/types/btree/README.md +55 -2
- package/types/btree/index.js +200 -93
- package/types/btree/test.js +78 -3
- package/types/function/compare/index.js +11 -3
- package/types/function/compare/test.js +13 -0
- package/types/map/index.js +3 -3
package/package.json
CHANGED
package/test.js
CHANGED
|
@@ -9,6 +9,7 @@ require('./io/commonjs/test')
|
|
|
9
9
|
require('./commonjs/package/dependencies/test')
|
|
10
10
|
require('./commonjs/package/test')
|
|
11
11
|
require('./commonjs/path/test')
|
|
12
|
+
require('./types/function/compare/test')
|
|
12
13
|
|
|
13
14
|
/** @type {() => never} */
|
|
14
15
|
const assert = () => { throw 'assert' }
|
package/types/btree/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
https://en.wikipedia.org/wiki/B-tree
|
|
4
4
|
|
|
5
|
-
## BTree 2-3 nodes
|
|
5
|
+
## BTree 2-3 nodes
|
|
6
6
|
|
|
7
7
|
`Node<T>`:
|
|
8
8
|
|
|
@@ -66,7 +66,7 @@ Posible actions:
|
|
|
66
66
|
|left | 0|`[(L VM R) v1 n2]` |
|
|
67
67
|
|right | 2|`[n0 v1 (L VM R)]` |
|
|
68
68
|
|
|
69
|
-
## Branch5 Overflow
|
|
69
|
+
## Branch5 Overflow
|
|
70
70
|
|
|
71
71
|
- current `[n0, v1, n2, v3, n4]`
|
|
72
72
|
- overflow `[L, VM, R]`
|
|
@@ -76,3 +76,56 @@ Posible actions:
|
|
|
76
76
|
|left | 0|`[...o v1 n2 v3 n4]`|`[(L VM R) v1 n2 v3 n4]`|`[[ L VM R ] v1 [n2 v3 n4]]`|
|
|
77
77
|
|middle| 2|`[n0 v1 ...o v3 n4]`|`[n0 v1 (L VM R) v3 n4]`|`[[n0 v1 L ] VM [ R v3 n4]]`|
|
|
78
78
|
|right | 4|`[n0 v1 n2 v3 ...o]`|`[n0 v1 n2 v3 (L VM R)]`|`[[n0 v1 n2] v3 [ L VM R ]]`|
|
|
79
|
+
|
|
80
|
+
## Deleting a Node
|
|
81
|
+
|
|
82
|
+
|type |index| | | |
|
|
83
|
+
|------------------|-----|---------------------|--------|-----------------------------|
|
|
84
|
+
|`[v]` | 0| | |underflow `undefined` |
|
|
85
|
+
|`[v0,v1]` | 0| | |replace `[v1]` |
|
|
86
|
+
| | 1| | |replace `[v0]` |
|
|
87
|
+
|`[n0,v1,n2]` | 1|`concat(n0,n2)` |overflow|replace `[n0_,v1_,n1_]` |
|
|
88
|
+
| | | |replace |underflow `n_` |
|
|
89
|
+
|`[n0,v1,n2,v3,n4]`| 1|`concat(n0,n2),v3,n4`|overflow|replace `[n0_,v1_,n1_,v3,n4]`|
|
|
90
|
+
| | | |replace |replace `[n_,v3,n4]` |
|
|
91
|
+
| | 3|`n0,v1,concat(n2,n4)`|overflow|replace `[n0,v1,n0_,v1_,n1_]`|
|
|
92
|
+
| | | |replace |replace `[n0,v1,n_]` |
|
|
93
|
+
|
|
94
|
+
### Underflow
|
|
95
|
+
|
|
96
|
+
|type |index| | |
|
|
97
|
+
|------------------|-----|---------------------------------------|-----------------------------------------------|
|
|
98
|
+
|`[n0,v1,n2]` | 0|`[[],v1,[v20]]` |underflow `[v1,v20]` |
|
|
99
|
+
| | |`[[],v1,[v20,v21]]` |replace `[[v1],v20,[v21]]` |
|
|
100
|
+
| | |`[[n_],v1,[n20,v21,n22]]` |underflow `[n_,v1,n20,v21,n22]` |
|
|
101
|
+
| | |`[[n_],v1,[n20,v21,n22,v23,n24]]` |replace `[[n_,v1,n20],v21,[n22,v23,n24]]` |
|
|
102
|
+
| | 2| | |
|
|
103
|
+
|`[n0,v1,n2,v3,n4]`| 0|`[[],v1,[v20],v3,n4]` |replace `[[v1,v20],v3,n4]` |
|
|
104
|
+
| | |`[[],v1,[v20,v21],v3,n4]` |replace `[[v1],v20,[v21],v3,n4]` |
|
|
105
|
+
| | |`[[n_],v1,[n20,v21,n22],v3,n4]` |replace `[[n_,v1,n20,v21,n22],v3,n4]` |
|
|
106
|
+
| | |`[[n_],v1,[n20,v21,n22,v23,n24],v3,n4]`|replace `[[n_,v1,n20],v21,[n22,v23,n24],v3,n4]`|
|
|
107
|
+
| | 2| | |
|
|
108
|
+
| | 4| | |
|
|
109
|
+
|
|
110
|
+
## Concat (n0,n1)
|
|
111
|
+
|
|
112
|
+
`concat` returns either `overflow 3` or `replace`:
|
|
113
|
+
- `overflow 3`: `[n0,v1,n2]`
|
|
114
|
+
- `replace`: `n`
|
|
115
|
+
|
|
116
|
+
|`n0` |`n1` | |
|
|
117
|
+
|-----------------------|-----------------------|-------------------------------------------------|
|
|
118
|
+
|`[v00]` |`[v10]` |R `[v00,v10]` |
|
|
119
|
+
| |`[v10,v11]` |O `[[v00],v10,[v11]]` |
|
|
120
|
+
|`[v00,v01]` |`n1` |O `[[v00],v01,n1]` |
|
|
121
|
+
|`[n00,v01,n02]` |`[n10,v11,n12]` |`n00,v01,concat(n02,n10),v11,n12` |
|
|
122
|
+
| |`[n10,v11,n12,v13,n14]`|`n00,v01,concat(n02,n10),v11,n12,v13,n14` |
|
|
123
|
+
|`[n00,v01,n02,v03,n04]`|`[n10,v11,n12]` |`n00,v01,n02,v03,concat(n04,n10),v11,n12` |
|
|
124
|
+
| |`[n10,v11,n12,v13,n14]`|`n00,v01,n02,v03,concat(n04,n10),v11,n12,v13,n14`|
|
|
125
|
+
|
|
126
|
+
|source |replace `cn` |overflow `[cn0,cv1,cn2]` |
|
|
127
|
+
|---------------------------------------|------------------------------------|---------------------------------------------|
|
|
128
|
+
|`n0,v1,concat(n2,n3),v4,n5` |R `[n0,v1,cn,v2,n3]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5]]` |
|
|
129
|
+
|`n0,v1,concat(n2,n3),v4,n5,v6,n7` |O `[[n0,v1,cn],v4,[n5,v6,n7]]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5,v6,n7]]` |
|
|
130
|
+
|`n0,v1,n2,v3,concat(n4,n5),v6,n7` |O `[[n0,v1,n2],v3,[cn,v6,n7]]` |O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7]]` |
|
|
131
|
+
|`n0,v1,n2,v3,concat(n4,n5),v6,n7,v8,n9`|O `[[n0,v1,n2],v3,[cn,v6,n7,v8,n9]]`|O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7,v8,n9]]`|
|
package/types/btree/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { todo } = require('../../dev')
|
|
1
2
|
const cmp = require('../function/compare')
|
|
2
3
|
const { index3, index5 } = cmp
|
|
3
4
|
const seq = require('../list')
|
|
@@ -87,10 +88,10 @@ const seq = require('../list')
|
|
|
87
88
|
* @typedef { Done<T> | Replace<T> | Overflow<T> } Result
|
|
88
89
|
*/
|
|
89
90
|
|
|
90
|
-
/** @typedef {<T>(_:
|
|
91
|
-
/** @typedef {<T>(_:
|
|
92
|
-
/** @typedef {<T>(_:
|
|
93
|
-
/** @typedef {<T>(_:
|
|
91
|
+
/** @typedef {<T>(_: Leaf1<T>) => LazyResult<T>} InLeaf1 */
|
|
92
|
+
/** @typedef {<T>(_: Leaf2<T>) => LazyResult<T>} InLeaf2 */
|
|
93
|
+
/** @typedef {<T>(_: Branch3<T>) => LazyResult<T>} InBranch3 */
|
|
94
|
+
/** @typedef {<T>(_: Branch5<T>) => LazyResult<T>} InBranch5 */
|
|
94
95
|
|
|
95
96
|
/**
|
|
96
97
|
* @typedef {{
|
|
@@ -113,6 +114,21 @@ const seq = require('../list')
|
|
|
113
114
|
* }} NotFound
|
|
114
115
|
*/
|
|
115
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @template T
|
|
119
|
+
* @typedef {(f: (_: Node<T>) => LazyResult<T>) => LazyResult<T>} FResult<T>
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @typedef {{
|
|
124
|
+
* readonly branch3_left: <T>(branch3: Branch3<T>) => FResult<T>
|
|
125
|
+
* readonly branch3_right: <T>(branch3: Branch3<T>) => FResult<T>
|
|
126
|
+
* readonly branch5_left: <T>(branch5: Branch5<T>) => FResult<T>
|
|
127
|
+
* readonly branch5_middle: <T>(branch5: Branch5<T>) => FResult<T>
|
|
128
|
+
* readonly branch5_right: <T>(branch5: Branch5<T>) => FResult<T>
|
|
129
|
+
* }} Continue
|
|
130
|
+
*/
|
|
131
|
+
|
|
116
132
|
/**
|
|
117
133
|
* @typedef {{
|
|
118
134
|
* readonly found: Found
|
|
@@ -122,19 +138,25 @@ const seq = require('../list')
|
|
|
122
138
|
|
|
123
139
|
/**
|
|
124
140
|
* @template T
|
|
125
|
-
* @typedef { readonly
|
|
141
|
+
* @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
|
|
126
142
|
*/
|
|
127
143
|
|
|
128
144
|
/** @type {<T>(n: Branch7<T>) => Branch3<T>} */
|
|
129
145
|
const split = ([n0, v1, n2, v3, n4, v5, n6]) => [[n0, v1, n2], v3, [n4, v5, n6]]
|
|
130
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @template T
|
|
149
|
+
* @typedef {(init: Lazy<T>) => Result<T>} LazyResult
|
|
150
|
+
*/
|
|
151
|
+
|
|
131
152
|
/**
|
|
132
153
|
* @type {<T>(extend: (o: Branch3<T>) => Result<T>) =>
|
|
133
154
|
* (replace: (r: Node<T>) => Node<T>) =>
|
|
134
|
-
* (result:
|
|
135
|
-
*
|
|
155
|
+
* (result: LazyResult<T>) =>
|
|
156
|
+
* LazyResult<T>}
|
|
136
157
|
*/
|
|
137
|
-
const merge = extend => replace =>
|
|
158
|
+
const merge = extend => replace => lazyResult => init => {
|
|
159
|
+
const result = lazyResult(init)
|
|
138
160
|
switch (result[0]) {
|
|
139
161
|
case 'done': { return result }
|
|
140
162
|
case 'replace': { return ['replace', replace(result[1])] }
|
|
@@ -142,7 +164,7 @@ const merge = extend => replace => result => {
|
|
|
142
164
|
}
|
|
143
165
|
}
|
|
144
166
|
|
|
145
|
-
/** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (
|
|
167
|
+
/** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (node: Node<T>) => LazyResult<T>} */
|
|
146
168
|
const visit = ({ found, notFound }) => cmp => {
|
|
147
169
|
const i3 = index3(cmp)
|
|
148
170
|
const i5 = index5(cmp)
|
|
@@ -150,84 +172,82 @@ const visit = ({ found, notFound }) => cmp => {
|
|
|
150
172
|
/**
|
|
151
173
|
* @type {(extend: (o: Branch3<T>) => Branch5<T>) =>
|
|
152
174
|
* (replace: (r: Node<T>) => Branch3<T>) =>
|
|
153
|
-
* (result:
|
|
154
|
-
*
|
|
175
|
+
* (result: LazyResult<T>) =>
|
|
176
|
+
* LazyResult<T>}
|
|
155
177
|
*/
|
|
156
178
|
const merge2 = extend => merge(o => ['replace', extend(o)])
|
|
157
179
|
/**
|
|
158
180
|
* @type {(extend: (o: Branch3<T>) => Branch7<T>) =>
|
|
159
181
|
* (replace: (r: Node<T>) => Branch5<T>) =>
|
|
160
|
-
* (result:
|
|
161
|
-
*
|
|
182
|
+
* (result: LazyResult<T>) =>
|
|
183
|
+
* LazyResult<T>}
|
|
162
184
|
*/
|
|
163
185
|
const merge3 = extend => merge(o => ['overflow', split(extend(o))])
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
default: { return notFound.leaf1_right(init)(node) }
|
|
173
|
-
}
|
|
186
|
+
/** @type {(node: Node<T>) => LazyResult<T>} */
|
|
187
|
+
const f = node => {
|
|
188
|
+
switch (node.length) {
|
|
189
|
+
case 1: {
|
|
190
|
+
switch (i3(node[0])) {
|
|
191
|
+
case 0: { return notFound.leaf1_left(node) }
|
|
192
|
+
case 1: { return found.leaf1(node) }
|
|
193
|
+
default: { return notFound.leaf1_right(node) }
|
|
174
194
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
195
|
+
}
|
|
196
|
+
case 2: {
|
|
197
|
+
switch (i5(node)) {
|
|
198
|
+
case 0: { return notFound.leaf2_left(node) }
|
|
199
|
+
case 1: { return found.leaf2_left(node) }
|
|
200
|
+
case 2: { return notFound.leaf2_middle(node) }
|
|
201
|
+
case 3: { return found.leaf2_right(node) }
|
|
202
|
+
default: { return notFound.leaf2_right(node) }
|
|
183
203
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
204
|
+
}
|
|
205
|
+
case 3: {
|
|
206
|
+
const [n0, v1, n2] = node
|
|
207
|
+
switch (i3(v1)) {
|
|
208
|
+
case 0: {
|
|
209
|
+
return merge2
|
|
210
|
+
(e => [...e, v1, n2])
|
|
211
|
+
(r => [r, v1, n2])
|
|
212
|
+
(f(n0))
|
|
213
|
+
}
|
|
214
|
+
case 1: { return found.branch3(node) }
|
|
215
|
+
default: {
|
|
216
|
+
return merge2
|
|
217
|
+
(e => [n0, v1, ...e])
|
|
218
|
+
(r => [n0, v1, r])
|
|
219
|
+
(f(n2))
|
|
200
220
|
}
|
|
201
221
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
}
|
|
223
|
+
default: {
|
|
224
|
+
const [n0, v1, n2, v3, n4] = node
|
|
225
|
+
switch (i5([v1, v3])) {
|
|
226
|
+
case 0: {
|
|
227
|
+
return merge3
|
|
228
|
+
(o => [...o, v1, n2, v3, n4])
|
|
229
|
+
(r => [r, v1, n2, v3, n4])
|
|
230
|
+
(f(n0))
|
|
231
|
+
}
|
|
232
|
+
case 1: { return found.branch5_left(node) }
|
|
233
|
+
case 2: {
|
|
234
|
+
return merge3
|
|
235
|
+
(o => [n0, v1, ...o, v3, n4])
|
|
236
|
+
(r => [n0, v1, r, v3, n4])
|
|
237
|
+
(f(n2))
|
|
238
|
+
}
|
|
239
|
+
case 3: { return found.branch5_right(node) }
|
|
240
|
+
default: {
|
|
241
|
+
return merge3
|
|
242
|
+
(o => [n0, v1, n2, v3, ...o])
|
|
243
|
+
(r => [n0, v1, n2, v3, r])
|
|
244
|
+
(f(n4))
|
|
225
245
|
}
|
|
226
246
|
}
|
|
227
247
|
}
|
|
228
248
|
}
|
|
229
|
-
return f
|
|
230
249
|
}
|
|
250
|
+
return f
|
|
231
251
|
}
|
|
232
252
|
|
|
233
253
|
/** @type { <T>(_: T) => Done<T> } */
|
|
@@ -235,12 +255,12 @@ const found = value => ['done', value]
|
|
|
235
255
|
|
|
236
256
|
/** @type {Found} */
|
|
237
257
|
const foundGet = {
|
|
238
|
-
leaf1: () => (
|
|
239
|
-
leaf2_left: () => (
|
|
240
|
-
leaf2_right: (
|
|
241
|
-
branch3: (
|
|
242
|
-
branch5_left: (
|
|
243
|
-
branch5_right: (
|
|
258
|
+
leaf1: ([value]) => () => found(value),
|
|
259
|
+
leaf2_left: ([value]) => () => found(value),
|
|
260
|
+
leaf2_right: ([, value]) => () => found(value),
|
|
261
|
+
branch3: ([, value]) => () => found(value),
|
|
262
|
+
branch5_left: ([, value]) => () => found(value),
|
|
263
|
+
branch5_right: ([, , , value]) => () => found(value),
|
|
244
264
|
}
|
|
245
265
|
/** @type { () => () => NotFoundDone } */
|
|
246
266
|
const notFound = () => () => ['done']
|
|
@@ -259,12 +279,12 @@ const replace = node => ['replace', node]
|
|
|
259
279
|
|
|
260
280
|
/** @type {Found} */
|
|
261
281
|
const foundReplace = {
|
|
262
|
-
leaf1:
|
|
263
|
-
leaf2_left:
|
|
264
|
-
leaf2_right:
|
|
265
|
-
branch3:
|
|
266
|
-
branch5_left:
|
|
267
|
-
branch5_right:
|
|
282
|
+
leaf1: () => f => replace([f()]),
|
|
283
|
+
leaf2_left: ([, v1]) => f => replace([f(), v1]),
|
|
284
|
+
leaf2_right: ([v0,]) => f => replace([v0, f()]),
|
|
285
|
+
branch3: ([n0, , n2]) => f => replace([n0, f(), n2]),
|
|
286
|
+
branch5_left: ([n0, , n2, v3, n4]) => f => replace([n0, f(), n2, v3, n4]),
|
|
287
|
+
branch5_right: ([n0, v1, n2, , n4]) => f => replace([n0, v1, n2, f(), n4])
|
|
268
288
|
}
|
|
269
289
|
|
|
270
290
|
/** @type {<T>(leaf3: Array3<T>) => Result<T>} */
|
|
@@ -272,11 +292,11 @@ const overflow = ([v0, v1, v2]) => ['overflow', [[v0], v1, [v2]]]
|
|
|
272
292
|
|
|
273
293
|
/** @type {NotFound} */
|
|
274
294
|
const notFoundInsert = {
|
|
275
|
-
leaf1_left:
|
|
276
|
-
leaf1_right:
|
|
277
|
-
leaf2_left:
|
|
278
|
-
leaf2_middle:
|
|
279
|
-
leaf2_right:
|
|
295
|
+
leaf1_left: ([v]) => f => replace([f(), v]),
|
|
296
|
+
leaf1_right: ([v]) => f => replace([v, f()]),
|
|
297
|
+
leaf2_left: ([v0, v1]) => f => overflow([f(), v0, v1]),
|
|
298
|
+
leaf2_middle: ([v0, v1]) => f => overflow([v0, f(), v1]),
|
|
299
|
+
leaf2_right: ([v0, v1]) => f => overflow([v0, v1, f()]),
|
|
280
300
|
}
|
|
281
301
|
|
|
282
302
|
/** @type {Visitor} */
|
|
@@ -303,7 +323,7 @@ const replaceVisitor = {
|
|
|
303
323
|
notFound: notFoundGet,
|
|
304
324
|
}
|
|
305
325
|
|
|
306
|
-
/** @type {<T>(node: Node<T>) => seq.
|
|
326
|
+
/** @type {<T>(node: Node<T>) => seq.Thunk<T>} */
|
|
307
327
|
const values = node => () => {
|
|
308
328
|
switch (node.length) {
|
|
309
329
|
case 1: case 2: { return node }
|
|
@@ -326,6 +346,91 @@ const values = node => () => {
|
|
|
326
346
|
}
|
|
327
347
|
}
|
|
328
348
|
|
|
349
|
+
/**
|
|
350
|
+
* @template T
|
|
351
|
+
* @typedef {readonly[Node<T>]} Branch1
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @template T
|
|
356
|
+
* @typedef { Branch1<T> | Branch3<T> } ConcatResult
|
|
357
|
+
*/
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @template T
|
|
361
|
+
* @typedef {readonly[...Branch7<T>,T,Node<T>]} Branch9
|
|
362
|
+
*/
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @template T
|
|
366
|
+
* @typedef {readonly[...Branch9<T>,T,Node<T>]} Branch11
|
|
367
|
+
*/
|
|
368
|
+
|
|
369
|
+
/** @type {<T>(n: Branch5<T> | Branch7<T> | Branch9<T> | Branch11<T>) => Branch1<T> | Branch3<T>} */
|
|
370
|
+
const up = n => {
|
|
371
|
+
switch (n.length) {
|
|
372
|
+
case 5: { return [n] }
|
|
373
|
+
case 7: {
|
|
374
|
+
const [n0, v1, n2, v3, n4, v5, n6] = n
|
|
375
|
+
return [[n0, v1, n2], v3, [n4, v5, n6]]
|
|
376
|
+
}
|
|
377
|
+
case 9: {
|
|
378
|
+
const [n0, v1, n2, v3, n4, v5, n6, v7, n8] = n
|
|
379
|
+
return [[n0, v1, n2], v3, [n4, v5, n6, v7, n8]]
|
|
380
|
+
}
|
|
381
|
+
case 11: {
|
|
382
|
+
const [n0, v1, n2, v3, n4, v5, n6, v7, n8, v9, n10] = n
|
|
383
|
+
return [[n0, v1, n2, v3, n4], v5, [n6, v7, n8, v9, n10]]
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @template T
|
|
390
|
+
* @typedef {readonly[Node<T>,T]} Head2
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* @template T
|
|
395
|
+
* @typedef {readonly[...Head2<T>, ...Head2<T>]} Head4
|
|
396
|
+
*/
|
|
397
|
+
|
|
398
|
+
/** @type {<T>(n: Branch3<T> | Branch5<T>) => readonly[Head2<T>|Head4<T>, Node<T>]} */
|
|
399
|
+
const bracnhSplit = n => {
|
|
400
|
+
if (n.length === 3) {
|
|
401
|
+
const [n0, v1, n2] = n
|
|
402
|
+
return [[n0, v1], n2]
|
|
403
|
+
} else {
|
|
404
|
+
const [n0, v1, n2, v3, n4] = n
|
|
405
|
+
return [[n0, v1, n2, v3], n4]
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** @type {<T>(a: Node<T>) => (b: Node<T>) => ConcatResult<T>} */
|
|
410
|
+
const concat = a => b => {
|
|
411
|
+
/** @typedef {typeof a extends Node<infer T> ? T : never} T */
|
|
412
|
+
switch (a.length) {
|
|
413
|
+
case 1: {
|
|
414
|
+
switch (b.length) {
|
|
415
|
+
case 1: { return [[a[0], b[0]]] }
|
|
416
|
+
case 2: { return [a, b[0], [b[1]]] }
|
|
417
|
+
default: { throw 'invalid b node' }
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
case 2: { return [[a[0]], a[1], b] }
|
|
421
|
+
default: {
|
|
422
|
+
switch (b.length) {
|
|
423
|
+
case 3: case 5: {
|
|
424
|
+
const [aHead, aLast] = bracnhSplit(a)
|
|
425
|
+
const [bn0, ...b1] = b
|
|
426
|
+
return up([...aHead, ...concat(aLast)(bn0), ...b1])
|
|
427
|
+
}
|
|
428
|
+
default: { throw 'invalid b node' }
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
329
434
|
module.exports = {
|
|
330
435
|
/** @readonly */
|
|
331
436
|
values,
|
|
@@ -334,14 +439,16 @@ module.exports = {
|
|
|
334
439
|
* @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
|
|
335
440
|
*/
|
|
336
441
|
getVisitor: cmp => node => {
|
|
337
|
-
const result = visit(getVisitor)(cmp)(() => { throw 'getVisitor' })
|
|
338
|
-
if (result[0]
|
|
339
|
-
return
|
|
442
|
+
const result = visit(getVisitor)(cmp)(node)(() => { throw 'getVisitor' })
|
|
443
|
+
if (result[0] !== 'done') { throw 'getVisitor result' }
|
|
444
|
+
return result[1]
|
|
340
445
|
},
|
|
341
446
|
/** @readonly */
|
|
342
447
|
setVisitor: visit(setVisitor),
|
|
343
448
|
/** @readonly */
|
|
344
449
|
getOrInsertVisitor: visit(getOrInsertVisitor),
|
|
345
450
|
/** @readonly */
|
|
346
|
-
replaceVisitor: visit(replaceVisitor)
|
|
451
|
+
replaceVisitor: visit(replaceVisitor),
|
|
452
|
+
/** @readonly */
|
|
453
|
+
concat,
|
|
347
454
|
}
|
package/types/btree/test.js
CHANGED
|
@@ -1,17 +1,92 @@
|
|
|
1
1
|
const btree = require('.')
|
|
2
|
-
const { setVisitor, values } = btree
|
|
3
|
-
const
|
|
2
|
+
const { getVisitor, setVisitor, values, concat } = btree
|
|
3
|
+
const json = require('../../json')
|
|
4
|
+
const { sort } = require('../object')
|
|
5
|
+
const { stringCmp } = require('../function/compare')
|
|
4
6
|
const list = require('../list')
|
|
5
7
|
|
|
8
|
+
/** @type {(sequence: list.List<json.Unknown>) => string} */
|
|
9
|
+
const stringify = sequence => json.stringify(sort)(list.toArray(sequence))
|
|
10
|
+
|
|
6
11
|
/** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
|
|
7
12
|
const set = node => value => {
|
|
8
|
-
const result = setVisitor(
|
|
13
|
+
const result = setVisitor(stringCmp(value))(node)(() => value)
|
|
9
14
|
switch (result[0]) {
|
|
10
15
|
case 'replace': case 'overflow': { return result[1] }
|
|
11
16
|
default: { return node }
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
19
|
|
|
20
|
+
{
|
|
21
|
+
/** @type {btree.Node<string>} */
|
|
22
|
+
let _map = ['a']
|
|
23
|
+
_map = set(_map)('b')
|
|
24
|
+
_map = set(_map)('c')
|
|
25
|
+
_map = set(_map)('d')
|
|
26
|
+
_map = set(_map)('e')
|
|
27
|
+
_map = set(_map)('f')
|
|
28
|
+
let result = stringify(values(_map))
|
|
29
|
+
if (result !== '["a","b","c","d","e","f"]') { throw result }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
/** @type {btree.Node<string>} */
|
|
34
|
+
let _map = ['1']
|
|
35
|
+
for(let i = 2; i <= 10; i++)
|
|
36
|
+
_map = set(_map)((i*i).toString())
|
|
37
|
+
let result = stringify(values(_map))
|
|
38
|
+
if (result !== '["1","100","16","25","36","4","49","64","81","9"]') { throw result }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
{
|
|
42
|
+
/** @type {btree.Node<string>} */
|
|
43
|
+
let _map = ['a']
|
|
44
|
+
_map = set(_map)('b')
|
|
45
|
+
_map = set(_map)('c')
|
|
46
|
+
const result = getVisitor(stringCmp('b'))(_map)
|
|
47
|
+
if (result === undefined) { throw result }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
/** @type {btree.Node<string>} */
|
|
52
|
+
let _map = ['a']
|
|
53
|
+
_map = set(_map)('b')
|
|
54
|
+
_map = set(_map)('c')
|
|
55
|
+
const result = getVisitor(stringCmp('e'))(_map)
|
|
56
|
+
if (result !== undefined) { throw result }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
/** @type {btree.Node<string>} */
|
|
61
|
+
let _map = ['1']
|
|
62
|
+
for (let i = 2; i <= 10; i++)
|
|
63
|
+
_map = set(_map)((i * i).toString())
|
|
64
|
+
if (_map.length !== 3) { throw _map }
|
|
65
|
+
// console.log(_map)
|
|
66
|
+
let [a,,b] = _map
|
|
67
|
+
let _c = concat(a)(b)
|
|
68
|
+
// console.log(_c)
|
|
69
|
+
if (_c.length !== 3) { throw _c }
|
|
70
|
+
[a,,b] = _c
|
|
71
|
+
_c = concat(a)(b)
|
|
72
|
+
// console.log(_c)
|
|
73
|
+
if (_c.length !== 1) { throw _c }
|
|
74
|
+
let [_r] = _c
|
|
75
|
+
if (_r.length !== 5) { throw _r }
|
|
76
|
+
[a,,b] = _r
|
|
77
|
+
_c = concat(a)(b)
|
|
78
|
+
// console.log(_c)
|
|
79
|
+
if (_c.length !== 3) { throw _c }
|
|
80
|
+
[a,,b] = _c
|
|
81
|
+
_c = concat(a)(b)
|
|
82
|
+
// console.log(_c)
|
|
83
|
+
if (_c.length !== 3) { throw _c }
|
|
84
|
+
[a,,b] = _c
|
|
85
|
+
_c = concat(a)(b)
|
|
86
|
+
// console.log(_c)
|
|
87
|
+
if (_c.length !== 1) { throw _c }
|
|
88
|
+
}
|
|
89
|
+
|
|
15
90
|
const test = () => {
|
|
16
91
|
/** @type {btree.Node<string>} */
|
|
17
92
|
let _map = ['a']
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @template T
|
|
6
|
-
* @typedef {import('../../array').Array2<T>} Array2
|
|
6
|
+
* @typedef {import('../../array').Array2<T>} Array2
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @typedef {-1|0|1} Sign */
|
|
@@ -22,8 +22,14 @@ const index5 = cmp => ([v0, v1]) => {
|
|
|
22
22
|
return /** @type {Index5} */ (_0 <= 0 ? _0 + 1 : cmp(v1) + 3)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/** @type {<T>(a: T) => (b: T) => Sign} */
|
|
26
|
+
const unsafeCmp = a => b => a < b ? -1 : a === b ? 0 : 1
|
|
27
|
+
|
|
25
28
|
/** @type {(a: string) => (b: string) => Sign} */
|
|
26
|
-
const
|
|
29
|
+
const stringCmp = unsafeCmp
|
|
30
|
+
|
|
31
|
+
/** @type {(a: number) => (b: number) => Sign} */
|
|
32
|
+
const numberCmp = unsafeCmp
|
|
27
33
|
|
|
28
34
|
module.exports = {
|
|
29
35
|
/** @readonly */
|
|
@@ -31,5 +37,7 @@ module.exports = {
|
|
|
31
37
|
/** @readonly */
|
|
32
38
|
index5,
|
|
33
39
|
/** @readonly */
|
|
34
|
-
|
|
40
|
+
stringCmp,
|
|
41
|
+
/** @readonly */
|
|
42
|
+
numberCmp,
|
|
35
43
|
}
|
package/types/map/index.js
CHANGED
|
@@ -2,7 +2,7 @@ const option = require("../option")
|
|
|
2
2
|
const btree = require('../btree')
|
|
3
3
|
const { getVisitor, setVisitor, values } = require("../btree")
|
|
4
4
|
const compare = require("../function/compare")
|
|
5
|
-
const {
|
|
5
|
+
const { stringCmp } = require("../function/compare")
|
|
6
6
|
const list = require("../list")
|
|
7
7
|
|
|
8
8
|
/** @typedef {compare.Sign} Sign */
|
|
@@ -33,7 +33,7 @@ const list = require("../list")
|
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
/** @type {(a: string) => <T>(b: Entry<T>) => Sign} */
|
|
36
|
-
const keyCmp = a => ([b]) =>
|
|
36
|
+
const keyCmp = a => ([b]) => stringCmp(a)(b)
|
|
37
37
|
|
|
38
38
|
/** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
|
|
39
39
|
const at = name => map => {
|
|
@@ -47,7 +47,7 @@ const set = name => value => map => {
|
|
|
47
47
|
/** @type {Entry<typeof value>} */
|
|
48
48
|
const entry = [name, value]
|
|
49
49
|
if (map === undefined) { return [entry] }
|
|
50
|
-
const result = setVisitor(keyCmp(name))(() => entry)
|
|
50
|
+
const result = setVisitor(keyCmp(name))(map)(() => entry)
|
|
51
51
|
switch (result[0]) {
|
|
52
52
|
case 'replace': case 'overflow': { return result[1] }
|
|
53
53
|
default: { throw 'invalid BTree operation' }
|