// File: wenleix[P]EdgePPR/src/ParamGraph.cpp
// Function: ParamGraph::ReadTextFile(_IO_FILE*)
ParamGraph* ParamGraph::ReadTextFile(FILE* txtFile) {
	const int MaxLineLen = 10000;
	char lineBuf[MaxLineLen];

    timeval start, end;
    gettimeofday(&start, NULL);

    ParamGraph *g = new ParamGraph();
	int numRead;
    numRead = fscanf(txtFile, "%d%d", &g->numVertex, &g->numEdge);
    assert(numRead == 2);

    fprintf(stdout, "INFO: # Vertex: %d, # Edge: %d\n", g->numVertex, g->numEdge);

    g->vertexList = new ParamVertex[g->numVertex];
	for (int i = 0; i < g->numVertex; i++)
		g->vertexList[i].inDeg = 0;
	g->edgeList = new ParamEdge[g->numEdge];

    int currentOffset = 0;
    for (int i = 0; i < g->numVertex; i++) {
        int vtxID, vtxType, outDeg;
        numRead = fscanf(txtFile, "%d%d%d ", &vtxID, &vtxType, &outDeg);
        assert(numRead == 3);
        assert(vtxID == i);
        assert(currentOffset + outDeg <= g->numEdge);

        char* fgetsRet = fgets(lineBuf, MaxLineLen, txtFile);
        assert(fgetsRet != NULL);
        lineBuf[strlen(lineBuf) - 1] = 0;   //  Delete the last '\n'
        g->vertexList[i].vertexID = i;
        g->vertexList[i].outDeg = outDeg;
        g->vertexList[i].SetVType(vtxType);
        g->vertexList[i].name = string(lineBuf);
        for (int j = 0; j < ParamGraph_NumEdgeTypes; j++)
        	g->vertexList[i].outEdgeTypeCount[j] = 0;

        ParamEdge *edgeStart = g->edgeList + currentOffset;
        for (int j = 0; j < outDeg; j++) {
        	int dstID, edgeType;
        	numRead = fscanf(txtFile, "%d%d", &dstID, &edgeType);
            assert(numRead == 2);
            edgeStart[j].dstId = dstID;
            edgeStart[j].SetEType(edgeType);
            g->vertexList[i].outEdgeTypeCount[edgeType]++;	//	Update the edge type count
        }

        //  Check self-loop and update inDeg
        for (int j = 0; j < outDeg; j++) {
			int dstID = edgeStart[j].dstId;
			if (i == dstID) {
				fprintf(stderr, "Self-loop: %d.\n", i);
			}
            assert(i != dstID);
            g->vertexList[dstID].inDeg++;
		}

        g->vertexList[i].outEdge = edgeStart;
        currentOffset += outDeg;
    }

    assert(currentOffset == g->numEdge);

    gettimeofday(&end, NULL);

    double elapse_ms = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0;
    fprintf(stdout, "INFO: Graph load done, time elapsed: %.2f sec.\n", elapse_ms / 1000.0);
	fflush(stdout);

	return g;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2810, %rsp           # imm = 0x2810
movq %rdi, -0x8(%rbp)
movl $0x2710, -0xc(%rbp)     # imm = 0x2710
xorl %eax, %eax
movl %eax, %esi
leaq -0x2730(%rbp), %rdi
callq 0x22d0
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x27d0(%rbp)
callq 0x4360
jmp 0x3a54
movq -0x27d0(%rbp), %rax
movq %rax, -0x2748(%rbp)
movq -0x8(%rbp), %rdi
movq -0x2748(%rbp), %rdx
movq -0x2748(%rbp), %rcx
addq $0x4, %rcx
leaq 0x4814(%rip), %rsi      # 0x8293
movb $0x0, %al
callq 0x2350
movl %eax, -0x2758(%rbp)
cmpl $0x2, -0x2758(%rbp)
jne 0x3a97
jmp 0x3ade
leaq 0x47fa(%rip), %rdi      # 0x8298
leaq 0x4769(%rip), %rsi      # 0x820e
movl $0x32, %edx
leaq 0x47f4(%rip), %rcx      # 0x82a5
callq 0x20f0
movq -0x27d0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2750(%rbp)
movl %eax, -0x2754(%rbp)
movl $0x18, %esi
callq 0x21a0
jmp 0x41dd
movq 0x84e3(%rip), %rax      # 0xbfc8
movq (%rax), %rdi
movq -0x2748(%rbp), %rax
movl (%rax), %edx
movq -0x2748(%rbp), %rax
movl 0x4(%rax), %ecx
leaq 0x47d7(%rip), %rsi      # 0x82d9
movb $0x0, %al
callq 0x2280
movq -0x2748(%rbp), %rax
movslq (%rax), %rax
movq %rax, -0x27e0(%rbp)
movl $0x60, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, %rcx
movq -0x27e0(%rbp), %rax
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, -0x27d8(%rbp)
cmpq $0x0, %rax
je 0x3bb9
movq -0x27d8(%rbp), %rax
movq -0x27e0(%rbp), %rcx
imulq $0x60, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x27f0(%rbp)
movq %rax, -0x27e8(%rbp)
movq -0x27e8(%rbp), %rdi
movq %rdi, -0x27f8(%rbp)
callq 0x4390
movq -0x27f8(%rbp), %rax
movq -0x27f0(%rbp), %rcx
addq $0x60, %rax
cmpq %rcx, %rax
movq %rax, -0x27e8(%rbp)
jne 0x3b88
movq -0x27d8(%rbp), %rcx
movq -0x2748(%rbp), %rax
movq %rcx, 0x8(%rax)
movl $0x0, -0x275c(%rbp)
movl -0x275c(%rbp), %eax
movq -0x2748(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x3c17
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x275c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x2c(%rax)
movl -0x275c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x275c(%rbp)
jmp 0x3bd5
movq -0x2748(%rbp), %rax
movslq 0x4(%rax), %rax
movl $0x10, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, %rcx
movq -0x2748(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x0, -0x2760(%rbp)
movl $0x0, -0x2764(%rbp)
movl -0x2764(%rbp), %eax
movq -0x2748(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x4105
movq -0x8(%rbp), %rdi
leaq 0x4674(%rip), %rsi      # 0x82f9
leaq -0x2768(%rbp), %rdx
leaq -0x276c(%rbp), %rcx
leaq -0x2770(%rbp), %r8
movb $0x0, %al
callq 0x2350
movl %eax, -0x2758(%rbp)
cmpl $0x3, -0x2758(%rbp)
jne 0x3cb2
jmp 0x3cd1
leaq 0x4648(%rip), %rdi      # 0x8301
leaq 0x454e(%rip), %rsi      # 0x820e
movl $0x3f, %edx
leaq 0x45d9(%rip), %rcx      # 0x82a5
callq 0x20f0
movl -0x2768(%rbp), %eax
cmpl -0x2764(%rbp), %eax
jne 0x3ce1
jmp 0x3d00
leaq 0x4626(%rip), %rdi      # 0x830e
leaq 0x451f(%rip), %rsi      # 0x820e
movl $0x40, %edx
leaq 0x45aa(%rip), %rcx      # 0x82a5
callq 0x20f0
movl -0x2760(%rbp), %eax
addl -0x2770(%rbp), %eax
movq -0x2748(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jg 0x3d1a
jmp 0x3d39
leaq 0x45f8(%rip), %rdi      # 0x8319
leaq 0x44e6(%rip), %rsi      # 0x820e
movl $0x41, %edx
leaq 0x4571(%rip), %rcx      # 0x82a5
callq 0x20f0
leaq -0x2720(%rbp), %rdi
movq -0x8(%rbp), %rdx
movl $0x2710, %esi           # imm = 0x2710
callq 0x22c0
movq %rax, -0x2778(%rbp)
cmpq $0x0, -0x2778(%rbp)
je 0x3d61
jmp 0x3d80
leaq 0x45d6(%rip), %rdi      # 0x833e
leaq 0x449f(%rip), %rsi      # 0x820e
movl $0x44, %edx
leaq 0x452a(%rip), %rcx      # 0x82a5
callq 0x20f0
leaq -0x2720(%rbp), %rdi
movq %rdi, -0x2808(%rbp)
callq 0x20b0
movq -0x2808(%rbp), %rcx
movb $0x0, -0x1(%rax,%rcx)
movslq -0x2764(%rbp), %rcx
movl %ecx, %edx
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
leaq (%rcx,%rcx,2), %rcx
shlq $0x5, %rcx
movl %edx, (%rax,%rcx)
movl -0x2770(%rbp), %edx
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x2764(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x5, %rcx
movl %edx, 0x30(%rax,%rcx)
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rdi
movslq -0x2764(%rbp), %rax
leaq (%rax,%rax,2), %rax
shlq $0x5, %rax
addq %rax, %rdi
movl -0x276c(%rbp), %esi
callq 0x3930
leaq -0x2799(%rbp), %rdi
movq %rdi, -0x2800(%rbp)
callq 0x2320
movq -0x2808(%rbp), %rsi
movq -0x2800(%rbp), %rdx
leaq -0x2798(%rbp), %rdi
callq 0x43b0
jmp 0x3e39
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rdi
movslq -0x2764(%rbp), %rax
imulq $0x60, %rax, %rax
addq %rax, %rdi
addq $0x8, %rdi
leaq -0x2798(%rbp), %rsi
callq 0x2230
leaq -0x2798(%rbp), %rdi
callq 0x20e0
leaq -0x2799(%rbp), %rdi
callq 0x21d0
movl $0x0, -0x27a0(%rbp)
cmpl $0x7, -0x27a0(%rbp)
jge 0x3ee9
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x2764(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movslq -0x27a0(%rbp), %rcx
movl $0x0, 0x40(%rax,%rcx,4)
movl -0x27a0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27a0(%rbp)
jmp 0x3e84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2750(%rbp)
movl %eax, -0x2754(%rbp)
leaq -0x2799(%rbp), %rdi
callq 0x21d0
jmp 0x41dd
movq -0x2748(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x2760(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x27a8(%rbp)
movl $0x0, -0x27ac(%rbp)
movl -0x27ac(%rbp), %eax
cmpl -0x2770(%rbp), %eax
jge 0x3ff1
movq -0x8(%rbp), %rdi
leaq 0x4363(%rip), %rsi      # 0x8293
leaq -0x27b0(%rbp), %rdx
leaq -0x27b4(%rbp), %rcx
movb $0x0, %al
callq 0x2350
movl %eax, -0x2758(%rbp)
cmpl $0x2, -0x2758(%rbp)
jne 0x3f56
jmp 0x3f75
leaq 0x433b(%rip), %rdi      # 0x8298
leaq 0x42aa(%rip), %rsi      # 0x820e
movl $0x51, %edx
leaq 0x4335(%rip), %rcx      # 0x82a5
callq 0x20f0
movl -0x27b0(%rbp), %ecx
movq -0x27a8(%rbp), %rax
movslq -0x27ac(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movq -0x27a8(%rbp), %rdi
movslq -0x27ac(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rdi
movl -0x27b4(%rbp), %esi
callq 0x39a0
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x2764(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movslq -0x27b4(%rbp), %rcx
movl 0x40(%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, 0x40(%rax,%rcx,4)
movl -0x27ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27ac(%rbp)
jmp 0x3f13
movl $0x0, -0x27b8(%rbp)
movl -0x27b8(%rbp), %eax
cmpl -0x2770(%rbp), %eax
jge 0x40bb
movq -0x27a8(%rbp), %rax
movslq -0x27b8(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, -0x27bc(%rbp)
movl -0x2764(%rbp), %eax
cmpl -0x27bc(%rbp), %eax
jne 0x4056
movq 0x7fa1(%rip), %rax      # 0xbfe0
movq (%rax), %rdi
movl -0x2764(%rbp), %edx
leaq 0x4300(%rip), %rsi      # 0x834f
movb $0x0, %al
callq 0x2280
movl -0x2764(%rbp), %eax
cmpl -0x27bc(%rbp), %eax
je 0x4066
jmp 0x4085
leaq 0x42f2(%rip), %rdi      # 0x835f
leaq 0x419a(%rip), %rsi      # 0x820e
movl $0x5d, %edx
leaq 0x4225(%rip), %rcx      # 0x82a5
callq 0x20f0
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x27bc(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rax)
movl -0x27b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27b8(%rbp)
jmp 0x3ffb
movq -0x27a8(%rbp), %rcx
movq -0x2748(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x2764(%rbp), %rdx
imulq $0x60, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x38(%rax)
movl -0x2770(%rbp), %eax
addl -0x2760(%rbp), %eax
movl %eax, -0x2760(%rbp)
movl -0x2764(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2764(%rbp)
jmp 0x3c65
movl -0x2760(%rbp), %eax
movq -0x2748(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x4119
jmp 0x4138
leaq 0x424a(%rip), %rdi      # 0x836a
leaq 0x40e7(%rip), %rsi      # 0x820e
movl $0x65, %edx
leaq 0x4172(%rip), %rcx      # 0x82a5
callq 0x20f0
leaq -0x2740(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x22d0
movq -0x2740(%rbp), %rax
subq -0x2730(%rbp), %rax
cvtsi2sd %rax, %xmm0
movq -0x2738(%rbp), %rax
subq -0x2728(%rbp), %rax
cvtsi2sd %rax, %xmm1
movsd 0x405a(%rip), %xmm2     # 0x81d0
divsd %xmm2, %xmm1
movsd 0x404e(%rip), %xmm2     # 0x81d0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x27c8(%rbp)
movq 0x7e2f(%rip), %rax      # 0xbfc8
movq (%rax), %rdi
movsd -0x27c8(%rbp), %xmm0
movsd 0x4024(%rip), %xmm1     # 0x81d0
divsd %xmm1, %xmm0
leaq 0x41cf(%rip), %rsi      # 0x8386
movb $0x1, %al
callq 0x2280
movq 0x7e03(%rip), %rax      # 0xbfc8
movq (%rax), %rdi
callq 0x2210
movq -0x2748(%rbp), %rax
addq $0x2810, %rsp           # imm = 0x2810
popq %rbp
retq
movq -0x2750(%rbp), %rdi
callq 0x2300
nopl (%rax)