mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-15 01:52:42 +03:00
interface: first pass at writing BigIntArrOrderedMap for flatGraphs
This commit is contained in:
parent
8291daf256
commit
dbb58bd00d
@ -347,12 +347,18 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
this.store.handleEvent({ data });
|
||||
}
|
||||
|
||||
async getDeepNodesUpTo(ship: string, resource: string, startTime = null, count: number) {
|
||||
async getDeepNewest(ship: string, resource: string, startTime = null, count: number) {
|
||||
const start = startTime ? decToUd(startTime) : null;
|
||||
const data = await this.scry<any>('graph-store',
|
||||
`/deep-nodes-up-to/${ship}/${resource}/${count}/${start}`
|
||||
);
|
||||
this.store.handleEvent({ data });
|
||||
const node = data['graph-update'];
|
||||
this.store.handleEvent({
|
||||
data: {
|
||||
'graph-update-flat': node,
|
||||
'graph-update': node
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getGraphSubset(ship: string, resource: string, start: string, end: string) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { GraphNode } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import BigIntArrayOrderedMap from '@urbit/api/lib/BigIntArrayOrderedMap';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import produce from 'immer';
|
||||
import _ from 'lodash';
|
||||
@ -22,6 +23,12 @@ export const GraphReducer = (json) => {
|
||||
if(loose) {
|
||||
reduceState<GraphState, any>(useGraphState, loose, [addNodesLoose]);
|
||||
}
|
||||
|
||||
const flat = _.get(json, 'graph-update-flat', false);
|
||||
if (flat) {
|
||||
reduceState<GraphState, any>(useGraphState, loose, [addNodesFlat]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const addNodesLoose = (json: any, state: GraphState): GraphState => {
|
||||
@ -39,6 +46,45 @@ const addNodesLoose = (json: any, state: GraphState): GraphState => {
|
||||
return state;
|
||||
};
|
||||
|
||||
const addNodesFlat = (json: any, state: GraphState): GraphState => {
|
||||
const data = _.get(json, 'add-nodes', false);
|
||||
if (data) {
|
||||
if (!('flatGraphs' in state)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const resource = data.resource.ship + '/' + data.resource.name;
|
||||
if (!(resource in state.flatGraphs)) {
|
||||
state.flatGraphs[resource] = new BigIntArrayOrderedMap();
|
||||
}
|
||||
const indices = Array.from(Object.keys(data.nodes));
|
||||
|
||||
indices.forEach((index) => {
|
||||
const node = data.nodes[index];
|
||||
if (index.split('/').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const indexArr = index.split('/').slice(1).map((ind) => {
|
||||
return bigInt(ind);
|
||||
});
|
||||
|
||||
if (indexArr.length === 0) {
|
||||
return state;
|
||||
}
|
||||
|
||||
state.flatGraphs[resource] =
|
||||
state.flatGraphs[resource].set(
|
||||
indexArr,
|
||||
produce(node, (draft) => {
|
||||
draft.children = mapifyChildren({});
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
const keys = (json, state: GraphState): GraphState => {
|
||||
const data = _.get(json, 'keys', false);
|
||||
if (data) {
|
||||
|
@ -2,6 +2,7 @@ import { Association, deSig, GraphNode, Graphs, resourceFromPath } from '@urbit/
|
||||
import { useCallback } from 'react';
|
||||
import { BaseState, createState } from './base';
|
||||
|
||||
|
||||
export interface GraphState extends BaseState<GraphState> {
|
||||
graphs: Graphs;
|
||||
graphKeys: Set<string>;
|
||||
@ -10,6 +11,7 @@ export interface GraphState extends BaseState<GraphState> {
|
||||
[index: string]: GraphNode;
|
||||
}
|
||||
};
|
||||
flatGraphs: FlatGraphs;
|
||||
pendingIndices: Record<string, any>;
|
||||
graphTimesentMap: Record<string, any>;
|
||||
// getKeys: () => Promise<void>;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Patp } from "..";
|
||||
import BigIntOrderedMap from "../lib/BigIntOrderedMap";
|
||||
import BigIntArrayOrderedMap from "../lib/BigIntArrayOrderedMap";
|
||||
|
||||
|
||||
export interface TextContent {
|
||||
text: string;
|
||||
@ -64,6 +66,15 @@ export interface GraphNode {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
export interface FlatGraphNode {
|
||||
children: null;
|
||||
post: Post;
|
||||
}
|
||||
|
||||
export type Graph = BigIntOrderedMap<GraphNode>;
|
||||
|
||||
export type Graphs = { [rid: string]: Graph };
|
||||
|
||||
export type FlatGraph = BigIntArrayOrderedMap<FlatGraphNode>;
|
||||
|
||||
export type FlatGraphs = { [rid: string]: FlatGraph };
|
||||
|
148
pkg/npm/api/lib/BigIntArrayOrderedMap.ts
Normal file
148
pkg/npm/api/lib/BigIntArrayOrderedMap.ts
Normal file
@ -0,0 +1,148 @@
|
||||
import produce, { immerable, castImmutable, castDraft, setAutoFreeze, enablePatches } from 'immer';
|
||||
import bigInt, { BigInteger } from "big-integer";
|
||||
|
||||
setAutoFreeze(false);
|
||||
|
||||
enablePatches();
|
||||
|
||||
function sortBigInt(a: BigInteger[], b: BigInteger[]) {
|
||||
if (a.lt(b)) {
|
||||
return 1;
|
||||
} else if (a.eq(b)) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function stringToBigIntArr(str: string) {
|
||||
return str.split('/').slice(1).map((ind) => {
|
||||
return bigInt(ind);
|
||||
});
|
||||
}
|
||||
|
||||
function arrToString(arr: BigInteger[]) {
|
||||
let string = '';
|
||||
arr.forEach((key) => {
|
||||
string = string + `/${key.toString()}`;
|
||||
});
|
||||
}
|
||||
|
||||
function sortBigIntArr(a: BigInteger[], b: BigInteger[]) {
|
||||
let aLen = a.length;
|
||||
let bLen = b.length;
|
||||
|
||||
let i = 0;
|
||||
while (i < aLen && i < bLen) {
|
||||
if (a[i].lt(b[i])) {
|
||||
return 1;
|
||||
} else if (a[i].gt(b[i])) {
|
||||
return -1;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return aLen - bLen;
|
||||
}
|
||||
|
||||
|
||||
export default class BigIntArrayOrderedMap<V> implements Iterable<[BigInteger[], V]> {
|
||||
root: Record<string, V> = {}
|
||||
cachedIter: [BigInteger[], V][] = null;
|
||||
[immerable] = true;
|
||||
|
||||
constructor(items: [BigInteger[], V][] = []) {
|
||||
items.forEach(([key, val]) => {
|
||||
this.set(key, val);
|
||||
});
|
||||
}
|
||||
|
||||
get size() {
|
||||
return Object.keys(this.root).length;
|
||||
}
|
||||
|
||||
|
||||
get(key: BigInteger[]) {
|
||||
return this.root[arrToString(key)] ?? null;
|
||||
}
|
||||
|
||||
gas(items: [BigInteger[], V][]) {
|
||||
return produce(this, draft => {
|
||||
items.forEach(([key, value]) => {
|
||||
draft.root[arrToString(key)] = castDraft(value);
|
||||
});
|
||||
draft.generateCachedIter();
|
||||
},
|
||||
(patches) => {
|
||||
//console.log(`gassed with ${JSON.stringify(patches, null, 2)}`);
|
||||
});
|
||||
}
|
||||
|
||||
set(key: BigInteger[], value: V) {
|
||||
return produce(this, draft => {
|
||||
draft.root[key.toString()] = castDraft(value);
|
||||
draft.cachedIter = null;
|
||||
});
|
||||
}
|
||||
|
||||
clear() {
|
||||
return produce(this, draft => {
|
||||
draft.cachedIter = [];
|
||||
draft.root = {}
|
||||
});
|
||||
}
|
||||
|
||||
has(key: BigInteger[]) {
|
||||
return arrToString(key) in this.root;
|
||||
}
|
||||
|
||||
delete(key: BigInteger[]) {
|
||||
const result = produce(this, draft => {
|
||||
delete draft.root[arrToString(key)];
|
||||
draft.cachedIter = null;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[BigInteger[], V]> {
|
||||
let idx = 0;
|
||||
let result = this.generateCachedIter();
|
||||
return {
|
||||
[Symbol.iterator]: this[Symbol.iterator],
|
||||
next: (): IteratorResult<[BigInteger[], V]> => {
|
||||
if (idx < result.length) {
|
||||
return { value: result[idx++], done: false };
|
||||
}
|
||||
return { done: true, value: null };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
peekLargest() {
|
||||
const sorted = Array.from(this);
|
||||
return sorted[0] as [BigInteger[], V] | null;
|
||||
}
|
||||
|
||||
peekSmallest() {
|
||||
const sorted = Array.from(this);
|
||||
return sorted[sorted.length - 1] as [BigInteger[], V] | null;
|
||||
}
|
||||
|
||||
keys() {
|
||||
return Array.from(this).map(([k,v]) => k);
|
||||
}
|
||||
|
||||
generateCachedIter() {
|
||||
if(this.cachedIter) {
|
||||
return [...this.cachedIter];
|
||||
}
|
||||
const result = Object.keys(this.root).map(key => {
|
||||
const num = stringtoBigIntArr(key);
|
||||
return [num, this.root[key]] as [BigInteger[], V];
|
||||
}).sort(([a], [b]) => sortBigIntArr(a,b));
|
||||
this.cachedIter = result;
|
||||
return [...result];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user