这个项目是作为一个内部项目的概念验证开始的,它需要将P4仓库转换为Git仓库。Git内部也有一个类似的解决方案,叫做git-p4.py。然而,它在处理任何超过1GB大小的仓库时有性能问题,而且它使用Python2在单线程中运行,这给git-p4.py在更大的使用场景中的使用增加了一系列限制。
该工具通过以下方式解决了git-p4.py中一些最有影响的扩展和性能限制:使用HelixCoreC++API来处理下载CL,从而更好地控制内存以及如何将其提交到Git存储库,而无需进行不必要的内存复制和文件I/O。使用libgit2将从Perforce服务器接收到的文件内容按原样转发到Git存储库,同时尽可能避免内存复制。该库允许从内存中简单存在的文件内容创建提交。使用在C++11中实现的自定义基于唤醒的线程池,该线程池运行HelixCoreC++API的线程本地库上下文,以对变更列表下载过程进行大量多线程处理。值得注意的是,P4Fusion 的速度快到足以在你的Perforce服务器上瞬间产生巨大的负载(如果以中等数量的线程运行,在几分钟内超过15万个请求)。因此,它需要仔细监测以确保Perforce服务器不受影响。这个工具将继续产生负载,没有任何速率限制(除了这个工具提供的运行时选项外),直到转换过程完成。然而,没有速率限制,用几百个网络线程(如果可能的话,甚至更多)来运行这个工具,是在转换过程中实现最大速度的理想情况。
网络线程的数量应设置为一般多于逻辑CPU的数量,因为最耗时的步骤是下载CL数据,这主要是网络I/O的限制。
官方研究表明,这个工具的运行速度比git-p4.py快100倍以上。在一个包含约3393个中等规模变更列表的仓库路径内,使用200个并行连接进行历史转换的平均时间为26秒,而git-p4.py转换同一仓库路径需要接近42分钟。如果Perforce服务器有完整的文件缓存,那么这些转换时间可能是可重复的,否则如果文件缓存是空的,那么前几次运行预计会花费更多时间。
对于更大的仓库(数百万个CL或更多),这些执行时间预计会按预期扩展。该工具提供了在转换过程中控制内存利用率的选项,因此这些选项将有助于更大的用例。
❯./build/p4-fusion/p4-fusion[PRINT@Main:24]Runningp4-fusionfrom:./build/p4-fusion/p4-fusion[PRINT@Main:43]Usage:[Required]--portSpecifywhichP4PORTtouse.[Required]--pathP4depotpathtoconverttoaGitrepo[Required]--lookAheadHowmanyCLsinthefuture,atmost,shallwekeepdownloadedbythetimeitistocommitthem?[Required]--srcLocalrelativesourcepathwithP4code.Gitrepowillbecreatedatthispath.Thispathshouldbeemptybeforerunningp4-fusion.[Required]--clientName/pathoftheclientworkspacespecification.[Required]--userSpecifywhichP4USERtouse.Pleaseensurethattheuserisloggedin.[Optional,Defaultisfalse]--includeBinariesDonotdiscardbinaryfileswhiledownloadingchangelists.[Optional,Defaultisfalse]--fsyncEnableEnablefsync()whilewritingobjectstodisktoensuretheygetwrittentopermanentstorageimmediatelyinsteadofbeingcached.Thisistomitigatedatalossineventsofhardwarefailure.[Optional,Defaultis10]--retriesSpecifyhowmanytimesacommandshouldberetriedbeforetheprocessexitsinafailure.[Optional,Defaultis16]--networkThreadsSpecifythenumberofthreadsinthethreadpoolforrunningnetworkcalls.DefaultstothenumberoflogicalCPUs.[Optional,Defaultis-1]--maxChangesSpecifythemaxnumberofchangelistswhichshouldbeprocessedinasinglerun.-1signifiesunlimitedrange.[Optional,Defaultis1]--printBatchSpecifythep4printbatchsize.[Optional,Defaultis100]--refreshSpecifyhowmanytimesaconnectionshouldbereusedbeforeitisrefreshed.
评论