10         PGraph Graph = PGraph::TObj::New();
 
   12   const TAttrType NodeType = Table->GetColType(SrcCol);
 
   13   Assert(NodeType == Table->GetColType(DstCol));
 
   14   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
   15   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
   18   if (NodeType == 
atInt) {
 
   19     for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
   20       if ((Table->Next)[CurrRowIdx] == Table->Invalid) { 
continue; }
 
   22       TInt SVal = (Table->IntCols)[SrcColIdx][CurrRowIdx];
 
   23       TInt DVal = (Table->IntCols)[DstColIdx][CurrRowIdx];
 
   25       Graph->AddNodeUnchecked(SVal);
 
   26       Graph->AddNodeUnchecked(DVal);
 
   27       Graph->AddEdgeUnchecked(SVal, DVal);
 
   29   } 
else if (NodeType == 
atFlt) {
 
   33     for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
   34       if ((Table->Next)[CurrRowIdx] == Table->Invalid) { 
continue; }
 
   37       TFlt FSVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
   38       SVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FSVal);
 
   39       TFlt FDVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
   40       DVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FDVal);
 
   41       Graph->AddEdge(SVal, DVal);
 
   44     for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
   45       if ((Table->Next)[CurrRowIdx] == Table->Invalid) { 
continue; }
 
   47       TInt SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
   49       TInt DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
   52       Graph->AddNodeUnchecked(SVal);
 
   53       Graph->AddNodeUnchecked(DVal);
 
   54       Graph->AddEdgeUnchecked(SVal, DVal);
 
   58   Graph->SortNodeAdjV();
 
   63 template<
class PGraph>
 
   65   const TStr& SrcCol, 
const TStr& DstCol,
 
   69         PGraph Graph = PGraph::TObj::New();
 
   71   const TAttrType NodeType = Table->GetColType(SrcCol);
 
   72   Assert(NodeType == Table->GetColType(DstCol));
 
   73   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
   74   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
   90   for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
   91     if ((Table->Next)[CurrRowIdx] == Table->Invalid) {
 
   97     if (NodeType == 
atFlt) {
 
   98       TFlt FSVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
   99       SVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FSVal);
 
  100       TFlt FDVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
  101       DVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FDVal);
 
  102     } 
else if (NodeType == 
atInt || NodeType == 
atStr) {
 
  103       if (NodeType == 
atInt) {
 
  104         SVal = (Table->IntCols)[SrcColIdx][CurrRowIdx];
 
  105         DVal = (Table->IntCols)[DstColIdx][CurrRowIdx];
 
  107         SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
  108         if (strlen(Table->GetContextKey(SVal)) == 0) { 
continue; }  
 
  109         DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
  110         if (strlen(Table->GetContextKey(DVal)) == 0) { 
continue; }  
 
  112       if (!Graph->IsNode(SVal)) {Graph->AddNode(SVal); }
 
  113       if (!Graph->IsNode(DVal)) {Graph->AddNode(DVal); }
 
  119     Graph->AddEdge(SVal, DVal, CurrRowIdx);
 
  122                 for (
TInt i = 0; i < EdgeAttrV.
Len(); i++) {
 
  123                         TStr ColName = EdgeAttrV[i];
 
  124                         TAttrType T = Table->GetColType(ColName);
 
  125                         TInt Index = Table->GetColIdx(ColName);
 
  128                                         Graph->AddIntAttrDatE(CurrRowIdx, Table->IntCols[Index][CurrRowIdx], ColName);
 
  131                                         Graph->AddFltAttrDatE(CurrRowIdx, Table->FltCols[Index][CurrRowIdx], ColName);
 
  134                                         Graph->AddStrAttrDatE(CurrRowIdx, Table->GetStrValIdx(Index, CurrRowIdx), ColName);
 
  140     if ((Table->SrcNodeAttrV).Len() > 0) {
 
  141       Table->AddNodeAttributes(SVal, Table->SrcNodeAttrV, CurrRowIdx, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
  144     if ((Table->DstNodeAttrV).Len() > 0) {
 
  145       Table->AddNodeAttributes(DVal, Table->DstNodeAttrV, CurrRowIdx, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
  150   if ((Table->SrcNodeAttrV).Len() > 0 || (Table->DstNodeAttrV).Len() > 0) {
 
  151     for (
TNEANet::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) {
 
  152       TInt NId = NodeI.GetId();
 
  153       if (NodeIntAttrs.
IsKey(NId)) {
 
  156           TInt AttrVal = Table->AggregateVector<
TInt>(it.GetDat(), AggrPolicy);
 
  157           Graph->AddIntAttrDatN(NId, AttrVal, it.GetKey());
 
  160       if (NodeFltAttrs.
IsKey(NId)) {
 
  163           TFlt AttrVal = Table->AggregateVector<
TFlt>(it.GetDat(), AggrPolicy);
 
  164           Graph->AddFltAttrDatN(NId, AttrVal, it.GetKey());
 
  167       if (NodeStrAttrs.
IsKey(NId)) {
 
  170           TStr AttrVal = Table->AggregateVector<
TStr>(it.GetDat(), AggrPolicy);
 
  171           Graph->AddStrAttrDatN(NId, AttrVal, it.GetKey());
 
  181 template<
class PGraph>
 
  186   return ToNetwork<PGraph>(Table, SrcCol, DstCol, V, AggrPolicy);
 
  190 template<
class PGraphMP>
 
  194   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
  195   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
  196   const TAttrType NodeType = Table->GetColType(SrcCol);
 
  197   Assert(NodeType == Table->GetColType(DstCol));
 
  199   const TInt NumRows = Table->NumValidRows;
 
  201   TIntV SrcCol1, DstCol1, SrcCol2, DstCol2;
 
  203   #pragma omp parallel sections num_threads(4) 
  206     { SrcCol1.
Reserve(NumRows, NumRows); }
 
  208     { SrcCol2.
Reserve(NumRows, NumRows); }
 
  210     { DstCol1.
Reserve(NumRows, NumRows); }
 
  212     { DstCol2.
Reserve(NumRows, NumRows); }
 
  219   Table->GetPartitionRanges(Partitions, omp_get_max_threads());
 
  220   TInt PartitionSize = Partitions[0].GetVal2()-Partitions[0].GetVal1()+1;
 
  225   omp_set_num_threads(omp_get_max_threads());
 
  226   if (NodeType == 
atInt) {
 
  227     #pragma omp parallel for schedule(static) 
  228     for (
int i = 0; i < Partitions.
Len(); i++) {
 
  231       while (RowI < EndI) {
 
  241   else if (NodeType == 
atStr) {
 
  242     #pragma omp parallel for schedule(static) 
  243     for (
int i = 0; i < Partitions.
Len(); i++) {
 
  246       while (RowI < EndI) {
 
  257   omp_set_num_threads(omp_get_max_threads());
 
  260     #pragma omp single nowait 
  262       #pragma omp task untied shared(SrcCol1, DstCol1) 
  265     #pragma omp single nowait 
  267       #pragma omp task untied shared(SrcCol2, DstCol2) 
  284   TInt NumThreads = omp_get_max_threads();
 
  285   TInt PartSize = (NumRows/NumThreads);
 
  287   TIntV SrcOffsets, DstOffsets;
 
  289   for (
TInt i = 1; i < NumThreads; i++) {
 
  290     TInt CurrOffset = i * PartSize;
 
  291     while (CurrOffset < (i+1) * PartSize &&
 
  292           SrcCol1[CurrOffset-1] == SrcCol1[CurrOffset]) {
 
  295     if (CurrOffset < (i+1) * PartSize) { SrcOffsets.
Add(CurrOffset); }
 
  297   SrcOffsets.
Add(NumRows);
 
  300   for (
TInt i = 1; i < NumThreads; i++) {
 
  301     TInt CurrOffset = i * PartSize;
 
  302     while (CurrOffset < (i+1) * PartSize &&
 
  303           DstCol2[CurrOffset-1] == DstCol2[CurrOffset]) {
 
  306     if (CurrOffset < (i+1) * PartSize) { DstOffsets.
Add(CurrOffset); }
 
  308   DstOffsets.
Add(NumRows);
 
  310   TInt SrcPartCnt = SrcOffsets.
Len()-1;
 
  311   TInt DstPartCnt = DstOffsets.
Len()-1;
 
  322   TIntV SrcNodeCounts, DstNodeCounts;
 
  323   SrcNodeCounts.
Reserve(SrcPartCnt, SrcPartCnt);
 
  324   DstNodeCounts.
Reserve(DstPartCnt, DstPartCnt);
 
  326   #pragma omp parallel for schedule(dynamic) 
  327   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
  328     if (t < SrcPartCnt) {
 
  330       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
  331         SrcNodeCounts[i] = 1;
 
  332         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
  333         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
  334           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
  335           if (j < SrcOffsets[i+1]) {
 
  337             CurrNode = SrcCol1[j];
 
  342       TInt i = t - SrcPartCnt;
 
  343       if (DstOffsets[i] != DstOffsets[i+1]) {
 
  344         DstNodeCounts[i] = 1;
 
  345         TInt CurrNode = DstCol2[DstOffsets[i]];
 
  346         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
  347           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
  348           if (j < DstOffsets[i+1]) {
 
  350             CurrNode = DstCol2[j];
 
  366   TInt TotalSrcNodes = 0;
 
  368   for (
int i = 0; i < SrcPartCnt; i++) {
 
  369     SrcIdOffsets.
Add(TotalSrcNodes);
 
  370     TotalSrcNodes += SrcNodeCounts[i];
 
  373   TInt TotalDstNodes = 0;
 
  375   for (
int i = 0; i < DstPartCnt; i++) {
 
  376     DstIdOffsets.
Add(TotalDstNodes);
 
  377     TotalDstNodes += DstNodeCounts[i];
 
  382   TIntPrV SrcNodeIds, DstNodeIds;
 
  383   #pragma omp parallel sections 
  386     { SrcNodeIds.
Reserve(TotalSrcNodes, TotalSrcNodes); }
 
  388     { DstNodeIds.
Reserve(TotalDstNodes, TotalDstNodes); }
 
  391   #pragma omp parallel for schedule(dynamic) 
  392   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
  393     if (t < SrcPartCnt) {
 
  395       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
  396         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
  397         TInt ThreadOffset = SrcIdOffsets[i];
 
  398         SrcNodeIds[ThreadOffset] = 
TIntPr(CurrNode, SrcOffsets[i]);
 
  400         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
  401           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
  402           if (j < SrcOffsets[i+1]) {
 
  403             CurrNode = SrcCol1[j];
 
  404             SrcNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
  410       TInt i = t - SrcPartCnt;
 
  411       if (DstOffsets[i] != DstOffsets[i+1]) {
 
  412         TInt CurrNode = DstCol2[DstOffsets[i]];
 
  413         TInt ThreadOffset = DstIdOffsets[i];
 
  414         DstNodeIds[ThreadOffset] = 
TIntPr(CurrNode, DstOffsets[i]);
 
  416         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
  417           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
  418           if (j < DstOffsets[i+1]) {
 
  419             CurrNode = DstCol2[j];
 
  420             DstNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
  432   Nodes.
Reserve(TotalSrcNodes+TotalDstNodes);
 
  438   while (i < TotalSrcNodes && j < TotalDstNodes) {
 
  439     if (SrcNodeIds[i].Val1 == DstNodeIds[j].Val1) {
 
  440       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, j));
 
  443     } 
else if (SrcNodeIds[i].Val1 < DstNodeIds[j].Val1) {
 
  444       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1));
 
  447       Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j));
 
  451   for (; i < TotalSrcNodes; i++) { Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1)); }
 
  452   for (; j < TotalDstNodes; j++) { Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j)); }
 
  462   int Delta = (NumNodes+NumThreads-1)/NumThreads;
 
  467   omp_set_num_threads(NumThreads);
 
  468   #pragma omp parallel for schedule(static,Delta) 
  469   for (
int m = 0; m < NumNodes; m++) {
 
  475       TInt Offset = SrcNodeIds[i].GetVal2();
 
  476       TInt Sz = DstCol1.
Len()-Offset;
 
  477       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
  482       TInt Offset = DstNodeIds[j].GetVal2();
 
  483       TInt Sz = SrcCol2.
Len()-Offset;
 
  484       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
  495   NumThreads = omp_get_max_threads();
 
  496   Delta = (NumNodes+NumThreads-1)/(10*NumThreads);
 
  497   omp_set_num_threads(NumThreads);
 
  498   #pragma omp parallel for schedule(dynamic) 
  499   for (
int m = 0; m < NumNodes; m++) {
 
  505       TInt Offset = SrcNodeIds[i].GetVal2();
 
  506       TInt Sz = DstCol1.
Len()-Offset;
 
  507       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
  512       TInt Offset = DstNodeIds[j].GetVal2();
 
  513       TInt Sz = SrcCol2.
Len()-Offset;
 
  514       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
  518     Graph->AddNodeWithEdges(n, InVV[m], OutVV[m]);
 
  522   Graph->SetNodes(NumNodes);
 
  531 template<
class PGraphMP>
 
  534   int MaxThreads = omp_get_max_threads();
 
  535   int Length, Threads, Delta, Nodes, Last;
 
  536   uint64_t NumNodesEst;
 
  537   TInt SrcColIdx, DstColIdx;
 
  540   SrcColIdx = Table->GetColIdx(SrcCol);
 
  541   DstColIdx = Table->GetColIdx(DstCol);
 
  542   const TAttrType NodeType = Table->GetColType(SrcCol);
 
  543   Assert(NodeType == Table->GetColType(DstCol));
 
  547   int NumRows = Table->Next.Len();
 
  549   int sz = NumRows / Load;
 
  550   int *buckets = (
int *)malloc(sz * 
sizeof(
int));
 
  552   #pragma omp parallel for 
  553     for (
int i = 0; i < sz; i++)
 
  556   if (NodeType == 
atInt) {
 
  557     #pragma omp parallel for 
  558       for (
int i = 0; i < NumRows; i++) {
 
  559         int vert = Table->IntCols[DstColIdx][i];
 
  560         buckets[vert % sz] = 1;
 
  563   else if (NodeType == 
atStr ) {
 
  564     #pragma omp parallel for 
  565       for (
int i = 0; i < NumRows; i++) {
 
  566         int vert = (Table->StrColMaps)[DstColIdx][i];
 
  567         buckets[vert % sz] = 1;
 
  571   #pragma omp parallel for reduction(+:cnt) 
  572     for (
int i = 0; i < sz; i++) {
 
  577   NumNodesEst = sz * log ((
double)sz / cnt);
 
  585     Length = Graph->Reserved();
 
  586     Threads = MaxThreads/2;
 
  587     Delta = (Length + Threads - 1) / Threads;
 
  595     omp_set_num_threads(Threads);
 
  596     #pragma omp parallel for schedule(static, Delta) 
  597       for (
int CurrRowIdx = 0; CurrRowIdx < Last; CurrRowIdx++) {
 
  598         if ((uint64_t) Nodes + 1000 >= NumNodesEst) {
 
  604         if (NodeType == 
atInt) {
 
  605           SVal = Table->IntCols[SrcColIdx][CurrRowIdx];
 
  606           DVal = Table->IntCols[DstColIdx][CurrRowIdx];
 
  608         else if (NodeType == 
atStr ) {
 
  609           SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
  610           DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
  613         if (!Graph->AddOutEdge1(SrcIdx, SVal, DVal)) {
 
  619         __sync_fetch_and_add(&OutVec[SrcIdx].Val, 1);
 
  622         if (!Graph->AddInEdge1(DstIdx, SVal, DVal)) {
 
  628         __sync_fetch_and_add(&InVec[DstIdx].Val, 1);
 
  631     if ((uint64_t) Nodes + 1000 >= NumNodesEst) {
 
  643   Graph->SetNodes(Nodes);
 
  646   for (
int i = 0; i < Length; i++) {
 
  647     Edges += OutVec[i] + InVec[i];
 
  650   for (
int Idx = 0; Idx < Length; Idx++) {
 
  651     if (OutVec[Idx] > 0 || InVec[Idx] > 0) {
 
  652       Graph->ReserveNodeDegs(Idx, InVec[Idx], OutVec[Idx]);
 
  657   Length = Graph->Reserved();
 
  658   Threads = MaxThreads;
 
  659   Delta = (Length + Threads - 1) / Threads;
 
  661   omp_set_num_threads(Threads);
 
  662   #pragma omp parallel for schedule(static,Delta) 
  663   for (
int CurrRowIdx = 0; CurrRowIdx < Last; CurrRowIdx++) {
 
  665         if (NodeType == 
atInt) {
 
  666       SVal = Table->IntCols[SrcColIdx][CurrRowIdx];
 
  667       DVal = Table->IntCols[DstColIdx][CurrRowIdx];
 
  669         else if (NodeType == 
atStr) {
 
  670       SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
  671       DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
  674     Graph->AddOutEdge2(SVal, DVal);
 
  675     Graph->AddInEdge2(SVal, DVal);
 
  679   Length = Graph->Reserved();
 
  680   Threads = MaxThreads*2;
 
  681   Delta = (Length + Threads - 1) / Threads;
 
  683   omp_set_num_threads(Threads);
 
  684   #pragma omp parallel for schedule(dynamic) 
  685   for (
int Idx = 0; Idx < Length; Idx++) {
 
  686     if (OutVec[Idx] > 0 || InVec[Idx] > 0) {
 
  687       Graph->SortEdges(Idx, InVec[Idx], OutVec[Idx]);
 
  695 template<
class PGraphMP>
 
  697   const TStr& SrcCol, 
const TStr& DstCol,
 
  703   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
  704   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
  705   const TInt NumRows = Table->GetNumValidRows();
 
  707   const TAttrType NodeType = Table->GetColType(SrcCol);
 
  708   Assert(NodeType == Table->GetColType(DstCol));
 
  711   TIntV SrcCol1, EdgeCol1, EdgeCol2, DstCol2;
 
  717   #pragma omp parallel sections num_threads(4) 
  720     { SrcCol1.Reserve(NumRows, NumRows); }
 
  722     { EdgeCol1.Reserve(NumRows, NumRows); }
 
  724     { DstCol2.Reserve(NumRows, NumRows); }
 
  726     { EdgeCol2.Reserve(NumRows, NumRows); }
 
  732   Table->GetPartitionRanges(Partitions, omp_get_max_threads());
 
  733   TInt PartitionSize = Partitions[0].GetVal2()-Partitions[0].GetVal1()+1;
 
  738   omp_set_num_threads(omp_get_max_threads());
 
  739   if (NodeType == 
atInt) {
 
  740     #pragma omp parallel for schedule(static) 
  741     for (
int i = 0; i < Partitions.
Len(); i++) {
 
  744       while (RowI < EndI) {
 
  747         EdgeCol1[RowId] = RowId;
 
  749         EdgeCol2[RowId] = RowId;
 
  754   else if (NodeType == 
atStr) {
 
  755     #pragma omp parallel for schedule(static) 
  756     for (
int i = 0; i < Partitions.
Len(); i++) {
 
  759       while (RowI < EndI) {
 
  762         EdgeCol1[RowId] = RowId;
 
  764         EdgeCol2[RowId] = RowId;
 
  772   omp_set_num_threads(omp_get_max_threads());
 
  775     #pragma omp single nowait 
  778       #pragma omp task untied shared(SrcCol1, EdgeCol1) 
  782     #pragma omp single nowait 
  785       #pragma omp task untied shared(EdgeCol2, DstCol2) 
  796   TInt NumThreads = omp_get_max_threads();
 
  797   TInt PartSize = (NumRows/NumThreads);
 
  801   TIntV SrcOffsets, DstOffsets;
 
  803   for (
TInt i = 1; i < NumThreads; i++) {
 
  804     TInt CurrOffset = i * PartSize;
 
  805     while (CurrOffset < (i+1) * PartSize &&
 
  806           SrcCol1[CurrOffset-1] == SrcCol1[CurrOffset]) {
 
  810     if (CurrOffset < (i+1) * PartSize) { SrcOffsets.
Add(CurrOffset); }
 
  812   SrcOffsets.
Add(NumRows);
 
  815   for (
TInt i = 1; i < NumThreads; i++) {
 
  816     TInt CurrOffset = i * PartSize;
 
  817     while (CurrOffset < (i+1) * PartSize &&
 
  818           DstCol2[CurrOffset-1] == DstCol2[CurrOffset]) {
 
  822     if (CurrOffset < (i+1) * PartSize) { DstOffsets.
Add(CurrOffset); }
 
  824   DstOffsets.
Add(NumRows);
 
  826   TInt SrcPartCnt = SrcOffsets.
Len()-1; 
 
  827   TInt DstPartCnt = DstOffsets.
Len()-1; 
 
  830   TIntV SrcNodeCounts, DstNodeCounts;
 
  831   SrcNodeCounts.
Reserve(SrcPartCnt, SrcPartCnt);
 
  832   DstNodeCounts.
Reserve(DstPartCnt, DstPartCnt);
 
  834   #pragma omp parallel for schedule(dynamic) 
  835   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
  836     if (t < SrcPartCnt) {
 
  838       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
  839         SrcNodeCounts[i] = 1;
 
  840         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
  841         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
  842           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
  843           if (j < SrcOffsets[i+1]) {
 
  845             CurrNode = SrcCol1[j];
 
  850       TInt i = t - SrcPartCnt;
 
  851       if (DstOffsets[i] != DstOffsets[i+1]) {
 
  852         DstNodeCounts[i] = 1;
 
  853         TInt CurrNode = DstCol2[DstOffsets[i]];
 
  854         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
  855           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
  856           if (j < DstOffsets[i+1]) {
 
  858             CurrNode = DstCol2[j];
 
  865   TInt TotalSrcNodes = 0;
 
  867   for (
int i = 0; i < SrcPartCnt; i++) {
 
  868     SrcIdOffsets.
Add(TotalSrcNodes);
 
  869     TotalSrcNodes += SrcNodeCounts[i];
 
  872   TInt TotalDstNodes = 0;
 
  874   for (
int i = 0; i < DstPartCnt; i++) {
 
  875     DstIdOffsets.
Add(TotalDstNodes);
 
  876     TotalDstNodes += DstNodeCounts[i];
 
  882   TIntPrV SrcNodeIds, DstNodeIds;
 
  883   #pragma omp parallel sections 
  886     { SrcNodeIds.
Reserve(TotalSrcNodes, TotalSrcNodes); }
 
  888     { DstNodeIds.
Reserve(TotalDstNodes, TotalDstNodes); }
 
  892   #pragma omp parallel for schedule(dynamic) 
  893   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
  894     if (t < SrcPartCnt) {
 
  896       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
  897         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
  898         TInt ThreadOffset = SrcIdOffsets[i];
 
  899         SrcNodeIds[ThreadOffset] = 
TIntPr(CurrNode, SrcOffsets[i]);
 
  901         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
  902           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
  903           if (j < SrcOffsets[i+1]) {
 
  904             CurrNode = SrcCol1[j];
 
  905             SrcNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
  911       TInt i = t - SrcPartCnt;
 
  912       if (DstOffsets[i] != DstOffsets[i+1]) {
 
  913         TInt CurrNode = DstCol2[DstOffsets[i]];
 
  914         TInt ThreadOffset = DstIdOffsets[i];
 
  915         DstNodeIds[ThreadOffset] = 
TIntPr(CurrNode, DstOffsets[i]);
 
  917         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
  918           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
  919           if (j < DstOffsets[i+1]) {
 
  920             CurrNode = DstCol2[j];
 
  921             DstNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
  933   Nodes.
Reserve(TotalSrcNodes+TotalDstNodes);
 
  936   while (i < TotalSrcNodes && j < TotalDstNodes) {
 
  937     if (SrcNodeIds[i].Val1 == DstNodeIds[j].Val1) {
 
  938       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, j));
 
  941     } 
else if (SrcNodeIds[i].Val1 < DstNodeIds[j].Val1) {
 
  942       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1));
 
  945       Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j));
 
  949   for (; i < TotalSrcNodes; i++) { Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1)); }
 
  950   for (; j < TotalDstNodes; j++) { Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j)); }
 
  955   PGraphMP Graph = PGraphMP::TObj::New(NumNodes, NumRows);
 
  963   #pragma omp parallel for schedule(static,100) 
  964   for (
int m = 0; m < NumNodes; m++) {
 
  970       TInt Offset = SrcNodeIds[i].GetVal2();
 
  971       TInt Sz = EdgeCol1.Len()-Offset;
 
  972       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
  977       TInt Offset = DstNodeIds[j].GetVal2();
 
  978       TInt Sz = EdgeCol2.Len()-Offset;
 
  979       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
  983     Graph->AddNodeWithEdges(n, InVV[m], OutVV[m]);
 
  985   Graph->SetNodes(NumNodes);
 
  989   omp_set_num_threads(omp_get_max_threads());
 
  990   if (NodeType == 
atInt) {
 
  991     #pragma omp parallel for schedule(static) 
  992     for (
int i = 0; i < Partitions.
Len(); i++) {
 
  995       while (RowI < EndI) {
 
  999         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1001                 for (
TInt ea_i = 0; ea_i < EdgeAttrV.
Len(); ea_i++) {
 
 1002           TStr ColName = EdgeAttrV[ea_i];
 
 1003           TAttrType T = Table->GetColType(ColName);
 
 1004           TInt Index = Table->GetColIdx(ColName);
 
 1007               Graph->AddIntAttrDatE(RowId, Table->IntCols[Index][RowId], ColName);
 
 1010               Graph->AddFltAttrDatE(RowId, Table->FltCols[Index][RowId], ColName);
 
 1013               Graph->AddStrAttrDatE(RowId, Table->GetStrValIdx(Index, RowId), ColName);
 
 1017         if ((Table->SrcNodeAttrV).Len() > 0) {
 
 1018           Table->AddNodeAttributes(SrcId, Table->SrcNodeAttrV, RowId, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
 1021         if ((Table->DstNodeAttrV).Len() > 0) {
 
 1022          Table->AddNodeAttributes(SrcId, Table->DstNodeAttrV, RowId, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
 1027   else if (NodeType == 
atStr) {
 
 1028     #pragma omp parallel for schedule(static) 
 1029     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1032       while (RowI < EndI) {
 
 1036         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1038                 for (
TInt ea_i = 0; ea_i < EdgeAttrV.
Len(); ea_i++) {
 
 1039           TStr ColName = EdgeAttrV[ea_i];
 
 1040           TAttrType T = Table->GetColType(ColName);
 
 1041           TInt Index = Table->GetColIdx(ColName);
 
 1044               Graph->AddIntAttrDatE(RowId, Table->IntCols[Index][RowId], ColName);
 
 1047               Graph->AddFltAttrDatE(RowId, Table->FltCols[Index][RowId], ColName);
 
 1050               Graph->AddStrAttrDatE(RowId, Table->GetStrValIdx(Index, RowId), ColName);
 
 1054         if ((Table->SrcNodeAttrV).Len() > 0) {
 
 1055           Table->AddNodeAttributes(SrcId, Table->SrcNodeAttrV, RowId, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
 1058         if ((Table->DstNodeAttrV).Len() > 0) {
 
 1059          Table->AddNodeAttributes(SrcId, Table->DstNodeAttrV, RowId, NodeIntAttrs, NodeFltAttrs, NodeStrAttrs);
 
 1068   if ((Table->SrcNodeAttrV).Len() > 0 || (Table->DstNodeAttrV).Len() > 0) {
 
 1069     for (
typename PGraphMP::TObj::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) {
 
 1070       TInt NId = NodeI.GetId();
 
 1071       if (NodeIntAttrs.
IsKey(NId)) {
 
 1074           TInt AttrVal = Table->AggregateVector<
TInt>(it.GetDat(), AggrPolicy);
 
 1075           Graph->AddIntAttrDatN(NId, AttrVal, it.GetKey());
 
 1078       if (NodeFltAttrs.
IsKey(NId)) {
 
 1081           TFlt AttrVal = Table->AggregateVector<
TFlt>(it.GetDat(), AggrPolicy);
 
 1082           Graph->AddFltAttrDatN(NId, AttrVal, it.GetKey());
 
 1085       if (NodeStrAttrs.
IsKey(NId)) {
 
 1088           TStr AttrVal = Table->AggregateVector<
TStr>(it.GetDat(), AggrPolicy);
 
 1089           Graph->AddStrAttrDatN(NId, AttrVal, it.GetKey());
 
 1096   Graph->SetEdges(NumRows);
 
 1106 template<
class PGraphMP>
 
 1111   return ToNetworkMP<PGraphMP>(Table, SrcCol, DstCol, V,AggrPolicy);
 
 1117 template<
class PGraphMP>
 
 1119   const TStr& SrcCol, 
const TStr& DstCol,
 
 1125   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
 1126   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
 1127   const TInt NumRows = Table->NumValidRows;
 
 1129   const TAttrType NodeType = Table->GetColType(SrcCol);
 
 1130   Assert(NodeType == Table->GetColType(DstCol));
 
 1134   TIntV SrcCol1, EdgeCol1, EdgeCol2, DstCol2;
 
 1136   #pragma omp parallel sections num_threads(4) 
 1139     { SrcCol1.
Reserve(NumRows, NumRows); }
 
 1141     { EdgeCol1.Reserve(NumRows, NumRows); }
 
 1143     { DstCol2.Reserve(NumRows, NumRows); }
 
 1145     { EdgeCol2.Reserve(NumRows, NumRows); }
 
 1151   const int NThreads = 40;
 
 1152   Table->GetPartitionRanges(Partitions, NThreads);
 
 1153   TInt PartitionSize = Partitions[0].GetVal2()-Partitions[0].GetVal1()+1;
 
 1158   if (NodeType == 
atInt) {
 
 1159     #pragma omp parallel for schedule(static) 
 1160     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1163       while (RowI < EndI) {
 
 1166         EdgeCol1[RowId] = RowId;
 
 1168         EdgeCol2[RowId] = RowId;
 
 1173   else if (NodeType == 
atStr) {
 
 1174     #pragma omp parallel for schedule(static) 
 1175     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1178       while (RowI < EndI) {
 
 1181         EdgeCol1[RowId] = RowId;
 
 1183         EdgeCol2[RowId] = RowId;
 
 1195   int Parts[NThreads+1];
 
 1196   for (
int i = 0; i < NThreads; i++) {
 
 1197     Parts[i] = NumRows.
Val / NThreads * i;
 
 1199   Parts[NThreads] = NumRows;
 
 1206   TInt ExtremePoints[4][NThreads];
 
 1207   omp_set_num_threads(omp_get_max_threads());
 
 1208   #pragma omp parallel 
 1210     #pragma omp for schedule(static) nowait 
 1211     for (
int i = 0; i < NThreads; i++) {
 
 1212       TInt StartPos = Parts[i];
 
 1213       TInt EndPos = Parts[i+1]-1;
 
 1216       ExtremePoints[0][i] = SrcCol1[StartPos];
 
 1217       ExtremePoints[2][i] = SrcCol1[EndPos];
 
 1219     #pragma omp for schedule(static) nowait 
 1220     for (
int i = 0; i < NThreads; i++) {
 
 1221       TInt StartPos = Parts[i];
 
 1222       TInt EndPos = Parts[i+1]-1;
 
 1225       ExtremePoints[1][i] = DstCol2[StartPos];
 
 1226       ExtremePoints[3][i] = DstCol2[EndPos];
 
 1234   TInt MinId(INT_MAX);
 
 1235   for (
int j = 0; j < 2; j++) {
 
 1236     for (
int i = 0; i < NThreads; i++) {
 
 1237       if (MinId > ExtremePoints[j][i]) { MinId = ExtremePoints[j][i]; }
 
 1241   for (
int j = 2; j < 4; j++) {
 
 1242     for (
int i = 0; i < NThreads; i++) {
 
 1243       if (MaxId < ExtremePoints[j][i]) { MaxId = ExtremePoints[j][i]; }
 
 1252   const int NumCollectors = 20;
 
 1253   int Range = MaxId.
Val - MinId.
Val;
 
 1254   TIntV IdRanges(NumCollectors+1);
 
 1255   for (
int j = 0; j < NumCollectors; j++) {
 
 1256     IdRanges[j] = MinId + Range/NumCollectors*j;
 
 1258   IdRanges[NumCollectors] = MaxId+1;
 
 1263   int SrcOffsets[NThreads][NumCollectors+1];
 
 1264   #pragma omp parallel for schedule(static) 
 1265   for (
int i = 0; i < NThreads; i++) {
 
 1266     int CollectorId = 0;
 
 1267     for (
int j = Parts[i]; j < Parts[i+1]; j++) {
 
 1268       while (SrcCol1[j] >= IdRanges[CollectorId]) {
 
 1269         SrcOffsets[i][CollectorId++] = j;
 
 1272     while (CollectorId <= NumCollectors) {
 
 1273       SrcOffsets[i][CollectorId++] = Parts[i+1];
 
 1276   int DstOffsets[NThreads][NumCollectors+1];
 
 1277   #pragma omp parallel for schedule(static) 
 1278   for (
int i = 0; i < NThreads; i++) {
 
 1279     int CollectorId = 0;
 
 1280     for (
int j = Parts[i]; j < Parts[i+1]; j++) {
 
 1281       while (DstCol2[j] >= IdRanges[CollectorId]) {
 
 1282         DstOffsets[i][CollectorId++] = j;
 
 1285     while (CollectorId <= NumCollectors) {
 
 1286       DstOffsets[i][CollectorId++] = Parts[i+1];
 
 1300   TIntV SrcCollectorOffsets(NumCollectors+1);
 
 1301   SrcCollectorOffsets[0] = 0;
 
 1302   for (
int k = 0; k < NumCollectors; k++) {
 
 1304     for (
int i = 0; i < NThreads; i++) {
 
 1305       SumOffset += SrcOffsets[i][k+1] - SrcOffsets[i][k];
 
 1307     SrcCollectorOffsets[k+1] = SrcCollectorOffsets[k] + SumOffset;
 
 1309   TIntV DstCollectorOffsets(NumCollectors+1);
 
 1310   DstCollectorOffsets[0] = 0;
 
 1311   for (
int k = 0; k < NumCollectors; k++) {
 
 1313     for (
int i = 0; i < NThreads; i++) {
 
 1314       SumOffset += DstOffsets[i][k+1] - DstOffsets[i][k];
 
 1316     DstCollectorOffsets[k+1] = DstCollectorOffsets[k] + SumOffset;
 
 1325   TIntV SrcCol3, EdgeCol3, EdgeCol4, DstCol4;
 
 1326   #pragma omp parallel sections num_threads(4) 
 1329     { SrcCol3.
Reserve(NumRows, NumRows); }
 
 1331     { EdgeCol3.
Reserve(NumRows, NumRows); }
 
 1333     { DstCol4.
Reserve(NumRows, NumRows); }
 
 1335     { EdgeCol4.
Reserve(NumRows, NumRows); }
 
 1338   TIntV SrcNodeCounts(NumCollectors), DstNodeCounts(NumCollectors);
 
 1339   #pragma omp parallel for schedule(static) 
 1340   for (
int k = 0; k < NumCollectors; k++) {
 
 1341     int ind = SrcCollectorOffsets[k];
 
 1342     for (
int i = 0; i < NThreads; i++) {
 
 1343       for (
int j = SrcOffsets[i][k]; j < SrcOffsets[i][k+1]; j++) {
 
 1344         SrcCol3[ind] = SrcCol1[j];
 
 1345         EdgeCol3[ind] = EdgeCol1[j];
 
 1349     TTable::QSortKeyVal(SrcCol3, EdgeCol3, SrcCollectorOffsets[k], SrcCollectorOffsets[k+1]-1);
 
 1351     if (SrcCollectorOffsets[k+1] > SrcCollectorOffsets[k]) {
 
 1353       for (
int j = SrcCollectorOffsets[k]+1; j < SrcCollectorOffsets[k+1]; j++) {
 
 1354         if (SrcCol3[j] != SrcCol3[j-1]) { SrcCount++; }
 
 1357     SrcNodeCounts[k] = SrcCount;
 
 1359     ind = DstCollectorOffsets[k];
 
 1360     for (
int i = 0; i < NThreads; i++) {
 
 1361       for (
int j = DstOffsets[i][k]; j < DstOffsets[i][k+1]; j++) {
 
 1362         DstCol4[ind] = DstCol2[j];
 
 1363         EdgeCol4[ind] = EdgeCol2[j];
 
 1367     TTable::QSortKeyVal(DstCol4, EdgeCol4, DstCollectorOffsets[k], DstCollectorOffsets[k+1]-1);
 
 1369     if (DstCollectorOffsets[k+1] > DstCollectorOffsets[k]) {
 
 1371       for (
int j = DstCollectorOffsets[k]+1; j < DstCollectorOffsets[k+1]; j++) {
 
 1372         if (DstCol4[j] != DstCol4[j-1]) { DstCount++; }
 
 1375     DstNodeCounts[k] = DstCount;
 
 1378   TInt TotalSrcNodes = 0;
 
 1380   for (
int i = 0; i < NumCollectors; i++) {
 
 1381     SrcIdOffsets.
Add(TotalSrcNodes);
 
 1382     TotalSrcNodes += SrcNodeCounts[i];
 
 1393   TInt TotalDstNodes = 0;
 
 1395   for (
int i = 0; i < NumCollectors; i++) {
 
 1396     DstIdOffsets.
Add(TotalDstNodes);
 
 1397     TotalDstNodes += DstNodeCounts[i];
 
 1401   TIntPrV SrcNodeIds, DstNodeIds;
 
 1402   #pragma omp parallel sections 
 1405     { SrcNodeIds.
Reserve(TotalSrcNodes, TotalSrcNodes); }
 
 1407     { DstNodeIds.
Reserve(TotalDstNodes, TotalDstNodes); }
 
 1411   #pragma omp parallel for schedule(dynamic) 
 1412   for (
int t = 0; t < 2*NumCollectors; t++) {
 
 1413     if (t < NumCollectors) {
 
 1415       if (SrcCollectorOffsets[i] < SrcCollectorOffsets[i+1]) {
 
 1416         TInt CurrNode = SrcCol3[SrcCollectorOffsets[i]];
 
 1417         TInt ThreadOffset = SrcIdOffsets[i];
 
 1418         SrcNodeIds[ThreadOffset] = 
TIntPr(CurrNode, SrcCollectorOffsets[i]);
 
 1420         for (
TInt j = SrcCollectorOffsets[i]+1; j < SrcCollectorOffsets[i+1]; j++) {
 
 1421           while (j < SrcCollectorOffsets[i+1] && SrcCol3[j] == CurrNode) { j++; }
 
 1422           if (j < SrcCollectorOffsets[i+1]) {
 
 1423             CurrNode = SrcCol3[j];
 
 1424             SrcNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 1430       TInt i = t - NumCollectors;
 
 1431       if (DstCollectorOffsets[i] < DstCollectorOffsets[i+1]) {
 
 1432         TInt CurrNode = DstCol4[DstCollectorOffsets[i]];
 
 1433         TInt ThreadOffset = DstIdOffsets[i];
 
 1434         DstNodeIds[ThreadOffset] = 
TIntPr(CurrNode, DstCollectorOffsets[i]);
 
 1436         for (
TInt j = DstCollectorOffsets[i]+1; j < DstCollectorOffsets[i+1]; j++) {
 
 1437           while (j < DstCollectorOffsets[i+1] && DstCol4[j] == CurrNode) { j++; }
 
 1438           if (j < DstCollectorOffsets[i+1]) {
 
 1439             CurrNode = DstCol4[j];
 
 1440             DstNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 1452   Nodes.
Reserve(TotalSrcNodes+TotalDstNodes);
 
 1455   while (i < TotalSrcNodes && j < TotalDstNodes) {
 
 1456     if (SrcNodeIds[i].Val1 == DstNodeIds[j].Val1) {
 
 1457       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, j));
 
 1460     } 
else if (SrcNodeIds[i].Val1 < DstNodeIds[j].Val1) {
 
 1461       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1));
 
 1464       Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j));
 
 1468   for (; i < TotalSrcNodes; i++) { Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1)); }
 
 1469   for (; j < TotalDstNodes; j++) { Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j)); }
 
 1474   PGraphMP Graph = PGraphMP::TObj::New(NumNodes, NumRows);
 
 1482   #pragma omp parallel for schedule(static,100) 
 1483   for (
int m = 0; m < NumNodes; m++) {
 
 1487     Nodes[m].
GetVal(n, i, j);
 
 1489       TInt Offset = SrcNodeIds[i].GetVal2();
 
 1490       TInt Sz = EdgeCol3.
Len()-Offset;
 
 1491       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
 1496       TInt Offset = DstNodeIds[j].GetVal2();
 
 1497       TInt Sz = EdgeCol4.
Len()-Offset;
 
 1498       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
 1502     Graph->AddNodeWithEdges(n, InVV[m], OutVV[m]);
 
 1504   Graph->SetNodes(NumNodes);
 
 1508   omp_set_num_threads(omp_get_max_threads());
 
 1509   if (NodeType == 
atInt) {
 
 1510     #pragma omp parallel for schedule(static) 
 1511     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1514       while (RowI < EndI) {
 
 1518         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1523   else if (NodeType == 
atStr) {
 
 1524     #pragma omp parallel for schedule(static) 
 1525     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1528       while (RowI < EndI) {
 
 1532         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1537   Graph->SetEdges(NumRows);
 
 1546 template<
class PGraphMP>
 
 1551   return ToNetworkMP2<PGraphMP>(Table, SrcCol, DstCol, V, V, V, AggrPolicy);
 
 1553 #endif // GCC_ATOMIC 
 1571 template<
class PGraph>
 
 1573   const TStr& SrcCol, 
const TStr& DstCol,
 
 1576   PGraph Graph = PGraph::TObj::New();
 
 1578   const TAttrType NodeType = Table->GetColType(SrcCol);
 
 1579   Assert(NodeType == Table->GetColType(DstCol));
 
 1580   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
 1581   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
 1592   for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
 1593     if ((Table->Next)[CurrRowIdx] == Table->Invalid) {
 
 1599     if (NodeType == 
atFlt) {
 
 1600       TFlt FSVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
 1601       SVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FSVal);
 
 1602       TFlt FDVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
 1603       DVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FDVal);
 
 1605     else if (NodeType == 
atInt || NodeType == 
atStr) {
 
 1606       if (NodeType == 
atInt) {
 
 1607         SVal = (Table->IntCols)[SrcColIdx][CurrRowIdx];
 
 1608         DVal = (Table->IntCols)[DstColIdx][CurrRowIdx];
 
 1611         SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
 1613         DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
 1616       if (!Graph->IsNode(SVal)) {Graph->AddNode(SVal); }
 
 1617       if (!Graph->IsNode(DVal)) {Graph->AddNode(DVal); }
 
 1623     Graph->AddEdge(SVal, DVal, CurrRowIdx);
 
 1626     for (
TInt i = 0; i < EdgeAttrV.
Len(); i++) {
 
 1627       TStr ColName = EdgeAttrV[i];
 
 1628       TAttrType T = Table->GetColType(ColName);
 
 1629       TInt Index = Table->GetColIdx(ColName);
 
 1632           Graph->AddIntAttrDatE(CurrRowIdx, Table->IntCols[Index][CurrRowIdx], ColName);
 
 1635           Graph->AddFltAttrDatE(CurrRowIdx, Table->FltCols[Index][CurrRowIdx], ColName);
 
 1638           Graph->AddStrAttrDatE(CurrRowIdx, Table->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 1650 template<
class PGraphMP>
 
 1652   const TStr& SrcCol, 
const TStr& DstCol,
 
 1658   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
 1659   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
 1660   const TInt NumRows = Table->GetNumValidRows();
 
 1662   const TAttrType NodeType = Table->GetColType(SrcCol);
 
 1663   Assert(NodeType == Table->GetColType(DstCol));
 
 1665   TIntV SrcCol1, EdgeCol1, EdgeCol2, DstCol2;
 
 1671   #pragma omp parallel sections num_threads(4) 
 1674     { SrcCol1.Reserve(NumRows, NumRows); }
 
 1676     { EdgeCol1.Reserve(NumRows, NumRows); }
 
 1678     { DstCol2.Reserve(NumRows, NumRows); }
 
 1680     { EdgeCol2.Reserve(NumRows, NumRows); }
 
 1686   Table->GetPartitionRanges(Partitions, omp_get_max_threads());
 
 1687   TInt PartitionSize = Partitions[0].GetVal2()-Partitions[0].GetVal1()+1;
 
 1693   omp_set_num_threads(omp_get_max_threads());
 
 1694   if (NodeType == 
atInt) {
 
 1695     #pragma omp parallel for schedule(static) 
 1696     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1699       while (RowI < EndI) {
 
 1702         EdgeCol1[RowId] = RowId;
 
 1704         EdgeCol2[RowId] = RowId;
 
 1709   else if (NodeType == 
atStr) {
 
 1710     #pragma omp parallel for schedule(static) 
 1711     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1714       while (RowI < EndI) {
 
 1717         EdgeCol1[RowId] = RowId;
 
 1719         EdgeCol2[RowId] = RowId;
 
 1727   omp_set_num_threads(omp_get_max_threads());
 
 1728   #pragma omp parallel 
 1730     #pragma omp single nowait 
 1733       #pragma omp task untied shared(SrcCol1, EdgeCol1) 
 1737     #pragma omp single nowait 
 1740       #pragma omp task untied shared(EdgeCol2, DstCol2) 
 1745     #pragma omp taskwait 
 1751   TInt NumThreads = omp_get_max_threads();
 
 1752   TInt PartSize = (NumRows/NumThreads);
 
 1756   TIntV SrcOffsets, DstOffsets;
 
 1758   for (
TInt i = 1; i < NumThreads; i++) {
 
 1759     TInt CurrOffset = i * PartSize;
 
 1760     while (CurrOffset < (i+1) * PartSize &&
 
 1761           SrcCol1[CurrOffset-1] == SrcCol1[CurrOffset]) {
 
 1765     if (CurrOffset < (i+1) * PartSize) { SrcOffsets.
Add(CurrOffset); }
 
 1767   SrcOffsets.
Add(NumRows);
 
 1770   for (
TInt i = 1; i < NumThreads; i++) {
 
 1771     TInt CurrOffset = i * PartSize;
 
 1772     while (CurrOffset < (i+1) * PartSize &&
 
 1773           DstCol2[CurrOffset-1] == DstCol2[CurrOffset]) {
 
 1777     if (CurrOffset < (i+1) * PartSize) { DstOffsets.
Add(CurrOffset); }
 
 1779   DstOffsets.
Add(NumRows);
 
 1781   TInt SrcPartCnt = SrcOffsets.
Len()-1; 
 
 1782   TInt DstPartCnt = DstOffsets.
Len()-1; 
 
 1785   TIntV SrcNodeCounts, DstNodeCounts;
 
 1786   SrcNodeCounts.
Reserve(SrcPartCnt, SrcPartCnt);
 
 1787   DstNodeCounts.
Reserve(DstPartCnt, DstPartCnt);
 
 1789   #pragma omp parallel for schedule(dynamic) 
 1790   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
 1791     if (t < SrcPartCnt) {
 
 1793       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
 1794         SrcNodeCounts[i] = 1;
 
 1795         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
 1796         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
 1797           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
 1798           if (j < SrcOffsets[i+1]) {
 
 1800             CurrNode = SrcCol1[j];
 
 1805       TInt i = t - SrcPartCnt;
 
 1806       if (DstOffsets[i] != DstOffsets[i+1]) {
 
 1807         DstNodeCounts[i] = 1;
 
 1808         TInt CurrNode = DstCol2[DstOffsets[i]];
 
 1809         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
 1810           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
 1811           if (j < DstOffsets[i+1]) {
 
 1813             CurrNode = DstCol2[j];
 
 1820   TInt TotalSrcNodes = 0;
 
 1822   for (
int i = 0; i < SrcPartCnt; i++) {
 
 1823     SrcIdOffsets.
Add(TotalSrcNodes);
 
 1824     TotalSrcNodes += SrcNodeCounts[i];
 
 1827   TInt TotalDstNodes = 0;
 
 1829   for (
int i = 0; i < DstPartCnt; i++) {
 
 1830     DstIdOffsets.
Add(TotalDstNodes);
 
 1831     TotalDstNodes += DstNodeCounts[i];
 
 1837   TIntPrV SrcNodeIds, DstNodeIds;
 
 1838   #pragma omp parallel sections 
 1841     { SrcNodeIds.
Reserve(TotalSrcNodes, TotalSrcNodes); }
 
 1843     { DstNodeIds.
Reserve(TotalDstNodes, TotalDstNodes); }
 
 1847   #pragma omp parallel for schedule(dynamic) 
 1848   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
 1849     if (t < SrcPartCnt) {
 
 1851       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
 1852         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
 1853         TInt ThreadOffset = SrcIdOffsets[i];
 
 1854         SrcNodeIds[ThreadOffset] = 
TIntPr(CurrNode, SrcOffsets[i]);
 
 1856         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
 1857           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
 1858           if (j < SrcOffsets[i+1]) {
 
 1859             CurrNode = SrcCol1[j];
 
 1860             SrcNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 1866       TInt i = t - SrcPartCnt;
 
 1867       if (DstOffsets[i] != DstOffsets[i+1]) {
 
 1868         TInt CurrNode = DstCol2[DstOffsets[i]];
 
 1869         TInt ThreadOffset = DstIdOffsets[i];
 
 1870         DstNodeIds[ThreadOffset] = 
TIntPr(CurrNode, DstOffsets[i]);
 
 1872         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
 1873           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
 1874           if (j < DstOffsets[i+1]) {
 
 1875             CurrNode = DstCol2[j];
 
 1876             DstNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 1888   Nodes.
Reserve(TotalSrcNodes+TotalDstNodes);
 
 1891   while (i < TotalSrcNodes && j < TotalDstNodes) {
 
 1892     if (SrcNodeIds[i].Val1 == DstNodeIds[j].Val1) {
 
 1893       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, j));
 
 1896     } 
else if (SrcNodeIds[i].Val1 < DstNodeIds[j].Val1) {
 
 1897       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1));
 
 1900       Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j));
 
 1904   for (; i < TotalSrcNodes; i++) { Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1)); }
 
 1905   for (; j < TotalDstNodes; j++) { Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j)); }
 
 1910   PGraphMP Graph = PGraphMP::TObj::New(NumNodes, NumRows);
 
 1918   #pragma omp parallel for schedule(static,100) 
 1919   for (
int m = 0; m < NumNodes; m++) {
 
 1923     Nodes[m].
GetVal(n, i, j);
 
 1925       TInt Offset = SrcNodeIds[i].GetVal2();
 
 1926       TInt Sz = EdgeCol1.Len()-Offset;
 
 1927       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
 1932       TInt Offset = DstNodeIds[j].GetVal2();
 
 1933       TInt Sz = EdgeCol2.Len()-Offset;
 
 1934       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
 1938     Graph->AddNodeWithEdges(n, InVV[m], OutVV[m]);
 
 1940   Graph->SetNodes(NumNodes);
 
 1944   omp_set_num_threads(omp_get_max_threads());
 
 1945   if (NodeType == 
atInt) {
 
 1946     #pragma omp parallel for schedule(static) 
 1947     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1950       while (RowI < EndI) {
 
 1954         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1959   else if (NodeType == 
atStr) {
 
 1960     #pragma omp parallel for schedule(static) 
 1961     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 1964       while (RowI < EndI) {
 
 1968         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 1975   Graph->SetEdges(NumRows);
 
 1976   Graph->SetMxEId(NumRows);
 
 1980   for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
 1981     if ((Table->Next)[CurrRowIdx] == Table->Invalid) {
 
 1984     for (
TInt ea_i = 0; ea_i < EdgeAttrV.
Len(); ea_i++) {
 
 1985       TStr ColName = EdgeAttrV[ea_i];
 
 1986       TAttrType T = Table->GetColType(ColName);
 
 1987       TInt Index = Table->GetColIdx(ColName);
 
 1990           Graph->AddIntAttrDatE(CurrRowIdx, Table->IntCols[Index][CurrRowIdx], ColName);
 
 1993           Graph->AddFltAttrDatE(CurrRowIdx, Table->FltCols[Index][CurrRowIdx], ColName);
 
 1996           Graph->AddStrAttrDatE(CurrRowIdx, Table->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 2006 #endif // GCC_ATOMIC 
 2009 template<
class PGraph>
 
 2011   const TStr& SrcCol, 
const TStr& DstCol,
 
 2014   PGraph Graph = PGraph::TObj::New();
 
 2016   const TAttrType NodeType = Table->GetColType(SrcCol);
 
 2017   Assert(NodeType == Table->GetColType(DstCol));
 
 2018   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
 2019   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
 2022   const TAttrType NodeTypeN = NodeTable->GetColType(NodeCol);
 
 2023   const TInt NodeColIdx = NodeTable->GetColIdx(NodeCol);
 
 2038   for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
 2039     if ((Table->Next)[CurrRowIdx] == Table->Invalid) {
 
 2045     if (NodeType == 
atFlt) {
 
 2046       TFlt FSVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
 2047       SVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FSVal);
 
 2048       TFlt FDVal = (Table->FltCols)[SrcColIdx][CurrRowIdx];
 
 2049       DVal = Table->CheckAndAddFltNode(Graph, FltNodeVals, FDVal);
 
 2051     else if (NodeType == 
atInt || NodeType == 
atStr) {
 
 2052       if (NodeType == 
atInt) {
 
 2053         SVal = (Table->IntCols)[SrcColIdx][CurrRowIdx];
 
 2054         DVal = (Table->IntCols)[DstColIdx][CurrRowIdx];
 
 2057         SVal = (Table->StrColMaps)[SrcColIdx][CurrRowIdx];
 
 2059         DVal = (Table->StrColMaps)[DstColIdx][CurrRowIdx];
 
 2062       if (!Graph->IsNode(SVal)) {Graph->AddNode(SVal); }
 
 2063       if (!Graph->IsNode(DVal)) {Graph->AddNode(DVal); }
 
 2069     Graph->AddEdge(SVal, DVal, CurrRowIdx);
 
 2072     for (
TInt i = 0; i < EdgeAttrV.
Len(); i++) {
 
 2073       TStr ColName = EdgeAttrV[i];
 
 2074       TAttrType T = Table->GetColType(ColName);
 
 2075       TInt Index = Table->GetColIdx(ColName);
 
 2078           Graph->AddIntAttrDatE(CurrRowIdx, Table->IntCols[Index][CurrRowIdx], ColName);
 
 2081           Graph->AddFltAttrDatE(CurrRowIdx, Table->FltCols[Index][CurrRowIdx], ColName);
 
 2084           Graph->AddStrAttrDatE(CurrRowIdx, Table->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 2092   if (NodeAttrV.
Len() > 0) {
 
 2093     for (
int CurrRowIdx = 0; CurrRowIdx < (NodeTable->Next).Len(); CurrRowIdx++) {
 
 2094       if ((NodeTable->Next)[CurrRowIdx] == NodeTable->Invalid) {
 
 2098       if (NodeTypeN == 
atInt) {
 
 2099         NId = (NodeTable->IntCols)[NodeColIdx][CurrRowIdx];
 
 2101       else if (NodeTypeN == 
atStr){
 
 2102         NId = (NodeTable->StrColMaps)[NodeColIdx][CurrRowIdx];
 
 2104       for (
TInt i = 0; i < NodeAttrV.
Len(); i++) {
 
 2105         TStr ColName = NodeAttrV[i];
 
 2106         TAttrType T = NodeTable->GetColType(ColName);
 
 2107         TInt Index = NodeTable->GetColIdx(ColName);
 
 2110             Graph->AddIntAttrDatN(NId, NodeTable->IntCols[Index][CurrRowIdx], ColName);
 
 2113             Graph->AddFltAttrDatN(NId, NodeTable->FltCols[Index][CurrRowIdx], ColName);
 
 2116             Graph->AddStrAttrDatN(NId, NodeTable->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 2130 template<
class PGraphMP>
 
 2132   const TStr& SrcCol, 
const TStr& DstCol,
 
 2138   const TInt SrcColIdx = Table->GetColIdx(SrcCol);
 
 2139   const TInt DstColIdx = Table->GetColIdx(DstCol);
 
 2140   const TInt NumRows = Table->GetNumValidRows();
 
 2142   const TAttrType NodeType = Table->GetColType(SrcCol);
 
 2143   Assert(NodeType == Table->GetColType(DstCol));
 
 2146   TIntV SrcCol1, EdgeCol1, EdgeCol2, DstCol2;
 
 2148   const TAttrType NodeTypeN = NodeTable->GetColType(NodeCol);
 
 2149   const TInt NodeColIdx = NodeTable->GetColIdx(NodeCol);
 
 2154   #pragma omp parallel sections num_threads(4) 
 2157     { SrcCol1.Reserve(NumRows, NumRows); }
 
 2159     { EdgeCol1.Reserve(NumRows, NumRows); }
 
 2161     { DstCol2.Reserve(NumRows, NumRows); }
 
 2163     { EdgeCol2.Reserve(NumRows, NumRows); }
 
 2169   Table->GetPartitionRanges(Partitions, omp_get_max_threads());
 
 2170   TInt PartitionSize = Partitions[0].GetVal2()-Partitions[0].GetVal1()+1;
 
 2175   omp_set_num_threads(omp_get_max_threads());
 
 2176   if (NodeType == 
atInt) {
 
 2177     #pragma omp parallel for schedule(static) 
 2178     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 2181       while (RowI < EndI) {
 
 2184         EdgeCol1[RowId] = RowId;
 
 2186         EdgeCol2[RowId] = RowId;
 
 2191   else if (NodeType == 
atStr) {
 
 2192     #pragma omp parallel for schedule(static) 
 2193     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 2196       while (RowI < EndI) {
 
 2199         EdgeCol1[RowId] = RowId;
 
 2201         EdgeCol2[RowId] = RowId;
 
 2209   omp_set_num_threads(omp_get_max_threads());
 
 2210   #pragma omp parallel 
 2212     #pragma omp single nowait 
 2215       #pragma omp task untied shared(SrcCol1, EdgeCol1) 
 2219     #pragma omp single nowait 
 2222       #pragma omp task untied shared(EdgeCol2, DstCol2) 
 2227     #pragma omp taskwait 
 2233   TInt NumThreads = omp_get_max_threads();
 
 2234   TInt PartSize = (NumRows/NumThreads);
 
 2238   TIntV SrcOffsets, DstOffsets;
 
 2240   for (
TInt i = 1; i < NumThreads; i++) {
 
 2241     TInt CurrOffset = i * PartSize;
 
 2242     while (CurrOffset < (i+1) * PartSize &&
 
 2243           SrcCol1[CurrOffset-1] == SrcCol1[CurrOffset]) {
 
 2247     if (CurrOffset < (i+1) * PartSize) { SrcOffsets.
Add(CurrOffset); }
 
 2249   SrcOffsets.
Add(NumRows);
 
 2252   for (
TInt i = 1; i < NumThreads; i++) {
 
 2253     TInt CurrOffset = i * PartSize;
 
 2254     while (CurrOffset < (i+1) * PartSize &&
 
 2255           DstCol2[CurrOffset-1] == DstCol2[CurrOffset]) {
 
 2259     if (CurrOffset < (i+1) * PartSize) { DstOffsets.
Add(CurrOffset); }
 
 2261   DstOffsets.
Add(NumRows);
 
 2263   TInt SrcPartCnt = SrcOffsets.
Len()-1; 
 
 2264   TInt DstPartCnt = DstOffsets.
Len()-1; 
 
 2267   TIntV SrcNodeCounts, DstNodeCounts;
 
 2268   SrcNodeCounts.
Reserve(SrcPartCnt, SrcPartCnt);
 
 2269   DstNodeCounts.
Reserve(DstPartCnt, DstPartCnt);
 
 2271   #pragma omp parallel for schedule(dynamic) 
 2272   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
 2273     if (t < SrcPartCnt) {
 
 2275       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
 2276         SrcNodeCounts[i] = 1;
 
 2277         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
 2278         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
 2279           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
 2280           if (j < SrcOffsets[i+1]) {
 
 2282             CurrNode = SrcCol1[j];
 
 2287       TInt i = t - SrcPartCnt;
 
 2288       if (DstOffsets[i] != DstOffsets[i+1]) {
 
 2289         DstNodeCounts[i] = 1;
 
 2290         TInt CurrNode = DstCol2[DstOffsets[i]];
 
 2291         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
 2292           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
 2293           if (j < DstOffsets[i+1]) {
 
 2295             CurrNode = DstCol2[j];
 
 2302   TInt TotalSrcNodes = 0;
 
 2304   for (
int i = 0; i < SrcPartCnt; i++) {
 
 2305     SrcIdOffsets.
Add(TotalSrcNodes);
 
 2306     TotalSrcNodes += SrcNodeCounts[i];
 
 2309   TInt TotalDstNodes = 0;
 
 2311   for (
int i = 0; i < DstPartCnt; i++) {
 
 2312     DstIdOffsets.
Add(TotalDstNodes);
 
 2313     TotalDstNodes += DstNodeCounts[i];
 
 2319   TIntPrV SrcNodeIds, DstNodeIds;
 
 2320   #pragma omp parallel sections 
 2323     { SrcNodeIds.
Reserve(TotalSrcNodes, TotalSrcNodes); }
 
 2325     { DstNodeIds.
Reserve(TotalDstNodes, TotalDstNodes); }
 
 2329   #pragma omp parallel for schedule(dynamic) 
 2330   for (
int t = 0; t < SrcPartCnt+DstPartCnt; t++) {
 
 2331     if (t < SrcPartCnt) {
 
 2333       if (SrcOffsets[i] != SrcOffsets[i+1]) {
 
 2334         TInt CurrNode = SrcCol1[SrcOffsets[i]];
 
 2335         TInt ThreadOffset = SrcIdOffsets[i];
 
 2336         SrcNodeIds[ThreadOffset] = 
TIntPr(CurrNode, SrcOffsets[i]);
 
 2338         for (
TInt j = SrcOffsets[i]+1; j < SrcOffsets[i+1]; j++) {
 
 2339           while (j < SrcOffsets[i+1] && SrcCol1[j] == CurrNode) { j++; }
 
 2340           if (j < SrcOffsets[i+1]) {
 
 2341             CurrNode = SrcCol1[j];
 
 2342             SrcNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 2348       TInt i = t - SrcPartCnt;
 
 2349       if (DstOffsets[i] != DstOffsets[i+1]) {
 
 2350         TInt CurrNode = DstCol2[DstOffsets[i]];
 
 2351         TInt ThreadOffset = DstIdOffsets[i];
 
 2352         DstNodeIds[ThreadOffset] = 
TIntPr(CurrNode, DstOffsets[i]);
 
 2354         for (
TInt j = DstOffsets[i]+1; j < DstOffsets[i+1]; j++) {
 
 2355           while (j < DstOffsets[i+1] && DstCol2[j] == CurrNode) { j++; }
 
 2356           if (j < DstOffsets[i+1]) {
 
 2357             CurrNode = DstCol2[j];
 
 2358             DstNodeIds[ThreadOffset+CurrCount] = 
TIntPr(CurrNode, j);
 
 2370   Nodes.
Reserve(TotalSrcNodes+TotalDstNodes);
 
 2373   while (i < TotalSrcNodes && j < TotalDstNodes) {
 
 2374     if (SrcNodeIds[i].Val1 == DstNodeIds[j].Val1) {
 
 2375       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, j));
 
 2378     } 
else if (SrcNodeIds[i].Val1 < DstNodeIds[j].Val1) {
 
 2379       Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1));
 
 2382       Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j));
 
 2386   for (; i < TotalSrcNodes; i++) { Nodes.
Add(
TIntTr(SrcNodeIds[i].Val1, i, -1)); }
 
 2387   for (; j < TotalDstNodes; j++) { Nodes.
Add(
TIntTr(DstNodeIds[j].Val1, -1, j)); }
 
 2392   PGraphMP Graph = PGraphMP::TObj::New(NumNodes, NumRows);
 
 2400   #pragma omp parallel for schedule(static,100) 
 2401   for (
int m = 0; m < NumNodes; m++) {
 
 2405     Nodes[m].
GetVal(n, i, j);
 
 2407       TInt Offset = SrcNodeIds[i].GetVal2();
 
 2408       TInt Sz = EdgeCol1.Len()-Offset;
 
 2409       if (i < SrcNodeIds.
Len()-1) { Sz = SrcNodeIds[i+1].GetVal2()-Offset; }
 
 2414       TInt Offset = DstNodeIds[j].GetVal2();
 
 2415       TInt Sz = EdgeCol2.Len()-Offset;
 
 2416       if (j < DstNodeIds.
Len()-1) { Sz = DstNodeIds[j+1].GetVal2()-Offset; }
 
 2420     Graph->AddNodeWithEdges(n, InVV[m], OutVV[m]);
 
 2422   Graph->SetNodes(NumNodes);
 
 2426   omp_set_num_threads(omp_get_max_threads());
 
 2427   if (NodeType == 
atInt) {
 
 2428     #pragma omp parallel for schedule(static) 
 2429     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 2432       while (RowI < EndI) {
 
 2436         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 2441   else if (NodeType == 
atStr) {
 
 2442     #pragma omp parallel for schedule(static) 
 2443     for (
int i = 0; i < Partitions.
Len(); i++) {
 
 2446       while (RowI < EndI) {
 
 2450         Graph->AddEdgeUnchecked(RowId, SrcId, DstId);
 
 2457   Graph->SetEdges(NumRows);
 
 2458   Graph->SetMxEId(NumRows);
 
 2462   for (
int CurrRowIdx = 0; CurrRowIdx < (Table->Next).Len(); CurrRowIdx++) {
 
 2463     if ((Table->Next)[CurrRowIdx] == Table->Invalid) {
 
 2466     for (
TInt ea_i = 0; ea_i < EdgeAttrV.
Len(); ea_i++) {
 
 2467       TStr ColName = EdgeAttrV[ea_i];
 
 2468       TAttrType T = Table->GetColType(ColName);
 
 2469       TInt Index = Table->GetColIdx(ColName);
 
 2472           Graph->AddIntAttrDatE(CurrRowIdx, Table->IntCols[Index][CurrRowIdx], ColName);
 
 2475           Graph->AddFltAttrDatE(CurrRowIdx, Table->FltCols[Index][CurrRowIdx], ColName);
 
 2478           Graph->AddStrAttrDatE(CurrRowIdx, Table->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 2485   if (NodeAttrV.
Len() > 0) {
 
 2486     for (
int CurrRowIdx = 0; CurrRowIdx < (NodeTable->Next).Len(); CurrRowIdx++) {
 
 2487       if ((NodeTable->Next)[CurrRowIdx] == NodeTable->Invalid) {
 
 2491       if (NodeTypeN == 
atInt) {
 
 2492         NId = (NodeTable->IntCols)[NodeColIdx][CurrRowIdx];
 
 2494       else if (NodeTypeN == 
atStr){
 
 2495         NId = (NodeTable->StrColMaps)[NodeColIdx][CurrRowIdx];
 
 2497       for (
TInt i = 0; i < NodeAttrV.
Len(); i++) {
 
 2498         TStr ColName = NodeAttrV[i];
 
 2499         TAttrType T = NodeTable->GetColType(ColName);
 
 2500         TInt Index = NodeTable->GetColIdx(ColName);
 
 2503             Graph->AddIntAttrDatN(NId, NodeTable->IntCols[Index][CurrRowIdx], ColName);
 
 2506             Graph->AddFltAttrDatN(NId, NodeTable->FltCols[Index][CurrRowIdx], ColName);
 
 2509             Graph->AddStrAttrDatN(NId, NodeTable->GetStrValIdx(Index, CurrRowIdx), ColName);
 
 2520 #endif // GCC_ATOMIC 
int GetPrimHashCd() const 
 
TPair< TInt, TInt > TIntPr
 
Main namespace for all the Snap global entities. 
 
enum TAttrType_ TAttrType
Types for tables, sparse and dense attributes. 
 
int LoadModeNetToNet(PMMNet Graph, const TStr &Name, PTable Table, const TStr &NCol, TStrV &NodeAttrV)
Loads a mode, with name Name, into the PMMNet from the TTable. NCol specifies the node id column and ...
 
TInt GetIntAttr(TInt ColIdx) const 
Returns value of integer attribute specified by integer column index for current row. 
 
PGraphMP ToGraphMP(PTable Table, const TStr &SrcCol, const TStr &DstCol)
Performs table to graph conversion in parallel using the sort-first algorithm. This is the recommende...
 
TSizeTy Len() const 
Returns the number of elements in the vector. 
 
static PNGraphMP New()
Static constructor that returns a pointer to the graph. Call: PNGraphMP Graph = TNGraphMP::New(). 
 
void Start(const TExperiment Exp)
Start a new experiment. 
 
TAttrAggr
Possible policies for aggregating node attributes. 
 
const TDat & GetDat(const TKey &Key) const 
 
Node iterator. Only forward iteration (operator++) is supported. 
 
void CopyUniqueFrom(TVec< TVal, TSizeTy > &Vec, TInt Offset, TInt Sz)
Copy Sz values from Vec starting at Offset. 
 
void Stop(const TExperiment Exp)
Stop the current experiment. 
 
Iterator class for TTable rows. 
 
const TVal & GetVal(const TSizeTy &ValN) const 
Returns a reference to the element at position ValN in the vector. 
 
int LoadCrossNetToNet(PMMNet Graph, const TStr &Mode1, const TStr &Mode2, const TStr &CrossName, PTable Table, const TStr &SrcCol, const TStr &DstCol, TStrV &EdgeAttrV)
Loads a crossnet from Mode1 to Mode2, with name CrossName, from the provided TTable. EdgeAttrV specifies edge attributes. 
 
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector. 
 
PGraph ToGraph(PTable Table, const TStr &SrcCol, const TStr &DstCol, TAttrAggr AggrPolicy)
Sequentially converts the table into a graph with links from nodes in SrcCol to those in DstCol...
 
int LoadCrossNet(TCrossNet &Graph, PTable Table, const TStr &SrcCol, const TStr &DstCol, TStrV &EdgeAttrV)
Loads the edges from the TTable and EdgeAttrV specifies columns containing edge attributes. 
 
PGraphMP ToNetworkMP(PTable Table, const TStr &SrcCol, const TStr &DstCol, TStrV &SrcAttrV, TStrV &DstAttrV, TStrV &EdgeAttrV, TAttrAggr AggrPolicy)
Does Table to Network conversion in parallel using the sort-first algorithm. This is the recommended ...
 
PGraph ToNetwork(PTable Table, const TStr &SrcCol, const TStr &DstCol, TStrV &SrcAttrV, TStrV &DstAttrV, TStrV &EdgeAttrV, TAttrAggr AggrPolicy)
Converts the Table into a graph with edges from SrcCol to DstCol, and attribute vector defined by the...
 
int LoadMode(TModeNet &Graph, PTable Table, const TStr &NCol, TStrV &NodeAttrV)
Loads the nodes specified in column NCol from the TTable with the attributes specified in NodeAttrV...
 
TInt GetRowIdx() const 
Gets the id of the row pointed by this iterator. 
 
TInt GetStrMapById(TInt ColIdx) const 
Returns integer mapping of a string attribute value specified by string column index for current row...
 
static void QSortKeyVal(TIntV &Key, TIntV &Val, TInt Start, TInt End)
 
The nodes of one particular mode in a TMMNet, and their neighbor vectors as TIntV attributes...
 
PGraphMP ToGraphMP3(PTable Table, const TStr &SrcCol, const TStr &DstCol)
Performs table to graph conversion in parallel. Uses the hash-first method, which is less optimal...
 
TTriple< TInt, TInt, TInt > TIntTr
 
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements. 
 
void Reserve(const TSizeTy &_MxVals)
Reserves enough memory for the vector to store _MxVals elements. 
 
static TStopwatch * GetInstance()
 
bool IsKey(const TKey &Key) const 
 
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element. 
 
PGraphMP ToNetworkMP2(PTable Table, const TStr &SrcCol, const TStr &DstCol, TStrV &SrcAttrV, TStrV &DstAttrV, TStrV &EdgeAttrV, TAttrAggr AggrPolicy)
Implements table to network conversion in parallel. Not the recommended algorithm, using ToNetworkMP instead. 
 
Implements a single CrossNet consisting of edges between two TModeNets (could be the same TModeNet) ...
 
Routines to benchmark table operations.