Skip to content

Commit

Permalink
save the credgraph
Browse files Browse the repository at this point in the history
  • Loading branch information
teamdandelion committed Feb 17, 2020
1 parent 668eee4 commit e2c6342
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 21 deletions.
1 change: 0 additions & 1 deletion src/analysis/pagerank.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export async function pagerank(
.map((_, i) => (1580603309 - 86400 * 7 * (i + 1)) * 1000);
const fibration = {
what: [NodeAddress.fromParts(["sourcecred", "github", "USERLIKE", "USER"])],
timeBoundaries,
beta: 0.5,
gammaForward: 0.1,
gammaBackward: 0.1,
Expand Down
21 changes: 21 additions & 0 deletions src/backend/computeFunction.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//@flow

import {type WeightedGraph} from "../core/weightedGraph";
import {CredGraph} from "../core/credGraph";
import {TaskReporter} from "../util/taskReporter";
import {type TimelineCredParameters} from "../analysis/timeline/params";
import {type PluginDeclaration} from "../analysis/pluginDeclaration";
import {TimelineCred} from "../analysis/timeline/timelineCred";
import {type Options as CredGraphOptions} from "../core/algorithm/pagerank";

/**
* An abstract handle for TimelineCred.compute-like functions.
Expand All @@ -16,6 +18,14 @@ type ComputeEnv = {
+reporter: TaskReporter,
};

export type CredGraphComputeFunction = (
opts: CredGraphComputeOpts
) => Promise<CredGraph>;
type CredGraphComputeOpts = {|
+weightedGraph: WeightedGraph,
+options: CredGraphOptions,
|};

type ComputeOpts = {|
weightedGraph: WeightedGraph,
params?: $Shape<TimelineCredParameters>,
Expand All @@ -33,3 +43,14 @@ export async function computeTask(
reporter.finish("compute-cred");
return cred;
}

export async function credGraphComputeTask(
compute: CredGraphComputeFunction,
{reporter}: ComputeEnv,
opts: CredGraphComputeOpts
): Promise<CredGraph> {
reporter.start("compute-cred-graph");
const cred = await compute(opts);
reporter.finish("compute-cred-graph");
return cred;
}
5 changes: 4 additions & 1 deletion src/backend/dataDirectory.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class DataDirectory implements CacheProvider, ProjectStorageProvider {

async storeProject(
project: Project,
{weightedGraph, cred, pluginDeclarations}: ProjectStorageExtras
{weightedGraph, cred, pluginDeclarations, credGraph}: ProjectStorageExtras
): Promise<void> {
const projectDirectory = directoryForProjectId(
project.id,
Expand All @@ -55,6 +55,9 @@ export class DataDirectory implements CacheProvider, ProjectStorageProvider {
if (cred) {
writeFile("cred.json", stringify(cred.toJSON()));
}
if (credGraph) {
writeFile("credGraph.json", stringify(credGraph.toJSON()));
}
if (pluginDeclarations) {
writeFile(
"pluginDeclarations.json",
Expand Down
31 changes: 30 additions & 1 deletion src/backend/loadContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import {type Project} from "../core/project";
import {type Weights as WeightsT} from "../core/weights";
import {type WeightedGraph as WeightedGraphT} from "../core/weightedGraph";
import * as WeightedGraph from "../core/weightedGraph";
import {CredGraph} from "../core/credGraph";
import {type TimelineCredParameters} from "../analysis/timeline/params";
import {type GithubToken} from "../plugins/github/token";
import {type CacheProvider} from "./cache";
import {TaskReporter} from "../util/taskReporter";
import {TimelineCred} from "../analysis/timeline/timelineCred";
import {type ComputeFunction as ComputeFunctionT} from "./computeFunction";
import {pagerank as credGraphCompute} from "../core/algorithm/pagerank";
import {
type ComputeFunction as ComputeFunctionT,
type CredGraphComputeFunction as CredGraphComputeFunctionT,
} from "./computeFunction";
import {type PluginLoaders as PluginLoadersT} from "./pluginLoaders";
import * as ComputeFunction from "./computeFunction";
import * as PluginLoaders from "./pluginLoaders";
Expand All @@ -22,6 +27,7 @@ export type LoadResult = {|
+pluginDeclarations: PluginDeclarations,
+weightedGraph: WeightedGraphT,
+cred: TimelineCred,
+credGraph: CredGraph,
|};

export type LoadContextOptions = {|
Expand Down Expand Up @@ -70,6 +76,7 @@ export class LoadContext {
+_contractPluginGraphs = PluginLoaders.contractPluginGraphs;
+_overrideWeights = WeightedGraph.overrideWeights;
+_computeTask = ComputeFunction.computeTask;
+_computeCredGraphTask = ComputeFunction.credGraphComputeTask;

/**
* The above proxy functions we're deferring to, accept interfaces so they
Expand All @@ -79,6 +86,8 @@ export class LoadContext {
*/

+_compute: ComputeFunctionT = TimelineCred.compute;
+_computeCredGraph: CredGraphComputeFunctionT = (opts) =>
credGraphCompute(opts.weightedGraph, opts.options);
+_pluginLoaders: PluginLoadersT = {
github: githubLoader,
discourse: discourseLoader,
Expand Down Expand Up @@ -116,10 +125,30 @@ export class LoadContext {
plugins,
weightedGraph,
});
const userTypes = [].concat(...plugins.map((p) => p.userTypes));
const scoringPrefixes = userTypes.map((x) => x.prefix);
const credGraph = await this._computeCredGraphTask(
this._computeCredGraph,
this._options,
{
weightedGraph,
options: {
fibrationOptions: {
what: scoringPrefixes,
beta: 0.5,
gammaForward: 0.15,
gammaBackward: 0.15,
},
seedOptions: {alpha: 0.1},
pagerankOptions: {},
},
}
);
return {
pluginDeclarations: plugins,
weightedGraph,
cred,
credGraph,
};
}
}
2 changes: 2 additions & 0 deletions src/backend/projectStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import {type WeightedGraph} from "../core/weightedGraph";
import {TimelineCred} from "../analysis/timeline/timelineCred";
import {CredGraph} from "../core/credGraph";
import {type Project} from "../core/project";
import {type PluginDeclarations} from "../analysis/pluginDeclaration";

export type ProjectStorageExtras = {
+weightedGraph?: WeightedGraph,
+cred?: TimelineCred,
+pluginDeclarations?: PluginDeclarations,
+credGraph?: CredGraph,
};

export interface ProjectStorageProvider {
Expand Down
30 changes: 12 additions & 18 deletions src/core/markovProcessGraph.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// @flow

import {max, min} from "d3-array";
import {weekIntervals} from "./interval";
import sortedIndex from "lodash.sortedindex";
import {makeAddressModule, type AddressModule} from "./address";
import {
Expand Down Expand Up @@ -75,7 +78,6 @@ function epochNodeAddressToRaw(addr: EpochNodeAddress) {
// STOPSHIP document these parameters
export type FibrationOptions = {|
+what: $ReadOnlyArray<NodeAddressT>,
+timeBoundaries: $ReadOnlyArray<TimestampMs>,
+beta: TransitionProbability,
+gammaForward: TransitionProbability,
+gammaBackward: TransitionProbability,
Expand Down Expand Up @@ -138,21 +140,13 @@ export class MarkovProcessGraph {
return result;
})();

const timeBoundaries = (() => {
let lastBoundary = -Infinity;
for (const boundary of fibration.timeBoundaries) {
if (!isFinite(boundary)) {
throw new Error(`non-finite boundary: ${String(boundary)}`);
}
if (boundary <= lastBoundary) {
throw new Error(
`non-increasing boundary: ` +
`${String(boundary)} <= ${String(lastBoundary)}`
);
}
}
return [-Infinity, ...fibration.timeBoundaries, Infinity];
})();
const edgeTimestamps = Array.from(
wg.graph.edges({showDangling: false})
).map((x) => x.timestampMs);
const start = min(edgeTimestamps);
const end = max(edgeTimestamps);
const boundaries = weekIntervals(start, end).map((x) => x.startTimeMs);
const timeBoundaries = [-Infinity, ...boundaries, Infinity];

// Build graph
{
Expand Down Expand Up @@ -410,15 +404,15 @@ export class MarkovProcessGraph {

*nodes(options?: {|+prefix: NodeAddressT|}): Iterator<MarkovNode> {
const prefix = options ? options.prefix : NodeAddress.empty;
for (const node of self._nodes.values()) {
for (const node of this._nodes.values()) {
if (NodeAddress.hasPrefix(node.address, prefix)) {
yield node;
}
}
}

*edges(): Iterator<MarkovEdge> {
for (const edge of self._edges.values()) {
for (const edge of this._edges.values()) {
yield edge;
}
}
Expand Down

0 comments on commit e2c6342

Please sign in to comment.