原文地址:http://www.ruanyifeng.com/blog/2015/09/git-bitmap.html

使用 Github 的时候,你有没有见过下面的提示?


$ git clone https://github.com/torvalds/linux
Cloning into 'linux'...
remote: Counting objects: 4350078, done.
remote: Compressing objects: 100% (4677/4677), done.
Receiving objects:   4% (191786/4350078), 78.19 MiB | 8.70 MiB/s

这段提示说,远程代码库一共有4350078个对象需要克隆。

这就叫"清点对象"(counting objects),Github需要实时计算出来,需要克隆的对象总数。

这个过程非常慢,根据Github的披露,像Linux kernel这样巨大的库,清点一次需要8分钟!也就是说,发出git clone命令后,会干等八分钟,然后才会开始真正的数据传输。这当然是无法忍受的。Github团队一直想解决这个问题。

后来,他们终于发现了一种新的算法,现在清点一次只要3毫秒!

为了理解这个算法,你必须先知道,什么是Git的对象。简单说,对象就是文件,最重要的对象有三种。

  • 快照对象(Commit)
  • 目录对象(Directory)
  • 文件对象(File)

每次提交代码的时候,会生成一个commit对象,里面有对应的当前"目录对象"的名字。"目录对象"保存了代码根目录所含有的子目录和文件信息。每一个子目录就是另一个"目录对象",每一个文件则是"文件对象",里面是具体的文件内容。

所以,"清点对象"就是清点各种commit、目录、文件等。git clonegit fetch操作都需要清点对象,因为需要知道,到底下载哪些对象文件。

清点对象的原始算法如下。

  1. 列出本地所有分支最新的一个commit
  2. 列出远程所有分支最新的一个commit
  3. 两者进行比较,只要有不同,就意味着分支发生变动
  4. 每一个发生变动的commit,都清点其中具体变动的子目录和文件
  5. 追溯到当前commit的父节点,重复第四步,直至本地与远程的历史一致为止
  6. 加总所有需要变动的对象

上面的过程说明,"清点对象"是一个文件遍历算法,变动的对象会被一一清点到,这就意味着大量的文件读操作。对于大型代码库来说,这个过程非常慢。

Github团队想到的新算法,是建立一个Bitmap索引,即为每一个commit生成一个二进制值。

打开本地Github仓库的.git/objects/pack/目录,你会看到一个索引文件和一个数据文件,它们就是Bitmap。简单说,这两个文件索引了当前代码库的所有对象,然后使用一个二进制值代表这些对象。有多少个对象,这个二进制值就有多少位。它的第n位,就代表数据文件里面的第n个对象。

每个commit都会有一个对应的二进制值,表示当前快照包含的所有对象。这些对象对应的二进制位都为1,其他二进制位都为0。

这样做的好处是,不用读取commit对象,只要读取这个二进制值,就会知道当前commit包含了哪些节点。更妙的是,两个二进制值只要做一次XOR运算,就会知道哪些位(即哪些对象)发生了变动。而且,因为新的对象总是添加到现有二进制位的后面,所以只要读取多出来的那些位,就知道当前commit比上一次commit多出了哪些对象。

这样一来,"清点对象"就变成了二进制值的比较运算,因此速度极快。进一步的介绍,请参看官方文档《Bitmap的解释》,《Bitmap的格式》。

目前,Github的生产环境已经部署了这套算法,用户再也不用为了清点对象,而苦苦等待了。而且,Github团队还把它合并进了Git,这意味着,从此所有Git实现都可以使用Bitmap功能了,因此将来肯定还会有更多好玩的用法出现。

(完)

Github 的清点对象算法相关推荐

  1. labuladong的算法小抄pdf_真漂亮!这份GitHub上爆火的算法面试笔记,助你圆满大厂梦...

    前言 Github作为程序员们的后花园,一直以来都是程序员最喜欢逛逛.学习的地方,小编也不例外,最近看到一份对标BAT等一线大厂的算法面试笔记,已经标星68+K了,很是惊讶,看了一下,觉得知识点整理得 ...

  2. 搬砖试金石!github星标7W算法刷题宝典,还愁拿不下大厂offer?

    前言 这几年IT技术蓬勃发展,日新月异,对技术人才的需求日益增长,程序员招聘市场也如火如荼.在有限的三五轮面试中,国外流行让面试者编程解决某些数据结构和算法的题目,通过观察面试者编码的熟练程度.思考的 ...

  3. 《github一天一道算法题》:并归排序

    看书.思考.写代码! /******************************************** copyright@hustyangju* blog: http://blog.csd ...

  4. 《github一天一道算法题》:分治法求数组最大连续子序列和

    看书.思考.写代码. /**************************************** copyright@hustyangju * blog: http://blog.csdn.n ...

  5. 《github一天一道算法题》:插入排序

    看书.思考.写代码! /*********************************************** * copyright@hustyangju * blog: http://bl ...

  6. 【南梦宫】预设性背景跟随对象算法

    public static float WIDTH = 4.0f;//一个背景的宽度     public static int MODEL_NUM = 3;//背景个数     private Ve ...

  7. JVM自动内存管理:对象判定和回收算法

    可回收对象的判断方法 1.引用计数算法 2.可达性分析算法 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是 ...

  8. GitHub超4.4k星:程序员求职,一个算法模板就够了

    来源:新智元 本文约1800字,建议阅读5分钟 本文为你介绍程序员求职中科学的.高效的刷题方式. [ 导读 ] 近日,GitHub上一个名为"算法模板"的项目引发热议,获得了超4. ...

  9. Github标星57k+,热榜第一,用Python实现所有算法

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 学会了Python基础知识,想进阶一下,那就来点算法吧!毕竟编程语言只是工具,结构 ...

最新文章

  1. SSL/TLSV1.0 programe in linux
  2. 亿级商城促销系统架构设计与实践
  3. 系统时间大全,待整理
  4. C#网络编程(基本概念和操作) - Part.1
  5. echarts formatter_vue使用echarts的方法
  6. php opcache 详解
  7. 换肤的css,换肤功能,css文件中准备三套颜色
  8. SQL实战之获取所有部门当前manager当前的薪水
  9. Emacs基本操作说明
  10. Python开发者必知的13个Python GUI库
  11. Python爬虫入门教程 29-100 手机APP数据抓取 pyspider
  12. linux go missing git command,go: missing Git command的解决办法
  13. 直播APP源码,视频直播技术篇 。
  14. C# PGM格式图像与BMP格式图像相互转换
  15. PDF预览、支持ie、谷歌等主流浏览器
  16. win7 svchost.exe占用内存和CPU很高,电脑很卡的解决方法
  17. 51单片机入门学习小结(流水灯与数码管)
  18. 桥式整流电路原理;电感滤波原理;电容滤波原理
  19. 炸金花游戏功能的实现(发牌,计算牌型,比牌)——python2.7
  20. 计算机顶级会议培训,计算机视觉顶级会议ICCV 2017 腾讯优图入选12篇论文

热门文章

  1. pg_config executable not found
  2. 最大池化层和平均池化层图解
  3. CentOS下面ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
  4. c++调用cplex求解例子_Java调用cplex求解运输问题
  5. linux下watch常见用法,watch命令详解(linux)
  6. oracle 数据导入 数据和备注(comment)乱码问题解决办法
  7. 面试高频问题:HashMap实现原理
  8. Java 比特币开发系列教程汇总
  9. 知道自己想要什么,保持自己的节奏。
  10. Hibernate- QBC-基本查询