<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8477590467225772179</id><updated>2026-03-26T17:39:15.828-07:00</updated><category term="Engineering Tools Blog"/><title type='text'>Google Engineering Tools</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ewood</name><uri>http://www.blogger.com/profile/12341551220176883769</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-7272922924710185337</id><published>2011-12-14T12:03:00.000-08:00</published><updated>2020-07-15T10:38:18.257-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Bug Prediction at Google</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;b id=&quot;internal-source-marker_0.47983512678183615&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;What&#39;s the problem?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Here at Google, we have thousands of engineers working on our code base every day. In fact, as &lt;/span&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Development-at-Google&quot;&gt;&lt;span style=&quot;color: #000099; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;previously noted&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;, 50% of the Google code base changes every month. That’s a lot of code and a lot of people. In order to ensure that our code base stays healthy, Google primarily employs unit testing and code review for all new check-ins. When a piece of code is ready for submission, not only should all the current tests pass, but new tests should also be written for any new functionality. Once the tests are green, the code reviewer swoops in to make sure that the code is doing what it is supposed to, and stamps the legendary “LGTM” (Looks Good To Me) on the submission, and the code can be checked in.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;However, Googlers work every day on increasingly more complex problems, providing the features and availability that our users depend on. Some of these problems are necessarily difficult to grapple with, leading to code that is unavoidably difficult. Sometimes, that code works very well, and is deployed without incident. Other times, the code creates issues again and again, as developers try to wrestle with the problem. For the sake of this article, we&#39;ll call this second class of code “hot spots”. Perhaps a hot spot is resistant to unit testing, or maybe a very specific set of conditions can lead the code to fail. Usually, our diligent, experienced, and fearless code reviewers are able to spot any issues and resolve them. That said, we&#39;re all human, and sneaky bugs are still able to creep in. We found that it can be difficult to realize when someone is changing a hot spot versus generally harmless code. Additionally, as Google&#39;s code base and teams increase in size, it becomes more unlikely that the submitter and reviewer will even be aware that they&#39;re changing a hot spot.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In order to help identify these hot spots and warn developers, we looked at &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;bug prediction&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;. Bug prediction uses machine-learning and statistical analysis to try to guess whether a piece of code is potentially buggy or not, usually within some confidence range. Source-based metrics that could be used for prediction are how many lines of code, how many dependencies are required and whether those dependencies are cyclic. These can work well, but these metrics are going to flag our necessarily difficult, but otherwise innocuous code, as well as our hot spots. We&#39;re only worried about our hot spots, so how do we only find them? Well, we actually have a great, authoritative record of where code has been requiring fixes: our bug tracker and our source control commit log! The research (for example, &lt;/span&gt;&lt;a href=&quot;http://scholar.google.com/scholar?cluster=338532016657424558&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;color: #000099; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;FixCache&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;) indicates that predicting bugs from the &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;source history&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; works very well, so we decided to deploy it at Google.&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b id=&quot;internal-source-marker_0.47983512678183615&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;How it works&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In the literature, &lt;/span&gt;&lt;a href=&quot;http://scholar.google.com/scholar?q=Bug+Cache+for+inspections%3A+hit+or+miss%3F&quot;&gt;&lt;span style=&quot;color: #000099; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Rahman et al.&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; found that a very cheap algorithm actually performs almost as well as some very expensive bug-prediction algorithms. They found that simply ranking files by the number of times they&#39;ve been changed with a &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;bug-fixing commit &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;(i.e. a commit which fixes a bug) will find the hot spots in a code base. Simple! This matches our intuition: if a file keeps requiring bug-fixes, it must be a hot spot because developers are clearly struggling with it.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Aside from the speed of execution, this algorithm is also very attractive as it&#39;s easy to communicate to others: files are flagged if they have attracted a large number of bug-fixing commits, no more and no less. Some bug prediction algorithms use a large number of metrics and perform many calculations before they output a result, but how do we know it&#39;s not a false positive? We don&#39;t! Once developers start feeling a tool is lying to them, they&#39;ll quickly stop using it. With the Rahman algorithm, whether a developer agrees with the prediction or not is up for debate, but no one can argue with the actual number it outputs.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;We implemented the Rahman algorithm by creating a program that hooked into our source control system, and pulls out all the changes which had a bug attached to them. It looks at each bug number, and verifies with the bug-tracking database that it was really a bug, and filters out everything else, such as feature requests. It then looks at all the files that appeared in these changes, and filters out those that have been deleted and are no longer at HEAD. For each file, the number of bug-fixing changes it&#39;s been in is calculated, and we output the files which were ranked in the top 10%.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;We showed output to the development teams (you know, just to make sure). The response?&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&quot;Hey guys, this list looks great, but there&#39;s a couple of files that used to be a problem, but we fixed them, so they shouldn&#39;t be on here now.&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;It turns out that while the Rahman algorithm shows us where hot spots are, it doesn&#39;t adapt to changes readily. If a development team manages to nail down a hot spot and get it fixed, it&#39;ll still appear in the list because of all the bug-fixing commits it created in the past.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;What we needed was a way of prioritizing newer bug-fixing commits, and downgrading the value of old ones, so fixed files begin to fall down the list.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;After some trial-and-error, we decided to score each file by weighting each bug-fixing commit by how old it is. As the commit gets older, so its influence tends towards 0.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: Arial;&quot;&gt;&lt;span style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;img height=&quot;34px;&quot; src=&quot;https://lh6.googleusercontent.com/AJBBJJXgQZ4q0PFyrddaLssDM7Dxal2Ls2wb23rvDiQZAj_R2tcGgtb-Dl1s1lhFJPBRAG0vyPC1BOTmrdovMxyHQaoRDJmeXwz2OfXKQLWxu1GfqbE&quot; width=&quot;187px;&quot; /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Where &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;n&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; is the number of bug-fixing commits, and &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 9px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: sub; white-space: pre-wrap;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; is the timestamp of the bug-fixing commit represented by &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;. The timestamp used in the equation is normalized from 0 to 1, where 0 is the earliest point in the code base, and 1 is now (where now is when the algorithm was run). Note that the score changes over time with this algorithm due to the moving normalization; it&#39;s not meant to provide some objective score, only provide a means of comparison between one file and another at any one point in time.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Some of you might wonder why we don&#39;t factor in the number of commits in the algorithm: a file that changes often as it&#39;s being developed will get more bug-fixing commits. Wouldn&#39;t it be fairer to look at the ratio of non-fixing commits to bug-fixing commits? Having trialled this, we found the results unsatisfying. Code churn has previously been pointed at as an indicator of the presence of defects (particularly by &lt;/span&gt;&lt;a href=&quot;http://research.microsoft.com/apps/pubs/default.aspx?id=69126&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;color: #000099; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Nagappan and Ball&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;), so employing a ratio removes that useful signal. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;If we plot our equation, it looks like this:&lt;/span&gt;&lt;b&gt;&lt;img height=&quot;423px;&quot; src=&quot;https://lh5.googleusercontent.com/eS7aZQqoXsjmY5fuNPDSvEJwB0w3EWOjBoQvBsYJlaItzPEFezPirfZVyy1kmxhRHIPVw4DGjpBpiScbDIQ1UgxajyGFvxniTOp8QHQc9vANbNQKWU4&quot; width=&quot;604px;&quot; /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Running using this scoring algorithm means that as commits get older, they are worth less and less. The drop-off happens quickly in order to really push up those newer bug-fixing changes and devalue the older ones. Files that don&#39;t get many bug-fixing commits for a while will end up falling out of the top 10%.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;How we&#39;re using it&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; white-space: pre-wrap;&quot;&gt;When a file is predicted to be a hot spot, we place a warning in our code review system on that file. Whenever a reviewer logs in to review that code, the warning will appear, which hopefully will encourage them to spend some more time reviewing the code, or hand off the review to someone more experienced if need be.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; white-space: pre-wrap;&quot;&gt;Bug prediction is not an objective measure by any means: the attentive amongst you will see it&#39;s another tool that we can provide Googlers with in order to help them gain insight into their code. We hope that by highlighting code hot spots, we&#39;ll help to stop tricky bugs making their way into the code base. We&#39;ll be monitoring how developers are engaging with these reviews in the months to come.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;- Chris Lewis and Rong Ou&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/7272922924710185337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/7272922924710185337?isPopup=true' title='224 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7272922924710185337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7272922924710185337'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/12/bug-prediction-at-google.html' title='Bug Prediction at Google'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh6.googleusercontent.com/AJBBJJXgQZ4q0PFyrddaLssDM7Dxal2Ls2wb23rvDiQZAj_R2tcGgtb-Dl1s1lhFJPBRAG0vyPC1BOTmrdovMxyHQaoRDJmeXwz2OfXKQLWxu1GfqbE=s72-c" height="72" width="72"/><thr:total>224</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-7052565056120367093</id><published>2011-10-27T13:05:00.000-07:00</published><updated>2020-07-15T10:38:18.244-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Build in the Cloud: Distributing Build Outputs</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;This is the fourth in a four part series describing how we use the cloud to scale building and testing of software at Google. This series elaborates on a&lt;/span&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=b52aXZ2yi08&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: #000099; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;presentation&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; given during the&lt;/span&gt;&lt;a href=&quot;http://sites.gtac.biz/gtac2010/&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: #000099; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Pre-GTAC 2010&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; event in Hyderabad. To get a sense of the scale and details on the types of problems we are solving in Engineering Tools at Google take a look at&lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/testing-at-speed-and-scale-of-google.html&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: #000099; font-size: 11pt; font-style: italic; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;this post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent;&quot;&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In the previous post, we saw how distributing build load across many machines and reusing the results of previous build actions can produce extremely fast build times. This distribution and reuse itself exposed other performance bottlenecks. &amp;nbsp;Specifically, a full build of a large project may produce several gigabytes of output files, all of which need to be shipped from the cloud back to the developer’s local machine. This taxes both our networks and the developer’s local disk, the limited latencies and bandwidth of which slow down the build.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Furthermore, a developer typically does not need access to all of the outputs of a build. She may be interested only in the final binary that results from a build, not all of the intermediate object files. Another example is when the developer uses the distributed build system to build and execute a test in the cloud; in this case, she does not need local access to any build outputs at all, but simply an indication that the test passed or failed. It is thus unnecessary and wasteful to always ship all build outputs from the cloud back to the developer’s local machine. Instead, it is sufficient to ship back only those build outputs that are actually accessed by the developer on demand.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;To address these bottlenecks, our distributed build system writes all build outputs that it generates to a persistent, distributed storage system in the cloud. This storage system can handle sustained read and write rates many times those of a local disk, and the network connectivity between the distributed build system and this storage system has significantly lower latency and higher bandwidth than to the developer’s local machine. The build outputs are stored by &lt;/span&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;content fingerprint&lt;/span&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;, providing a straightforward mechanism for indexing and retrieval of the files. (This cloud storage system also serves as a secondary caching layer for the distributed build system, providing an additional performance benefit in instances when build outputs fall out of the primary caching layer.) Using this distributed storage system in the cloud, we are able to make build speeds more than twice as fast as a distributed build that stores all build outputs on the developer’s local disk.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;With cloud-based storage of build outputs providing substantial increases in build times, the remaining challenge is to still make build outputs available to the developer’s local machine, on demand, once the build completes. We achieve this by writing a custom file system to provide a view of the build outputs. Like we described in &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot;&gt;&lt;span style=&quot;background-color: white; color: #000099; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;our first blog post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: white; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;, the &lt;/span&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Filesystem_in_Userspace&quot;&gt;&lt;span style=&quot;background-color: white; color: #009eb8; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;File System in Userspace&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: white; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; (FUSE) kernel module is a convenient way of implementing a user space daemon that implements such a file system. As individual build steps complete, the distributed build system informs the daemon about the creation of new build outputs, providing both a relative file path and a content fingerprint. Then, when the developer accesses one of the files on these paths, the daemon downloads the file from the cloud, using the content fingerprint as the key, and serves it via FUSE to the developer (caching downloaded files on the developer’s machine to speed up subsequent accesses). The content fingerprint itself is also made available to the build system as an extended attribute via the FUSE layer, which, as we indicated in &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html&quot;&gt;&lt;span style=&quot;background-color: white; color: #000099; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;our second blog post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: white; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;, is necessary for the build system to perform incremental builds.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In addition to serving build outputs from the cloud and build output metadata from the local machine, the local daemon performs many additional tasks important for the functionality of the system. For example, build outputs are kept in the cloud only as long as they are referenced by at least one developer’s local machine. The daemon periodically extends leases for all build outputs present in any build on a developer’s workstation. As another example, the performance of the virtual file system would be dismal if large build outputs were fetched sequentially once they were requested by the developer; instead, the daemon downloads chunks of the file in parallel from multiple storage servers in the cloud. The daemon is also responsible for local data integrity checks, local disk management and data eviction, and many other maintenance tasks.&lt;/span&gt;&lt;span style=&quot;background-color: transparent; font-size: 12pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;The picture below summarizes how Google’s build system works as a whole, taking into account the four blog posts in this series:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZoKDd7euUrEj2vlf4lu9A5KQDm-lCzw7LOPTaC0cyGpE0HtNeQN9AWJhoRFUDHoPZlwglZ_0KFkBBCEHZEAO7oMuHC55vR8z70WpyI0k7FB3uuUumyTw5dQWkMMpQUzoZC334kSfYRns/s1600/BuildintheCloudPart4DistributingBuildOutputs+%25282%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;480&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZoKDd7euUrEj2vlf4lu9A5KQDm-lCzw7LOPTaC0cyGpE0HtNeQN9AWJhoRFUDHoPZlwglZ_0KFkBBCEHZEAO7oMuHC55vR8z70WpyI0k7FB3uuUumyTw5dQWkMMpQUzoZC334kSfYRns/s640/BuildintheCloudPart4DistributingBuildOutputs+%25282%2529.png&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; font-family: inherit; font-size: 15px; white-space: pre-wrap;&quot;&gt;The developer invokes the build system client on her workstation, specifying one or more targets to build. The client then coordinates and dispatches individual build actions to execute in the cloud, reading the necessary source code metadata from the FUSE daemon to provide as input to the cloud execution system. The build outputs of these actions (such as binaries) are then stored in our cloud storage system, and downloaded on demand by the user through FUSE daemon. The end result of this is a build system that can deliver build results to developers on the order of seconds or minutes, as opposed to hours.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: transparent;&quot;&gt;
&lt;span style=&quot;background-color: white; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; font-size: 11pt; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;This concludes our four-part series of blog posts describing how we use the cloud to scale building at Google. In this series, we covered cloud-based source control, how our build system works, and how we distribute both build actions and build outputs to the cloud. We encourage readers to comment on these posts, and to comment on any additional topics they would like to see covered in this blog.&lt;/span&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; font-family: inherit; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;- Milos Besta, Yevgeniy Miretskiy and Jeff Cox&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/7052565056120367093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/7052565056120367093?isPopup=true' title='57 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7052565056120367093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7052565056120367093'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/10/build-in-cloud-distributing-build.html' title='Build in the Cloud: Distributing Build Outputs'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZoKDd7euUrEj2vlf4lu9A5KQDm-lCzw7LOPTaC0cyGpE0HtNeQN9AWJhoRFUDHoPZlwglZ_0KFkBBCEHZEAO7oMuHC55vR8z70WpyI0k7FB3uuUumyTw5dQWkMMpQUzoZC334kSfYRns/s72-c/BuildintheCloudPart4DistributingBuildOutputs+%25282%2529.png" height="72" width="72"/><thr:total>57</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-4887963294021386329</id><published>2011-09-27T15:09:00.000-07:00</published><updated>2020-07-15T10:38:18.182-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Trying on the new Dynamic Views from Blogger</title><content type='html'>As you may have noticed, the Engineering Tools blog looks a lot different today. That’s because we—along with a few other Google blogs—are trying out a new set of &lt;a href=&quot;http://www.blogger.com/&quot;&gt;Blogger&lt;/a&gt; templates called Dynamic Views.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://buzz.blogger.com/2011/09/dynamic-views-seven-new-ways-to-share.html&quot;&gt;Launched today&lt;/a&gt;, Dynamic Views is a unique browsing experience that makes it easier and faster for readers to explore blogs in interactive ways. We’re using the Classic view, but you can also preview this blog in any of the other six new views by using the view selection bar at the top left of the screen.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;284&quot; src=&quot;http://www.youtube.com/embed/lpDQF2lFnBU&quot; width=&quot;500&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
We’re eager to hear what you think about the new Dynamic Views. You can submit feedback using the “Send feedback” link on the bottom right of this page, or just &lt;a href=&quot;mailto:google-engtools@google.com&quot;&gt;send us an email&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
If you like what you see here, and we hope you do, we encourage you to try out the new look(s) on your own blog—read the &lt;a href=&quot;http://buzz.blogger.com/2011/09/dynamic-views-seven-new-ways-to-share.html&quot;&gt;Blogger Buzz post&lt;/a&gt;&amp;nbsp;for more info.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;post-author&quot;&gt;Posted by John Thomas, Tech lEad&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/4887963294021386329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/4887963294021386329?isPopup=true' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/4887963294021386329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/4887963294021386329'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/09/trying-on-new-dynamic-views-from.html' title='Trying on the new Dynamic Views from Blogger'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/lpDQF2lFnBU/default.jpg" height="72" width="72"/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-7475523687360657477</id><published>2011-09-22T15:32:00.000-07:00</published><updated>2020-07-15T10:38:18.270-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Build in the Cloud: Distributing Build Steps</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;i&gt;This is the third in a four part series describing how we use the cloud to scale building and testing of software at Google. This series elaborates on a &lt;a href=&quot;http://www.youtube.com/watch?v=b52aXZ2yi08&quot;&gt;presentation&lt;/a&gt; given during the &lt;a href=&quot;http://sites.gtac.biz/gtac2010/&quot;&gt;Pre-GTAC 2010&lt;/a&gt; event in Hyderabad. Please see our &lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot;&gt;first post&lt;/a&gt; in the series for a description how we access our code repository in a scalable way. To get a sense of the scale and details on the types of problems we are solving in Engineering Tools at Google take a look at &lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/testing-at-speed-and-scale-of-google.html&quot;&gt;this post&lt;/a&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
The two previous posts described a custom file system for providing access to source code hosted in the cloud, and how the build system works. This post builds on these to describe a system for efficiently distributing build steps across a large number of machines. As you will see, details of the source file system and the build system are important to how we achieve fast and efficient distributed builds. So before we get into the mechanics of how build steps are distributed, it is helpful to call attention to a few points.&lt;br /&gt;
&lt;br /&gt;
First, the build system is &lt;b&gt;content-based&lt;/b&gt; where the internal bookkeeping for inputs and outputs is based on content digest, not file and timestamp (as in Make). This means that content equality is determined by comparing content digests, and these digests are tracked internally by the build system as it builds and operates on the action graph. Computing content digests for builds with a large amount of source code could be expensive because of the time spent reading files. We avoid this problem by computing and storing digests as content is checked in, and then providing digests directly to the build system as &lt;a href=&quot;http://en.wikipedia.org/wiki/Extended_file_attributes&quot;&gt;extended attributes&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Second, the build system reads BUILD files to construct a graph of dependencies, and then uses the dependency graph to construct a graph of &lt;b&gt;build actions&lt;/b&gt; or build steps. The graph is constructed by using the outputs of actions as inputs to other actions. Dependencies are expected to be completely specified and there is no dynamic dependency detection. The combination of content digests along with completely specified dependencies means that actions can be expressed as functions. In this &lt;b&gt;functional model&lt;/b&gt;, the function inputs are the content digests and the environment (environment variables, command line options), the function is the tool or script which transforms inputs, and the outputs are the function results. These functional build actions are atomic units of work, and the transformation of inputs to outputs is opaque to the system. This means that build actions are language and tool agnostic and, among other things, may compile a C++ translation unit, compile Java files, link a binary, or even run a unit test.&lt;br /&gt;
&lt;br /&gt;
An example of the action graph. Outputs of actions, such as &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;search.o&lt;/span&gt; from from the &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;CC&lt;/span&gt; action, become inputs to other actions (&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;LD&lt;/span&gt; in this case).&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2GXwFM78ncFQht55I1pxG44LlX6TEOURSRS_8Kwp3dAIl8TAuLOMTWMJzXT3us1Vtp436YKOjjip24RYRta_Qzkk1tLyf73yF0Th0BxlyucN5g4Nl_8LxFzXXVTn9oEydailGwkWdQLY/s1600/BuildintheCloudPart2HowtheBuildSystemworks+%25281%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2GXwFM78ncFQht55I1pxG44LlX6TEOURSRS_8Kwp3dAIl8TAuLOMTWMJzXT3us1Vtp436YKOjjip24RYRta_Qzkk1tLyf73yF0Th0BxlyucN5g4Nl_8LxFzXXVTn9oEydailGwkWdQLY/s320/BuildintheCloudPart2HowtheBuildSystemworks+%25281%2529.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Third, we require that every build action is a function of only its declared inputs. This means that if we would execute the &lt;b&gt;same&lt;/b&gt; action with the &lt;b&gt;same&lt;/b&gt; input again we would get &lt;b&gt;bit-identical&lt;/b&gt; output. This guarantees that not re-executing an action because the input files have the same content as in a previous build will not change the build results. This sounds like a reasonable requirement, but in practice an action may depend on things other than the declared input files, such as the contents of system header files or even the time of day (consider the __DATE__ macro expanded by the C preprocessor, or the timestamps embedded in every jar file). We address these problems by configuring our tools to make actions &lt;b&gt;hermetic&lt;/b&gt; and post-processing some file types to overwrite timestamps.&lt;br /&gt;
&lt;br /&gt;
Now let’s continue with details of how we use these functional actions to distribute the build.&lt;br /&gt;
&lt;br /&gt;
As self-contained, atomic units of work, build actions are &lt;b&gt;portable&lt;/b&gt; in that they can be sent to other machines, along with the inputs, for remote execution. This is useful at Google because we happen to have a lot of machines in data centers, which means we can distribute execution of build actions across thousands of workers. In this model all actions can be distributed, and the parallelism of the build is limited only by the width of the action graph.&lt;br /&gt;
&lt;br /&gt;
Distributing actions across lots of workers makes the build fast, but we also found that workers duplicated a lot of work since many engineers build the same code. The functional nature of build actions, where the same inputs alway produce bit-identical outputs, means that we can easily and correctly cache and reuse results. We construct a cache key by computing a digest from the entire request (the command line and inputs), so it is not possible to “leave out” something and get incorrect cache hits. Remember that input files are described by content digest, so computing the cache key is relatively cheap, even for a large amount of content. When an action is ready for remote execution, we first compute the cache key. In case of a cache miss, the action is executed on a worker and the result is cached as it is returned to the user. In case of a cache hit, we simply return the cached result. &amp;nbsp;To maintain the illusion that a cached action is actually executed, we also cache and replay the stdout+stderr of the action.&lt;br /&gt;
&lt;br /&gt;
As changes are submitted to the code base, the first build to encounter each change waits a bit longer on actions affected by the code change because these need to be re-executed, but because build actions are distributed the difference is not very noticeable. In many cases, such as whitespace or comment changes in C++, different inputs still produce bit-identical output. Because the build system is content-based, this situation will then produce cache hits for subsequent actions, which provides another form of build avoidance. The end result is a &lt;b&gt;greater than 90% cache hit rate&lt;/b&gt; overall. This means that even “clean” rebuilds are mostly reusing work done for previous builds, resulting in extremely fast build times. Another way to think of this is that each change to the code base results in an on-demand binary release of every library and executable affected by the change.&lt;br /&gt;
&lt;br /&gt;
Distributing build load across many machines and reusing build actions have been so successful in speeding up builds that we inadvertently created another issue. &amp;nbsp;A clean build of a large project may produce several gigabytes of output, and since these builds typically take less than a few minutes and we do tens of thousands of builds per day, the volume of data produced by the distributed build resulted in considerable load on our networks and local disk I/O. Our next and final post in this series will describe how we solved this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Stay tuned! In this post we explained how builds are distributed and cached to make the build fast and efficient. Part four in this series describes how we solved the problem of dealing with the large amount of data produced by doing many builds very quickly.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;
- Nathan York&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/7475523687360657477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/7475523687360657477?isPopup=true' title='64 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7475523687360657477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7475523687360657477'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/09/build-in-cloud-distributing-build-steps.html' title='Build in the Cloud: Distributing Build Steps'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2GXwFM78ncFQht55I1pxG44LlX6TEOURSRS_8Kwp3dAIl8TAuLOMTWMJzXT3us1Vtp436YKOjjip24RYRta_Qzkk1tLyf73yF0Th0BxlyucN5g4Nl_8LxFzXXVTn9oEydailGwkWdQLY/s72-c/BuildintheCloudPart2HowtheBuildSystemworks+%25281%2529.png" height="72" width="72"/><thr:total>64</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-6019422688106148564</id><published>2011-08-18T02:44:00.000-07:00</published><updated>2020-07-15T10:38:18.195-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Build in the Cloud: How the Build System works</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Times New Roman&#39;; &quot; &gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;This is the second in a four part series describing how we use the cloud to scale building and testing of software at Google. This series elaborates on a&lt;/span&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=b52aXZ2yi08&quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;presentation&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; given during the&lt;/span&gt;&lt;a href=&quot;http://sites.gtac.biz/gtac2010/&quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Pre-GTAC 2010&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; event in Hyderabad. Please see our&lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; first post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; in the series for a description how we access our code repository in a scalable way. To get a sense of the scale and details on the types of problems we are solving in Engineering Tools at Google take a look at &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/testing-at-speed-and-scale-of-google.html&quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;this post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;As you have learned in the &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot; style=&quot;font-family: &#39;Times New Roman&#39;; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;previous post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;, at Google every product is constantly building from head. In this article we will go into a little more detail in how we tell the build system about the source code and its dependencies. In a later article we will explain how we take advantage of having this exact knowledge to distribute the builds at Google across a large cluster of machines and share build results between developers.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;From some of the feedback we got for our first posts it is clear that you want to see how we actually go about describing the dependencies we use to drive our build and test support.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;At Google we partition our source code into smaller entities that we call &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;packages&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. You can think of a package as a directory containing a number of source files and a description of how these source files should get translated into build outputs. The files describing that are all called &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;BUILD&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; and the existence of a &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;BUILD&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; file in a directory makes that directory into a package.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;All packages reside in a single file tree and the relative path from the root of that tree to the directory containing the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;BUILD&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; file is used as a globally unique identifier for the package. This means that there is a 1:1 relationship between package names and directory names.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Within a &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;BUILD&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; file we have a number of named &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; describing the build outputs of the package. The combination of package name and rule name uniquely identifies the rule. We call this combination a &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;label&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; and we use labels to describe dependencies across rules.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Let’s look at an example to make this a little more concrete:&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;root&gt;/search/BUILD:&lt;/root&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_binary(name = ‘google_search_page’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;          deps = [ ‘:search’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;                   ‘:show_results’])&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library(name = ‘search’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           srcs = [ ‘search.h’,‘search.cc’],&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           deps = [‘//index:query’])&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;root&gt;/index/BUILD:&lt;/root&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library(name = ‘query’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           srcs = [ ‘query.h’, ‘query.cc’, ‘query_util.cc’],&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           deps = [‘:ranking’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;                   ‘:index’])&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library(name = ‘ranking’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           srcs = [‘ranking.h’, ‘ranking.cc’],&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           deps = [‘:index’, &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;                   ‘//storage/database:query’])&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library(name = ‘index’,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           srcs = [‘index.h’, ‘index.cc’],&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;           deps = [‘//storage/database:query’])&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;This example shows two &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;BUILD&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; files. The first one describes a binary and a library in the package&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; //search&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; and the second one describes several libraries in the package &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;//index&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. All rules are named using the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;name&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; attribute, You can see the dependencies expressed in the &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;deps&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; attribute of each rule. The ‘&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;:&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;’ separates the package name from the name of the rule.  Dependencies on rules in a different package start with a “&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;//&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;” and dependencies on rules in the same package can just omit the package name itself and start with a ‘&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;:&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;’. You can clearly see the dependencies between the rules. If you look carefully you will notice that several rules depend on the same rule &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;//storage/database:query&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;, which means that the dependencies form a directed graph. We require that the graph is acyclic, so that we can create an order in which to build the individual targets.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre-wrap; &quot; &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;div style=&quot;font-family: &#39;Times New Roman&#39;; background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Here is a graphical representation of the dependencies described above:&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzvCnY0_x_KPbsp_cojqyp4_OGe-AgZTGoVRnw5Qxah_ybEv0hBJGnQNPEUhSUwAmhzkhqkEkpxE4UoSogoPmpTYopL76dfeLeaEXwt_30_m99pXHv5p45egTfxfXlTZd7746IkwMsGC0/s1600/BuildintheCloudPart2HowtheBuildSystemworks.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzvCnY0_x_KPbsp_cojqyp4_OGe-AgZTGoVRnw5Qxah_ybEv0hBJGnQNPEUhSUwAmhzkhqkEkpxE4UoSogoPmpTYopL76dfeLeaEXwt_30_m99pXHv5p45egTfxfXlTZd7746IkwMsGC0/s400/BuildintheCloudPart2HowtheBuildSystemworks.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5642155427929257170&quot; style=&quot;cursor: pointer; width: 395px; height: 400px; &quot; /&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre-wrap; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;You can also see that instead of referring to concrete build outputs as typically happens in &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;make&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; based build systems, we refer to abstract entities. In fact a rule like &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; does not necessarily produce any output at all. It is simply a way to logically organize your source files. This has an important advantage that our build system uses to make the build faster. Even though there are dependencies between the different &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;cc_library&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; rules, we have the freedom to compile all of the source files in arbitrary order. All we need to compile &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;‘query.cc’&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; and &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;‘query_util.cc’&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; are the header files of the dependencies &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;‘ranking.h’ &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;and &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;‘index.h’&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. In practice we will compile all these source files at the same time, which is always possible unless there is a dependency on an actual output file of another rule. &lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre-wrap; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;In order to actually perform the build steps necessary we decompose each rule into one or more discrete steps called &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;actions&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. You can think of an action as a command line and a list of the input and output files. Output files of one action can be the input files to another action. That way all the actions in a build form a &lt;/span&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Bipartite_graph&quot; style=&quot;font-family: &#39;Times New Roman&#39;; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;bipartite graph&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; consisting of actions and files. All we have to do to build our target is to walk this graph from the leaves - the source files that do not have an action that produces them - to the root and executing all the actions in that order. This will guarantee that we will always have all the input files to an action in place prior to executing that action.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;An example of the bipartite action graph for a small number of targets. Actions are shown in green and files in yellow color:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWZesQKz84FKFurcRxOklvxzkkyItMzekXQrrTY0D59Ntwi1Hc7R2nryV7_pdFjzJo24ty1TWUpov4kmluyh0bpMyFM4sr0kDu-r_nP2_Mu_xGeRnCzRKessKHUXHEUG71xoJj1b9TkhI/s1600/BuildintheCloudPart2HowtheBuildSystemworks+%25281%2529.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWZesQKz84FKFurcRxOklvxzkkyItMzekXQrrTY0D59Ntwi1Hc7R2nryV7_pdFjzJo24ty1TWUpov4kmluyh0bpMyFM4sr0kDu-r_nP2_Mu_xGeRnCzRKessKHUXHEUG71xoJj1b9TkhI/s400/BuildintheCloudPart2HowtheBuildSystemworks+%25281%2529.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5642155430923073490&quot; style=&quot;cursor: pointer; width: 400px; height: 291px; &quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;We also make sure that the command-line arguments of every action only contain file names using relative paths - using the relative path from the root of our directory hierarchy for source files. This and the fact that we know all input and output files for an action allows us to easily execute any action remotely: we just copy all of the input files to the remote machine, execute the command on that machine and copy the output files back to the user’s machine. We will talk about some of the ways we make remote builds more efficient in a later post.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;All of this is not much different from what happens in &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;make&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. The important difference lies in the fact that we don’t specify the dependencies between rules in terms of files, which gives the build system a much larger degree of freedom to choose the order in which to execute the actions.  The more parallelism we have in a build (i.e. the &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;wider&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; the action graph) the faster we can deliver the end results to the user. At Google we usually build our solutions in a way that can scale simply by adding more machines. If we have a sufficiently large number of machines in our datacenter, the time it takes to perform a build should be dominated only by the &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;height&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; of the action graph.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;What I describe above is how a &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;clean build&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; works at Google. In practice most builds during development will be &lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;incremental&lt;/span&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;. This means that a developer will make changes to a small number of source files in between builds. Building the whole action graph would be wasteful in this case, so we will skip executing an action unless one or more of its input files change compared to the previous build. In order to do that we keep track of the content digest of each input file whenever we execute an action. As we mentioned in the &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot; style=&quot;font-family: &#39;Times New Roman&#39;; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;previous blog post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;, we keep track of the content digest of source files and we use the same content digest to track changes to files. The FUSE filesystem described in the &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html&quot; style=&quot;font-family: &#39;Times New Roman&#39;; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;previous post&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; exposes the digest of each file as an extended attribute. This makes determining the digest of a file very cheap for the build system and allows us to skip executing actions if none of the input files have changed.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Stay tuned! In this post we explained how the build system works and some of the important concepts that allow us to make the build faster. Part three in this series describes how we made remote execution really efficient and how it can be used to improve build times even more!&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: transparent; &quot;&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;- Christian Kemper&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/6019422688106148564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/6019422688106148564?isPopup=true' title='91 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/6019422688106148564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/6019422688106148564'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html' title='Build in the Cloud: How the Build System works'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzvCnY0_x_KPbsp_cojqyp4_OGe-AgZTGoVRnw5Qxah_ybEv0hBJGnQNPEUhSUwAmhzkhqkEkpxE4UoSogoPmpTYopL76dfeLeaEXwt_30_m99pXHv5p45egTfxfXlTZd7746IkwMsGC0/s72-c/BuildintheCloudPart2HowtheBuildSystemworks.png" height="72" width="72"/><thr:total>91</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-7578220560117608733</id><published>2011-07-27T04:24:00.000-07:00</published><updated>2020-07-15T10:38:18.283-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Are SSDs a silver bullet to improve IntelliJ&#39;s indexing performance?</title><content type='html'>[cross post from &lt;a href=&quot;http://inside-intellij.blogspot.com/2010/09/is-there-silver-bullet-to-improve.html&quot;&gt;http://inside-intellij.blogspot.com/2010/09/is-there-silver-bullet-to-improve.html&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;We are the &lt;a href=&quot;http://www.jetbrains.com/idea/&quot;&gt;IntelliJ&lt;/a&gt; IDE team at Google. We develop IntelliJ code (plugins and patches) to provide a seamless integration with Google’s unique build system, and make IntelliJ scale to Google’s huge and &lt;a href=&quot;http://www.infoq.com/presentations/Development-at-Google&quot;&gt;rapidly changing codebase&lt;/a&gt; performance-wise.&lt;br /&gt;&lt;br /&gt;We recently investigated whether using Solid State Devices (SSDs) could improve indexing performance for large projects. We decided to share our analysis and results here for the benefit of our Engineering Tools blog readers.&lt;br /&gt;&lt;br /&gt;First, what do we mean by indexing? IntelliJ, like any IDE, maintains a datastore of source code meta-information that helps autocomplete, hyperlinking in source code, refactoring and a plethora of other features that operate on code. The process of creating this datastore is called ‘indexing’.&lt;br /&gt;&lt;br /&gt;But why do we want to speed up indexing? Indexing occurs whenever a new IntelliJ project is created or source files change outside of IntelliJ (like a source control sync). As you can imagine, these are frequent operations. Now considering the scale and size of projects in a monolithic codebase like Google’s, the changed delta can be large and so it can take a significant amount of time to index. This operation effectively blocks users from using many rich features the IDE has to offer. We want to minimize this block time.&lt;br /&gt;&lt;br /&gt;Why SSDs? Being aware that indexing is I/O intensive, we thought that using faster storage devices could be a silver bullet to improve indexing performance. But when we did some experiments, we learned otherwise.&lt;br /&gt;&lt;br /&gt;SSDs use solid state memory to store data and have no electromechanical parts like a Hard Disk Drive (HDD). They offer lower latencies for data transfer in general. For random accesses read operations SSDs perform 50x-200x times better than typical HDDs, and they perform better than HDDs for sequential reads as well. Though SSD writes are not as fast as reads, write operations on modern SSDs are still faster than typical HDDs.&lt;br /&gt;&lt;br /&gt;Now doing these experiments is one thing, but how to measure results? It would be ideal to determine the total mix of read and write operations performed by IntelliJ process during indexing to compute effective performance benefits. But while there are tools like &lt;a href=&quot;http://linux.die.net/man/8/blktrace&quot;&gt;blktrace&lt;/a&gt; that offer process level drill down of IO operations, it’s not easy for them to track internal file system level optimizations made before disk writes. For example, many write operations will actually be buffered and executed together by pdflush, but IO monitoring tools would actually count those as pdflush process writes only.&lt;br /&gt;&lt;br /&gt;Long story short, we think the most reliable way to measure indexing improvements for now is to actually trigger a build/indexing for sample projects with and without SSDs and measure each case.&lt;br /&gt;&lt;br /&gt;Now on to the fun stuff. Here are some details of the machine we used for sampling:&lt;br /&gt;&lt;br /&gt;CPU: Intel quad core 2.4GHz&lt;br /&gt;SSD: Kingston 128GB&lt;br /&gt;HDD: WDC 500GB 7200RPM SATA-II&lt;br /&gt;RAM: 8 GB DDR2, 800MHz (1.2ns)&lt;br /&gt;JVM - 64-bit OpenJDK&lt;br /&gt;IntelliJ Version - 10.5&lt;br /&gt;File system: ext3&lt;br /&gt;&lt;br /&gt;For the experiments, we chose sample projects that represented the set of projects we’re trying to optimize indexing performance for. We ran these experiments using SSDs in one case and HDDs in the other, keeping everything else constant. These are the results averaged out for 10 runs for one such sample project:&lt;br /&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-family: Times; font-size: medium; &quot;&gt;&lt;table style=&quot;border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; border-collapse: collapse; width: 524px; &quot;&gt;&lt;colgroup&gt;&lt;col width=&quot;157&quot;&gt;&lt;col width=&quot;155&quot;&gt;&lt;col width=&quot;*&quot;&gt;&lt;col width=&quot;*&quot;&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr style=&quot;height: 0px; &quot;&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Storage Device&lt;/span&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Num Files&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Scanning Files to index Time &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;(secs)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Indexing Time &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;(secs)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;height: 0px; &quot;&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;SSD&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;78144&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;24.51&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;128.71&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;height: 0px; &quot;&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;HDD&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;78144&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;15.69&lt;/p&gt;&lt;/td&gt;&lt;td style=&quot;border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(170, 170, 170); border-right-color: rgb(170, 170, 170); border-bottom-color: rgb(170, 170, 170); border-left-color: rgb(170, 170, 170); vertical-align: top; padding-top: 7px; padding-right: 7px; padding-bottom: 7px; padding-left: 7px; &quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;text-align: center; margin-top: 0pt; margin-bottom: 0pt; &quot;&gt;141.1&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;Table 1: &lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Index times of IntelliJ community edition code using SSD, normal hard-disk&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;From our experiments we did not find any significant improvements in indexing time when SSDs were used. While SSDs did offer 25% faster performance in the first run, which is when the source files of interest are not already cached by the file system (like after a reboot), on subsequent indexing operations (the practical case) this advantage reduces sharply. So the cost-benefit of this silver bullet does not really come through for us.&lt;br /&gt;&lt;br /&gt;However this doesn’t mean SSDs can not possibly make things better. We feel there could be greater indexing performance boosts using SSDs if:&lt;ol&gt;&lt;li&gt;The underlying filesystem is highly optimized for SSDs (like ZFS for Solaris)&lt;/li&gt;&lt;li&gt;Number of disk read operations performed is more than number of write operations.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;But some of these requirements are not trivial for us to implement. Till then, we will explore other ideas to improve IntelliJ performance and post any learnings that we feel would benefit our readers and the community. Stay tuned.&lt;br /&gt;&lt;br /&gt;- Chandra Sekhar Pydi, Siddharth Priya, Abhishek Sheopory</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/7578220560117608733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/7578220560117608733?isPopup=true' title='47 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7578220560117608733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/7578220560117608733'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/07/are-ssds-silver-bullet-to-improve.html' title='Are SSDs a silver bullet to improve IntelliJ&#39;s indexing performance?'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>47</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-3979528288580989011</id><published>2011-06-21T07:21:00.000-07:00</published><updated>2020-07-15T10:38:18.157-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Build in the Cloud: Accessing Source Code</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot;    style=&quot;font-family:arial;font-size:11pt;color:black;&quot;&gt;&lt;br /&gt;&lt;i&gt;This is the first in a four part series describing how we use the cloud to scale building and testing of software at Google. This series elaborates on a &lt;a href=&quot;http://www.youtube.com/watch?v=b52aXZ2yi08&quot;&gt;presentation&lt;/a&gt; given during the Pre-&lt;a href=&quot;http://sites.gtac.biz/gtac2010/&quot;&gt;GTAC 2010&lt;/a&gt; event in Hyderabad. Please see our &lt;a href=&quot;http://google-engtools.blogspot.com/2011/05/welcome-to-google-engineering-tools.html&quot;&gt;first post&lt;/a&gt; for more details on the types of problems we are solving in Engineering Tools at Google.&lt;/i&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Much of our day-to-day activities as software engineers involves source code. When we join a project one of the first things we do is look at the source. We want to build it, run it, experiment with changes, test it, and challenge our assumptions about how it works. For most of us this means we start by “checking out” the source from version control. For small to moderately sized projects almost any reasonable version control system is adequate. But as the number of engineers increases and the code base grows, this can put a strain on the version control system and decrease engineer productivity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here at Google, &lt;a href=&quot;http://google-engtools.blogspot.com/2011/06/testing-at-speed-and-scale-of-google.html&quot;&gt;all products are built from head&lt;/a&gt;. This approach has advantages: the code is open for anyone to explore and tinker with, it avoids the headaches associated with merging long-lived branches, and building from source ensures there are no binary compatibility issues between libraries. The downside is, with over a hundred million lines of code, it takes a long time to check out. And Google is a global company, which means checkout times are amplified in distributed offices. By computing dependency graphs and using this information to limit the number of files checked out, we have been somewhat successful in reducing checkout time. However, computing dependencies also takes time, and even with this improvement things still took too long.&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Engineer time lost to checking out code is the most obvious cost, but the true cost is much higher. Automated build and testing systems also need access to source code. Time spent checking out code in these systems increases the feedback cycle, which decreases their utility. It also increases the complexity of these systems since they are required to maintain state on a file system and interact closely with the version control system for what is essentially read-only access to source code.&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In fact, we have found that engineers check out and edit a very small amount code relative to the amount read to perform builds. This is because we always build from source, and changes tend to be localized to a small part of our source tree. So, both engineers and automated systems primarily need quick, read-only access to the large quantity of unedited code required to perform their builds. The unedited code itself is immutable, since it doesn’t change once it’s checked in to the version control system. This means we can use Google infrastructure to mirror all version control information in the cloud as a way to provide fast and scalable read-only access to source code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In our system, every revision of every file has an associated metadata record. The metadata includes information such as the path location in the repository, the file name, size, version, and such. It also includes a digest of the content associated with this file revision. This digest is the hash of the file content itself, created using a hashing function appropriate for &lt;a href=&quot;http://en.wikipedia.org/wiki/Content-addressable_storage&quot;&gt;Content Addressable Storage&lt;/a&gt; (CAS). There are many areas in our system where we utilize CAS; expect to hear more about it in subsequent posts.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A view of the metadata for version 5 of &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;/some/path/foo.cc&lt;/span&gt; and CAS file content:&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 104px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1G0vxJmv0REaGdGZvIh9Mgm2njlp6KKGcyBZtzfc9cQDT1X_GjEAHqabht5ImoWr-z-D_PSUg58CN0lzMGoruo3PbruhTMMi-2t5qdl5NA4KrECJYGwuJNs1d5_dKWMPmnu3NhAWON7Y/s320/image02.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5620679681434724146&quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Our system watches for changes arriving in the version control system. As changes arrive, we hash the file contents to compute digests and insert the content into &lt;a href=&quot;http://en.wikipedia.org/wiki/BigTable&quot;&gt;BigTable&lt;/a&gt;.  We then construct metadata records for each affected file and insert these into BigTable. At this point we have a complete history of all file versions in the cloud.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that we have this data, what do we do with it? We could write a command line tool to checkout code from the cloud to the developer’s workstation. This would be an improvement because it reduces load on the version control system, and replicating the data near distributed offices improves performance by reducing network latency. However it would be extremely useful if, instead of checking out source before it is actually needed, we automatically downloaded code on-demand. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This can be accomplished by writing a custom file system to provide a read-only view of the version history. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Filesystem_in_Userspace&quot;&gt;File System in Userspace&lt;/a&gt; (FUSE) kernel module is a convenient way of implementing a user space daemon that implements such a file system. Users interact with this source file system like any other file system, with the exception that certain path elements are special in that they configure the version information.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, accessing &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;foo.cc&lt;/span&gt; at global version 1000 from our previous example:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYMH1yXcfTZGZf9cxNbFLUGaem9ZHXDeCibZxL4loT56wF7nt2FFVjdSvBG4Po2cShlVSQ7n-39TvRHSVIwdiG7ecQq9oxvYnjI3BnqO9f4WxMBZbcdOeadDd5UQPhKWQwNG_FbymgFXk/s1600/image01.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 142px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYMH1yXcfTZGZf9cxNbFLUGaem9ZHXDeCibZxL4loT56wF7nt2FFVjdSvBG4Po2cShlVSQ7n-39TvRHSVIwdiG7ecQq9oxvYnjI3BnqO9f4WxMBZbcdOeadDd5UQPhKWQwNG_FbymgFXk/s320/image01.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5620680092403698770&quot; /&gt;&lt;/a&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The file system resolves metadata calls such as &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;stat()&lt;/span&gt; and &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;readdir() &lt;/span&gt;by first interpreting the version number from the path and then querying the version control data in the cloud.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, using &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;gcc&lt;/span&gt; (or any other tool) to compile &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;foo.cc&lt;/span&gt;, where &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;gcc&lt;/span&gt; first calls &lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;courier new&#39;;&quot;&gt;stat()&lt;/span&gt; to check file existence:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinCyk3OgDmjXUIqM9-xvd2IITLnNwLe_EF1ij5hxC7jzRRLI64c-o71K5pbIuxcyT48UHXzr55Z6QHvHg8LslSSlmzge0Ku2yRkpIYhGW7Kqie7mucezF8mUGx3jczPqbqnLQbJ6IAhoM/s1600/image00.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 203px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinCyk3OgDmjXUIqM9-xvd2IITLnNwLe_EF1ij5hxC7jzRRLI64c-o71K5pbIuxcyT48UHXzr55Z6QHvHg8LslSSlmzge0Ku2yRkpIYhGW7Kqie7mucezF8mUGx3jczPqbqnLQbJ6IAhoM/s400/image00.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5620687180855566514&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This allows users and tools to explore the version control using just the version metadata. File content is only downloaded at the point where it is opened. Since file versions are immutable, content can be cached and reused indefinitely. The use of CAS provides de-duplication of file content for free and the same content is never downloaded twice.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By putting our revision history in the cloud we provide engineers with complete access to all the source, and yet almost no time is spent checking out code. Replicating the cloud to multiple geographic regions ensures that performance is similar in all offices around the world. Finally, automated build and test systems can easily access code via a simple file system interface without dealing with the version control system directly. All of this adds up to a fast and efficient system which enables engineers and automated systems to focus on building and testing software instead of the mechanics of downloading source code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Stay tuned! In this post we mentioned dependency analysis and Content Addressable Storage. Part two in this series describes our build system and how it relates to these topics.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;- Nathan York&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/3979528288580989011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/3979528288580989011?isPopup=true' title='111 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/3979528288580989011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/3979528288580989011'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/06/build-in-cloud-accessing-source-code.html' title='Build in the Cloud: Accessing Source Code'/><author><name>Engineering</name><uri>http://www.blogger.com/profile/00189130917435003943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1G0vxJmv0REaGdGZvIh9Mgm2njlp6KKGcyBZtzfc9cQDT1X_GjEAHqabht5ImoWr-z-D_PSUg58CN0lzMGoruo3PbruhTMMi-2t5qdl5NA4KrECJYGwuJNs1d5_dKWMPmnu3NhAWON7Y/s72-c/image02.png" height="72" width="72"/><thr:total>111</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-4593283131183309515</id><published>2011-06-07T17:25:00.000-07:00</published><updated>2020-07-15T10:38:18.169-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Testing at the speed and scale of Google</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; clear: left; float: left; margin-bottom: 1em; margin-right: 1em; margin-top: 0px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial; font-size: 15px; white-space: pre-wrap;&quot;&gt;Continuous integration systems play a crucial role in keeping software working while it is being developed. The basic steps most continuous integration systems follow are:&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;1. Get the latest copy of the code.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;2. Run all tests.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;3. Report results.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;4. Repeat 1-3.&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;This works great while the codebase is small, code flux is reasonable and tests are fast. As a codebase grows over time, the effectiveness of such a system decreases. As more code is added, each clean run takes much longer and more changes gets crammed into a single run. If something breaks, finding and backing out the bad change is a tedious and error prone task for development teams.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Software development at &lt;/span&gt;&lt;a href=&quot;http://google-engtools.blogspot.com/2011/05/welcome-to-google-engineering-tools.html&quot;&gt;&lt;span style=&quot;background-color: transparent; color: #000099; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Google is big and fast&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;. The code base receives &lt;/span&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Development-at-Google&quot;&gt;&lt;span style=&quot;background-color: transparent; color: #000099; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;20+ code changes per minute and 50% of the files change every month&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;! Each product is developed and released from ‘head’ relying on automated tests verifying the product behavior. Release frequency varies from multiple times per day to once every few weeks, depending on the product team. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;With such a huge, fast-moving codebase, it is possible for teams to get stuck spending a lot of time just keeping their build ‘green’. A continuous integration system should help by providing the &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;exact &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;change at which a test started failing, instead of a range of suspect changes or doing a lengthy binary-search for the offending change. To find the exact change that broke a test, we could run every test at every change, but that would be very expensive.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;To solve this problem, we built a continuous integration system that uses dependency analysis to determine all the tests a change transitively affects and then runs only those tests for every change. The system is built on top of Google’s cloud computing infrastructure enabling many builds to be executed concurrently, allowing the system to run affected tests as soon as a change is submitted.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Here is an example where our system can provide faster and more precise feedback than a traditional continuous build. In this scenario, there are two tests and three changes that affect these tests. The gmail_server_tests are broken by the second change, however a typical continuous integration system will only be able to tell that either change #2 or change #3 caused this test to fail. By using concurrent builds, we can launch tests without waiting for the current build/test cycle to finish. Dependency analysis limits the number of tests executed for each change, so that in this example, the total number of test executions is the same as before.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-GjJBCofxF3I/Te5d0IlAEoI/AAAAAAAAAUM/GebfyV9aazg/s1600/image06.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;http://2.bp.blogspot.com/-GjJBCofxF3I/Te5d0IlAEoI/AAAAAAAAAUM/GebfyV9aazg/s400/image06.png&quot; width=&quot;396&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Let’s look deeper into how we perform the dependency analysis. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;We maintain an in-memory graph of coarse-grained dependencies between various tests and build rules across the entire codebase. This graph, several GBs in-memory, is kept up-to-date with each change that gets checked in. This allows us to transitively determine all tests that depend on the code modified in a given change and hence need to be re-run to know the current state of the build. Let’s walk through an example.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Consider two sample projects, each containing a different set of tests:&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-aSZlZXVSfac/Te5dySTdrGI/AAAAAAAAAUA/5s8faMPVr0g/s1600/image03.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;58&quot; src=&quot;http://4.bp.blogspot.com/-aSZlZXVSfac/Te5dySTdrGI/AAAAAAAAAUA/5s8faMPVr0g/s400/image03.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;where the build dependency graph looks like this:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-cs6tWNIqyUU/Te5dyJlVE3I/AAAAAAAAAT8/L-aWQkRq_Bw/s1600/image02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;136&quot; src=&quot;http://2.bp.blogspot.com/-cs6tWNIqyUU/Te5dyJlVE3I/AAAAAAAAAT8/L-aWQkRq_Bw/s400/image02.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;We will see how two isolated code changes, at different depths of the dependency tree, are analyzed to determine affected tests, that is the minimal set of tests that needs to be run to ensure that both Gmail and Buzz projects are “green”.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Case1: Change in common library&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Times New Roman&#39;; font-size: small; font-weight: normal; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;For first scenario, consider a change that modifies files in &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: &#39;Courier New&#39;; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;common_collections_util&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Times New Roman&#39;; font-size: small; font-weight: normal; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://lh6.googleusercontent.com/8uSH947j9AhbQrT0Fwh4j5TPbtUnBpKjSUk9BW7Ecp7Hp-f5pBXXPojM0HknZ_vHIg_8vRxjToV8_YsKUjvsCb7D5BjN-wbOx0VzrrIUr3MD0goYVaI&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;167&quot; src=&quot;https://lh6.googleusercontent.com/8uSH947j9AhbQrT0Fwh4j5TPbtUnBpKjSUk9BW7Ecp7Hp-f5pBXXPojM0HknZ_vHIg_8vRxjToV8_YsKUjvsCb7D5BjN-wbOx0VzrrIUr3MD0goYVaI&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot; /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;As soon as this change is submitted, we start a breadth-first search to find all tests that depend on it.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-Dz87R9ZduFA/Te53QrdTl7I/AAAAAAAAAU4/k4pNAuHXplc/s1600/image05.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;162&quot; src=&quot;http://4.bp.blogspot.com/-Dz87R9ZduFA/Te53QrdTl7I/AAAAAAAAAU4/k4pNAuHXplc/s400/image05.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;internal-source-marker_0.11855968087911606&quot; style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Once all the direct dependencies are found, continue BFS to collect all transitive dependencies till we reach all the leaf nodes.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-cvfCFYyjfeo/Te53TXbxQJI/AAAAAAAAAVU/1JJQCJZYdME/s1600/image12.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;166&quot; src=&quot;http://4.bp.blogspot.com/-cvfCFYyjfeo/Te53TXbxQJI/AAAAAAAAAVU/1JJQCJZYdME/s400/image12.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;internal-source-marker_0.11855968087911606&quot; style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;When done, we have all the tests that need to be run, and can calculate the projects that will need to update their overall status based on results from these tests.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-GCPftvqhMPM/Te53RSqd6PI/AAAAAAAAAVA/YJKp7exzskQ/s1600/image07.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;183&quot; src=&quot;http://3.bp.blogspot.com/-GCPftvqhMPM/Te53RSqd6PI/AAAAAAAAAVA/YJKp7exzskQ/s400/image07.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span id=&quot;internal-source-marker_0.11855968087911606&quot; style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Case2: Change in a dependent project:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;When a change modifying files in &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: &#39;Courier New&#39;; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;youtube_client&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; is submitted.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-qBefF5zIZPQ/Te53QaFQ7cI/AAAAAAAAAU0/MeQp88kWGCs/s1600/image04.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;165&quot; src=&quot;http://1.bp.blogspot.com/-qBefF5zIZPQ/Te53QaFQ7cI/AAAAAAAAAU0/MeQp88kWGCs/s400/image04.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;internal-source-marker_0.11855968087911606&quot; style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;We perform the same analysis to conclude that only &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: &#39;Courier New&#39;; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;buzz_client_tests&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; is affected and status of Buzz project needs to be updated:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-RC-r1bQR3oA/Te53Si8EcNI/AAAAAAAAAVM/nN8c3hUOk6E/s1600/image10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;182&quot; src=&quot;http://2.bp.blogspot.com/-RC-r1bQR3oA/Te53Si8EcNI/AAAAAAAAAVM/nN8c3hUOk6E/s400/image10.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; font-family: &#39;Times New Roman&#39;; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;The example above illustrates how we optimize the number of tests run per change without sacrificing the accuracy of end results for a project. A lesser number of tests run per change allows us to run all &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: italic; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;affected&lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; tests for every change that gets checked in, making it easier for a developer to detect and deal with an offending change.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Use of smart tools and cloud computing infrastructure in the continuous integration system makes it fast and reliable. While we are constantly working on making improvements to this system, thousands of Google projects are already using it to launch-and-iterate quickly and hence making faster user-visible progress.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;- Pooja Gupta, Mark Ivey and John Penix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/4593283131183309515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/4593283131183309515?isPopup=true' title='46 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/4593283131183309515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/4593283131183309515'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/06/testing-at-speed-and-scale-of-google.html' title='Testing at the speed and scale of Google'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-GjJBCofxF3I/Te5d0IlAEoI/AAAAAAAAAUM/GebfyV9aazg/s72-c/image06.png" height="72" width="72"/><thr:total>46</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-8935209530778534326</id><published>2011-05-23T13:00:00.000-07:00</published><updated>2020-07-15T10:38:18.296-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>C++ at Google: Here Be Dragons</title><content type='html'>&lt;i&gt;(Cross-posted on the &lt;a href=&quot;http://blog.llvm.org/2011/05/c-at-google-here-be-dragons.html&quot;&gt;LLVM Project Blog&lt;/a&gt;)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://1.bp.blogspot.com/-N5zgv4J_GjM/Tdq5zxU31LI/AAAAAAAAAGc/a1XAgEhA2JU/s1600/DragonMedium.png&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 242px;&quot; src=&quot;https://1.bp.blogspot.com/-N5zgv4J_GjM/Tdq5zxU31LI/AAAAAAAAAGc/a1XAgEhA2JU/s320/DragonMedium.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5610000584908723378&quot; /&gt;&lt;/a&gt;Google has one of the largest monolithic C++ codebases in the world. We have thousands of engineers working on millions of lines of C++ code every day. To help keep the entire thing running and all these engineers fast and productive we have had to build some unique C++ tools, centering around the Clang C++ compiler. These help engineers understand their code and prevent bugs before they get to our production systems.&lt;br /&gt;&lt;br /&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Of course, improving the speed of Google engineers—their productivity—doesn’t always correlate to &lt;i&gt;speed&lt;/i&gt; in the traditional sense. It requires the holistic acceleration of Google’s engineering efforts. Making any one tool faster just doesn’t cut it; the entire process has to be improved from end to end.&lt;br /&gt;&lt;br /&gt;As a performance junkie, I like to think of this in familiar terms. It’s analogous to an &lt;b&gt;algorithmic&lt;/b&gt; performance improvement. You get “algorithmic” improvements in productivity when you reduce the total work required for an engineer to get the job done, or fundamentally shift the time scale that the work requires. However, improving the time a single task requires often runs afoul of all the adages about performance tuning, 80/20 rules, and the pitfalls of over-optimizing.&lt;br /&gt;&lt;br /&gt;One of the best ways to get these algorithmic improvements to productivity is to completely remove a set of tasks. Let’s take the task of triaging and debugging serious production bugs. If you’ve worked on a large software project, you’ve probably seen bugs which are somehow missed during code review, testing, and QA. When these bugs make it to production they cause a massive drain on developer productivity as the engineers cope with outages, data loss, and user complaints.&lt;br /&gt;&lt;br /&gt;What if we could build a tool that would find these exact kinds of bugs in software automatically? What if we could prevent them from ever bringing down a server, reaching a user’s data, or causing a pager to go off? Many of these bugs boil down to simple C++ programming errors. Consider this snippet of code:&lt;br /&gt;&lt;pre&gt;Response ProcessRequest(Widget foo, Whatsit bar, bool *charge_acct) {&lt;br /&gt;  // Do some fancy stuff...&lt;br /&gt;  if (/* Detect a subscription user */) {&lt;br /&gt;    charge_acct = false;&lt;br /&gt;  }&lt;br /&gt;  // Lots more fancy stuff...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Do you see the bug? Careful testing and code reviews catch these and other bugs constantly, but inevitably one will sneak through, because the code &lt;b&gt;looks fine&lt;/b&gt;. It says that it shouldn’t charge the account right there, plain as day. Unfortunately, C++ insists that ‘false’ is the same as ‘0’ which can be a pointer just as easily as it can be a boolean flag. This code sets the pointer to NULL, and never touches the flag.&lt;br /&gt;&lt;br /&gt;Humans aren’t good at spotting this type of devious typo, any more than humans are good at translating C++ code into machine instructions. We have tools to do that, and the tool of choice in this case is the compiler. Not just any compiler will do, because while the code above is &lt;em&gt;one&lt;/em&gt; example of a bug, we need to teach our compiler to find lots of other examples. We also have to be careful to make certain that developers will act upon the information these tools provide. Within Google’s C++ codebase, that means we break the build for every compiler diagnostic, even warnings. We continually need to enhance our tools to find new bugs in new code based on new patterns, all while maintaining enough precision to immediately break the build and have high confidence that the code is wrong.&lt;br /&gt;&lt;br /&gt;To address these issues we started a project at Google which is working with the &lt;a href=&quot;http://llvm.org/&quot;&gt;LLVM Project&lt;/a&gt; to develop the &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;Clang&lt;/a&gt; C++ compiler. We can rapidly add warnings to Clang and customize them to emit precise diagnostics about dangerous and potentially buggy constructs. Clang is designed as a collection of libraries with the express goal of supporting diverse tools and application uses. These libraries can be directly integrated into IDEs and commandline tools while still forming the core of the compiler itself.&lt;br /&gt;&lt;br /&gt;We’ve been working on Clang for over a year now so that it can understand and reason about all of the C++ code at Google. But building the tools and technology to catch these bugs is only half the battle; we have to get engineers to &lt;em&gt;use&lt;/em&gt; them as well. When other teams at Google respond to production bugs, our team will often begin working to enable any Clang diagnostics that might have caught the bug. Within one week of production issues, we can sweep the entire code base using these diagnostics to fix any latent bugs.&lt;br /&gt;&lt;br /&gt;Recently we enabled the Clang C++ compiler for every C++ build at Google in order to provide accurate and helpful warnings and diagnostics to engineers. Some examples of how Clang can help developers with bad code are discussed on &lt;a href=&quot;http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-recovery.html&quot;&gt; this post&lt;/a&gt; to the LLVM blog. Beyond that, once we have swept the codebase with a bug-finding diagnostic, we can enable it for all our engineers to catch future bugs before they’re committed. These diagnostics break the entire build of that piece of software to ensure that they aren’t ignored and are acted on immediately. For the code sample above, the user gets an error message:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;example1.cc:4:17: error: initialization of pointer of type &#39;bool *&#39; from literal &#39;false&#39; [-Werror,-Wbool-conversions]&lt;/b&gt;&lt;br /&gt;   charge_acct = false;&lt;br /&gt;                 &lt;b&gt;^&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here are two other classes of bugs we’ve found::&lt;br /&gt;&lt;pre&gt;long kMaxDiskSpace = 10 &amp;lt;&amp;lt; 30;  // Ten gigs ought to be enough for anybody.&lt;br /&gt;&lt;br /&gt;void SomeService() {&lt;br /&gt;  // Setup task using external resource...&lt;br /&gt;  while (/* Check if resource is available yet ... */) {&lt;br /&gt;    sleep(0.5);  // Yield the CPU&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which now trigger the following errors:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;example2.cc:12:25: error: shift result (10737418240) requires 35 bits to represent, but &#39;int&#39; only has 32 bits [-Werror,-Wshift-overflow]&lt;/b&gt;&lt;br /&gt;long kMaxDiskSpace = 10 &amp;lt;&amp;lt; 30;  // Thirty gigs ought to be enough for anybody.&lt;br /&gt;                     &lt;b&gt;~~ ^  ~~&lt;/b&gt;&lt;br /&gt;&lt;b&gt;example2.cc:16:11: error: implicit conversion turns literal floating-point number into integer: &#39;double&#39; to &#39;unsigned int&#39; [-Werror,-Wliteral-conversion]&lt;/b&gt;&lt;br /&gt;    sleep(0.5);&lt;br /&gt;    &lt;b&gt;~~~~~ ^~~&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;All of these represent real bugs that we have found in our code, and that we are catching and fixing with the help of Clang today.&lt;br /&gt;&lt;br /&gt;Clang and its diagnostics don’t in any way obviate the need for careful code review and thorough testing. Rather, they complement these practices, combining to help reduce the number of bugs in our code. This is the platform on which we are developing new and better diagnostics for engineers going forward. This is how we are providing an algorithmic improvement to their productivity, and accelerating Google.&lt;br /&gt;&lt;br /&gt;Stay tuned for more posts about how we rolled Clang out to Google engineers, how we have enhanced Clang to make it even more relevant for our code and our developers’ needs, and some of the exciting tools we’re building on top of this platform.&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;post-author&quot;&gt;Posted by Chandler Carruth&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/8935209530778534326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/8935209530778534326?isPopup=true' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/8935209530778534326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/8935209530778534326'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/05/c-at-google-here-be-dragons.html' title='C++ at Google: Here Be Dragons'/><author><name>Chandler Carruth</name><uri>http://www.blogger.com/profile/17412143732665364317</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-N5zgv4J_GjM/Tdq5zxU31LI/AAAAAAAAAGc/a1XAgEhA2JU/s72-c/DragonMedium.png" height="72" width="72"/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477590467225772179.post-2598871672046038394</id><published>2011-05-03T09:49:00.001-07:00</published><updated>2020-07-15T10:38:18.133-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Engineering Tools Blog"/><title type='text'>Welcome to the Google Engineering Tools blog!</title><content type='html'>&lt;meta charset=&quot;utf-8&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; &gt;&lt;meta charset=&quot;utf-8&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;meta charset=&quot;utf-8&quot;&gt;&lt;div style=&quot;background-color: transparent; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 15px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;We pride ourselves on being a company that develops new products and features at a very fast pace. At the heart of all of this is the way software is developed here—which enables us to maintain the rapid pace of development while keeping the quality of our products high. Of course, this rapid pace wouldn’t be possible without our world-class engineers, but a key part of Google&#39;s success is our investment in developer infrastructure and tools.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Googlers are obsessed with speed and scale—and our infrastructure and tools are no exception. With developers across the world writing, building, testing and releasing code in multiple programming languages like C++, Java, Python, Javascript and others, the Engineering Tools team’s challenge is to keep this development ecosystem running smoothly.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;To get a sense of the size and scale of our challenge, take a look at some of these stats from a &lt;/span&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Development-at-Google&quot; style=&quot;font-family: Times; font-size: medium; white-space: normal; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;talk&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; Ashish (Director, Engineering Tools) gave last year:&lt;/span&gt;&lt;ul style=&quot;font-family: Times; font-size: medium; white-space: normal; &quot;&gt;&lt;li style=&quot;list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;5000+ developers across 40+ offices around the world&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;20+ changes per minute; 50% code base changes every month&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;More than 50 million test cases executed every day&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Single-rooted code tree with mixed language code&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Development on head; all releases from source&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;… And the numbers continue to grow! &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;Over time we have picked up knowledge about how to keep software development running at scale. Through this blog we plan to share news and updates related to our developer tools and infrastructure, the technical challenges of keeping such an infrastructure running at an ever-increasing scale, and lessons we learn along the way.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;We’d like to engage with a community of folks who are equally passionate about developer productivity. Please &lt;/span&gt;&lt;a href=&quot;mailto:google-engtools@google.com&quot; style=&quot;font-family: Times; font-size: medium; white-space: normal; &quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;send us&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt; your thoughts, ideas and comments about tools and productivity challenges and solutions in your areas. In addition, please point us to other leading research and industry work in the engineering tools area.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; &quot;&gt;John Thomas (Engineering Manager) and Ashish Kumar (Engineering Director)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://google-engtools.blogspot.com/feeds/2598871672046038394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8477590467225772179/2598871672046038394?isPopup=true' title='77 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/2598871672046038394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477590467225772179/posts/default/2598871672046038394'/><link rel='alternate' type='text/html' href='http://google-engtools.blogspot.com/2011/05/welcome-to-google-engineering-tools.html' title='Welcome to the Google Engineering Tools blog!'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>77</thr:total></entry></feed>