OSDN Git Service

Upgrade lanes from qgit2.3
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / lanes.cpp
index a1d5425..43e561a 100644 (file)
-/*
-       Description: history graph computation
-
-       Author: Marco Costalba (C) 2005-2007
-
-       Copyright: See COPYING file that comes with this distribution
-
-*/
-#include "stdafx.h"
-#include "lanes.h"
-
-#define IS_NODE(x) (x == NODE || x == NODE_R || x == NODE_L)
-
-
-void Lanes::init(const QString& expectedSha) {
-
-       clear();
-       activeLane = 0;
-       setBoundary(false);
-       add(BRANCH, expectedSha, activeLane);
-}
-
-void Lanes::clear() {
-
-       typeVec.clear();
-       nextShaVec.clear();
-}
-
-void Lanes::setBoundary(bool b) {
-// changes the state so must be called as first one
-
-       NODE   = b ? BOUNDARY_C : MERGE_FORK;
-       NODE_R = b ? BOUNDARY_R : MERGE_FORK_R;
-       NODE_L = b ? BOUNDARY_L : MERGE_FORK_L;
-       boundary = b;
-
-       if (boundary)
-               typeVec[activeLane] = BOUNDARY;
-}
-
-bool Lanes::isFork(const QString& sha, bool& isDiscontinuity) {
-
-       int pos = findNextSha(sha, 0);
-       isDiscontinuity = (activeLane != pos);
-       if (pos == -1) // new branch case
-               return false;
-
-       return (findNextSha(sha, pos + 1) != -1);
-/*
-       int cnt = 0;
-       while (pos != -1) {
-               cnt++;
-               pos = findNextSha(sha, pos + 1);
-//             if (isDiscontinuity)
-//                     isDiscontinuity = (activeLane != pos);
-       }
-       return (cnt > 1);
-*/
-}
-
-void Lanes::setFork(const QString& sha) {
-
-       int rangeStart, rangeEnd, idx;
-       rangeStart = rangeEnd = idx = findNextSha(sha, 0);
-
-       while (idx != -1) {
-               rangeEnd = idx;
-               typeVec[idx] = TAIL;
-               idx = findNextSha(sha, idx + 1);
-       }
-       typeVec[activeLane] = NODE;
-
-       int& startT = typeVec[rangeStart];
-       int& endT = typeVec[rangeEnd];
-
-       if (startT == NODE)
-               startT = NODE_L;
-
-       if (endT == NODE)
-               endT = NODE_R;
-
-       if (startT == TAIL)
-               startT = TAIL_L;
-
-       if (endT == TAIL)
-               endT = TAIL_R;
-
-       for (int i = rangeStart + 1; i < rangeEnd; i++) {
-
-               int& t = typeVec[i];
-
-               if (t == NOT_ACTIVE)
-                       t = CROSS;
-
-               else if (t == EMPTY)
-                       t = CROSS_EMPTY;
-       }
-}
-
-void Lanes::setMerge(const QStringList& parents) {
-// setFork() must be called before setMerge()
-
-       if (boundary)
-               return; // handle as a simple active line
-
-       int& t = typeVec[activeLane];
-       bool wasFork   = (t == NODE);
-       bool wasFork_L = (t == NODE_L);
-       bool wasFork_R = (t == NODE_R);
-       bool joinWasACross = false;
-
-       t = NODE;
-
-       int rangeStart = activeLane, rangeEnd = activeLane;
-
-       QStringList::const_iterator it=parents.begin();
-
-       for (++it; it != parents.end(); ++it) { // skip first parent
-
-               int idx = findNextSha(*it, 0);
-               if (idx != -1) {
-
-                       if (typeVec[idx] == CROSS)
-                               joinWasACross = true;
-
-                       typeVec[idx] = JOIN;
-
-                       if (idx > rangeEnd)
-                               rangeEnd = idx;
-
-                       if (idx < rangeStart)
-                               rangeStart = idx;
-               } else
-                       rangeEnd = add(HEAD, *it, rangeEnd + 1);
-       }
-       int& startT = typeVec[rangeStart];
-       int& endT = typeVec[rangeEnd];
-
-       if (startT == NODE && !wasFork && !wasFork_R)
-               startT = NODE_L;
-
-       if (endT == NODE && !wasFork && !wasFork_L)
-               endT = NODE_R;
-
-       if (startT == JOIN && !joinWasACross)
-               startT = JOIN_L;
-
-       if (endT == JOIN && !joinWasACross)
-               endT = JOIN_R;
-
-       if (startT == HEAD)
-               startT = HEAD_L;
-
-       if (endT == HEAD)
-               endT = HEAD_R;
-
-       for (int i = rangeStart + 1; i < rangeEnd; i++) {
-
-               int& t = typeVec[i];
-
-               if (t == NOT_ACTIVE)
-                       t = CROSS;
-
-               else if (t == EMPTY)
-                       t = CROSS_EMPTY;
-
-               else if (t == TAIL_R || t == TAIL_L)
-                       t = TAIL;
-       }
-}
-
-void Lanes::setInitial() {
-
-       int& t = typeVec[activeLane];
-       if (!IS_NODE(t) && t != APPLIED)
-               t = (boundary ? BOUNDARY : INITIAL);
-}
-
-void Lanes::setApplied() {
-
-       // applied patches are not merges, nor forks
-       typeVec[activeLane] = APPLIED; // TODO test with boundaries
-}
-
-void Lanes::changeActiveLane(const QString& sha) {
-
-       int& t = typeVec[activeLane];
-       if (t == INITIAL || isBoundary(t))
-               t = EMPTY;
-       else
-               t = NOT_ACTIVE;
-
-       int idx = findNextSha(sha, 0); // find first sha
-       if (idx != -1)
-               typeVec[idx] = ACTIVE; // called before setBoundary()
-       else
-               idx = add(BRANCH, sha, activeLane); // new branch
-
-       activeLane = idx;
-}
-
-void Lanes::afterMerge() {
-
-       if (boundary)
-               return; // will be reset by changeActiveLane()
-
-       for (unsigned int i = 0; i < typeVec.size(); i++) {
-
-               int& t = typeVec[i];
-
-               if (isHead(t) || isJoin(t) || t == CROSS)
-                       t = NOT_ACTIVE;
-
-               else if (t == CROSS_EMPTY)
-                       t = EMPTY;
-
-               else if (IS_NODE(t))
-                       t = ACTIVE;
-       }
-}
-
-void Lanes::afterFork() {
-
-       for (unsigned int i = 0; i < typeVec.size(); i++) {
-
-               int& t = typeVec[i];
-
-               if (t == CROSS)
-                       t = NOT_ACTIVE;
-
-               else if (isTail(t) || t == CROSS_EMPTY)
-                       t = EMPTY;
-
-               if (!boundary && IS_NODE(t))
-                       t = ACTIVE; // boundary will be reset by changeActiveLane()
-       }
-       while (typeVec.back() == EMPTY) {
-               typeVec.pop_back();
-               nextShaVec.pop_back();
-       }
-}
-
-bool Lanes::isBranch() {
-
-       return (typeVec[activeLane] == BRANCH);
-}
-
-void Lanes::afterBranch() {
-
-       typeVec[activeLane] = ACTIVE; // TODO test with boundaries
-}
-
-void Lanes::afterApplied() {
-
-       typeVec[activeLane] = ACTIVE; // TODO test with boundaries
-}
-
-void Lanes::nextParent(const QString& sha) {
-
-       nextShaVec[activeLane] = (boundary ? QString(_T("")) : sha);
-}
-
-int Lanes::findNextSha(const QString& next, int pos) {
-
-       for (unsigned int i = pos; i < nextShaVec.size(); i++)
-               if (nextShaVec[i] == next)
-                       return i;
-       return -1;
-}
-
-int Lanes::findType(int type, int pos) {
-
-       for (unsigned int i = pos; i < typeVec.size(); i++)
-               if (typeVec[i] == type)
-                       return i;
-       return -1;
-}
-
-int Lanes::add(int type, const QString& next, int pos) {
-
-       // first check empty lanes starting from pos
-       if (pos < (int)typeVec.size()) {
-               pos = findType(EMPTY, pos);
-               if (pos != -1) {
-                       typeVec[pos] = type;
-                       nextShaVec[pos] = next;
-                       return pos;
-               }
-       }
-       // if all lanes are occupied add a new lane
-       typeVec.push_back(type);
-       nextShaVec.push_back(next);
-       return typeVec.size() - 1;
-}
+/*\r
+       Description: history graph computation\r
+\r
+       Author: Marco Costalba (C) 2005-2007\r
+\r
+       Copyright: See COPYING file that comes with this distribution\r
+\r
+*/\r
+#include "stdafx.h"\r
+#include "lanes.h"\r
+\r
+#define IS_NODE(x) (x == NODE || x == NODE_R || x == NODE_L)\r
+\r
+\r
+void Lanes::init(const QString& expectedSha) {\r
+\r
+       clear();\r
+       activeLane = 0;\r
+       setBoundary(false);\r
+       add(BRANCH, expectedSha, activeLane);\r
+}\r
+\r
+void Lanes::clear() {\r
+\r
+       typeVec.clear();\r
+       nextShaVec.clear();\r
+}\r
+\r
+void Lanes::setBoundary(bool b) {\r
+// changes the state so must be called as first one\r
+\r
+       NODE   = b ? BOUNDARY_C : MERGE_FORK;\r
+       NODE_R = b ? BOUNDARY_R : MERGE_FORK_R;\r
+       NODE_L = b ? BOUNDARY_L : MERGE_FORK_L;\r
+       boundary = b;\r
+\r
+       if (boundary)\r
+               typeVec[activeLane] = BOUNDARY;\r
+}\r
+\r
+bool Lanes::isFork(const QString& sha, bool& isDiscontinuity) {\r
+\r
+       int pos = findNextSha(sha, 0);\r
+       isDiscontinuity = (activeLane != pos);\r
+       if (pos == -1) // new branch case\r
+               return false;\r
+\r
+       return (findNextSha(sha, pos + 1) != -1);\r
+/*\r
+       int cnt = 0;\r
+       while (pos != -1) {\r
+               cnt++;\r
+               pos = findNextSha(sha, pos + 1);\r
+//             if (isDiscontinuity)\r
+//                     isDiscontinuity = (activeLane != pos);\r
+       }\r
+       return (cnt > 1);\r
+*/\r
+}\r
+\r
+void Lanes::setFork(const QString& sha) {\r
+\r
+       int rangeStart, rangeEnd, idx;\r
+       rangeStart = rangeEnd = idx = findNextSha(sha, 0);\r
+\r
+       while (idx != -1) {\r
+               rangeEnd = idx;\r
+               typeVec[idx] = TAIL;\r
+               idx = findNextSha(sha, idx + 1);\r
+       }\r
+       typeVec[activeLane] = NODE;\r
+\r
+       int& startT = typeVec[rangeStart];\r
+       int& endT = typeVec[rangeEnd];\r
+\r
+       if (startT == NODE)\r
+               startT = NODE_L;\r
+\r
+       if (endT == NODE)\r
+               endT = NODE_R;\r
+\r
+       if (startT == TAIL)\r
+               startT = TAIL_L;\r
+\r
+       if (endT == TAIL)\r
+               endT = TAIL_R;\r
+\r
+       for (int i = rangeStart + 1; i < rangeEnd; i++) {\r
+\r
+               int& t = typeVec[i];\r
+\r
+               if (t == NOT_ACTIVE)\r
+                       t = CROSS;\r
+\r
+               else if (t == EMPTY)\r
+                       t = CROSS_EMPTY;\r
+       }\r
+}\r
+\r
+void Lanes::setMerge(const QStringList& parents) {\r
+// setFork() must be called before setMerge()\r
+\r
+       if (boundary)\r
+               return; // handle as a simple active line\r
+\r
+       int& t = typeVec[activeLane];\r
+       bool wasFork   = (t == NODE);\r
+       bool wasFork_L = (t == NODE_L);\r
+       bool wasFork_R = (t == NODE_R);\r
+       bool startJoinWasACross = false, endJoinWasACross = false;\r
+\r
+       t = NODE;\r
+\r
+       int rangeStart = activeLane, rangeEnd = activeLane;\r
+       QStringList::const_iterator it(parents.begin());\r
+       for (++it; it != parents.end(); ++it) { // skip first parent\r
+\r
+               int idx = findNextSha(*it, 0);\r
+               if (idx != -1) {\r
+\r
+                       if (idx > rangeEnd) {\r
+\r
+                               rangeEnd = idx;\r
+                               endJoinWasACross = typeVec[idx] == CROSS;\r
+                       }\r
+\r
+                       if (idx < rangeStart) {\r
+\r
+                               rangeStart = idx;\r
+                               startJoinWasACross = typeVec[idx] == CROSS;\r
+                       }\r
+\r
+                       typeVec[idx] = JOIN;\r
+               } else\r
+                       rangeEnd = add(HEAD, *it, rangeEnd + 1);\r
+       }\r
+       int& startT = typeVec[rangeStart];\r
+       int& endT = typeVec[rangeEnd];\r
+\r
+       if (startT == NODE && !wasFork && !wasFork_R)\r
+               startT = NODE_L;\r
+\r
+       if (endT == NODE && !wasFork && !wasFork_L)\r
+               endT = NODE_R;\r
+\r
+       if (startT == JOIN && !startJoinWasACross)\r
+               startT = JOIN_L;\r
+\r
+       if (endT == JOIN && !endJoinWasACross)\r
+               endT = JOIN_R;\r
+\r
+       if (startT == HEAD)\r
+               startT = HEAD_L;\r
+\r
+       if (endT == HEAD)\r
+               endT = HEAD_R;\r
+\r
+       for (int i = rangeStart + 1; i < rangeEnd; i++) {\r
+\r
+               int& t = typeVec[i];\r
+\r
+               if (t == NOT_ACTIVE)\r
+                       t = CROSS;\r
+\r
+               else if (t == EMPTY)\r
+                       t = CROSS_EMPTY;\r
+\r
+               else if (t == TAIL_R || t == TAIL_L)\r
+                       t = TAIL;\r
+       }\r
+}\r
+\r
+void Lanes::setInitial() {\r
+\r
+       int& t = typeVec[activeLane];\r
+       if (!IS_NODE(t) && t != APPLIED)\r
+               t = (boundary ? BOUNDARY : INITIAL);\r
+}\r
+\r
+void Lanes::setApplied() {\r
+\r
+       // applied patches are not merges, nor forks\r
+       typeVec[activeLane] = APPLIED; // TODO test with boundaries\r
+}\r
+\r
+void Lanes::changeActiveLane(const QString& sha) {\r
+\r
+       int& t = typeVec[activeLane];\r
+       if (t == INITIAL || isBoundary(t))\r
+               t = EMPTY;\r
+       else\r
+               t = NOT_ACTIVE;\r
+\r
+       int idx = findNextSha(sha, 0); // find first sha\r
+       if (idx != -1)\r
+               typeVec[idx] = ACTIVE; // called before setBoundary()\r
+       else\r
+               idx = add(BRANCH, sha, activeLane); // new branch\r
+\r
+       activeLane = idx;\r
+}\r
+\r
+void Lanes::afterMerge() {\r
+\r
+       if (boundary)\r
+               return; // will be reset by changeActiveLane()\r
+\r
+       for (unsigned int i = 0; i < typeVec.size(); i++) {\r
+\r
+               int& t = typeVec[i];\r
+\r
+               if (isHead(t) || isJoin(t) || t == CROSS)\r
+                       t = NOT_ACTIVE;\r
+\r
+               else if (t == CROSS_EMPTY)\r
+                       t = EMPTY;\r
+\r
+               else if (IS_NODE(t))\r
+                       t = ACTIVE;\r
+       }\r
+}\r
+\r
+void Lanes::afterFork() {\r
+\r
+       for (unsigned int i = 0; i < typeVec.size(); i++) {\r
+\r
+               int& t = typeVec[i];\r
+\r
+               if (t == CROSS)\r
+                       t = NOT_ACTIVE;\r
+\r
+               else if (isTail(t) || t == CROSS_EMPTY)\r
+                       t = EMPTY;\r
+\r
+               if (!boundary && IS_NODE(t))\r
+                       t = ACTIVE; // boundary will be reset by changeActiveLane()\r
+       }\r
+       while (typeVec.back() == EMPTY) {\r
+               typeVec.pop_back();\r
+               nextShaVec.pop_back();\r
+       }\r
+}\r
+\r
+bool Lanes::isBranch() {\r
+\r
+       return (typeVec[activeLane] == BRANCH);\r
+}\r
+\r
+void Lanes::afterBranch() {\r
+\r
+       typeVec[activeLane] = ACTIVE; // TODO test with boundaries\r
+}\r
+\r
+void Lanes::afterApplied() {\r
+\r
+       typeVec[activeLane] = ACTIVE; // TODO test with boundaries\r
+}\r
+\r
+void Lanes::nextParent(const QString& sha) {\r
+\r
+       nextShaVec[activeLane] = (boundary ? QString(_T("")) : sha);\r
+}\r
+\r
+int Lanes::findNextSha(const QString& next, int pos) {\r
+\r
+       for (unsigned int i = pos; i < nextShaVec.size(); i++)\r
+               if (nextShaVec[i] == next)\r
+                       return i;\r
+       return -1;\r
+}\r
+\r
+int Lanes::findType(int type, int pos) {\r
+\r
+       for (unsigned int i = pos; i < typeVec.size(); i++)\r
+               if (typeVec[i] == type)\r
+                       return i;\r
+       return -1;\r
+}\r
+\r
+int Lanes::add(int type, const QString& next, int pos) {\r
+\r
+       // first check empty lanes starting from pos\r
+       if (pos < (int)typeVec.size()) {\r
+               pos = findType(EMPTY, pos);\r
+               if (pos != -1) {\r
+                       typeVec[pos] = type;\r
+                       nextShaVec[pos] = next;\r
+                       return pos;\r
+               }\r
+       }\r
+       // if all lanes are occupied add a new lane\r
+       typeVec.push_back(type);\r
+       nextShaVec.push_back(next);\r
+       return typeVec.size() - 1;\r
+}\r