天天看點

批量同步Gerrit Change的先後邏輯算法

做某個項目,會将開發提供的一堆gerrit change同步下來後,自動編譯。

但一組gerrit change可能由于dependon的問題,合理同步順序不一定是開發的送出順序。比如,存在送出 1 和送出 2,送出1依賴于送出2,那麼,合理的下載下傳順序是,先下載下傳送出2,再下載下傳送出1。

那如果開發需要編譯的送出有十幾個,怎麼計算?

一開始的想法,這就是一個有向圖,每個送出就是一個節點,而送出之前的依賴關系就是連接配接。當然,有可能這幾個提互動相都沒有關系,那就可以虛拟一個root。然後通過深度優先周遊得到正确的順序。

感覺以上想法,代碼量有點多,同時,需求上其實并不在意同級的送出誰先誰後,隻在意dependon的送出先被同步,于是,通過類似動态規劃的想法,設計出如下算法:

思路:對于一組開發的送出,可以分成兩組,一組a是可以認為是不安全的,另一組b認為是安全的,即同步的順序是确定。隻要不斷地确定b的集合,就能得出相應的隊列。

舉例:開發有送出1,2, 3, 4

其中,1依賴于2和3,2依賴于4, 3依賴于4, 4不依賴任何送出

1. 初始集合 seta = {1,2,3,4}

2. 得出初始數組的依賴集合 setb = {2,3,4}

3. seta – setb,得出 {1},入清單[1]

4. seta & setb = {2,3,4},将其設為新的seta

5. 得到新的setb = {4}

6. seta – setb,得出 {2,3},入清單得到[2,3,1] (注,新的需要放在頭上,當然,放成[3,2,1]也可以,因為認為2與3是等價的)

7. seta & setb = {4},将其設為新的seta

8. setb為空

9. seta – setb,得出 {4},入清單得到[4,2,3,1]

由于setb為空,跳出循環

實際使用中,這個算法能處理循環依賴問題,也就是如果存在seta為空的時候,就說明出現了循環依賴。同時,也能處理依賴的送出并不在使用者送出的送出清單的情況,如,送出4依賴于送出5。由于采用了集合的運算,能很快将這些噪音過濾掉。

附上python代碼,其中self.getdependsonarray(list(setgerrit))是擷取送出的依賴送出集合,另,一開始設計的時候,想用stack來處理得到的safe送出,實作的時候,覺得用list比較友善,就用list來處理了。

代碼是以前寫的,存在大量對pep8規範的違反,請主動忽略