{"thread":{"id":"37","subject":"Re: space compression (again)","startedAt":"2005-04-15T19:33:03Z","lastAt":"2005-04-16T12:29:02Z","messageCount":2,"participants":["Ray Heasman","David Lang"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"238","messageId":"1113593583.29624.46.camel@maze.mythral.org","threadId":"37","inReplyTo":null,"subject":"Re: space compression (again)","fromName":"Ray Heasman","fromEmail":"lists@mythral.org","sentAt":"2005-04-15T19:33:03Z","receivedAt":"2005-04-15T19:33:03Z","isPatch":false,"sender":{"key":"lists@mythral.org","avatar":null},"body":"For for this email not threading properly, I have been lurking on the\nmail list archives and just had to reply to this message.\n\nI was planning to ask exactly this question, and Scott beat me to to. I\neven wanted to call them \"chunks\" too. :-)\n\nIt's probably worthwhile for anyone discussing this subject to read this\nlink: http://www.cs.bell-labs.com/sys/doc/venti/venti.pdf . I know it's\nbeen posted before, but it really is worth reading. :-)\n\nOn Fri, 15 Apr 2005, Linus Torvalds wrote:\n> On Fri, 15 Apr 2005, C. Scott Ananian wrote:\n> > \n> > Why are blobs per-file?  [After all, Linus insists that files are an \n> > illusion.]  Why not just have 'chunks', and assemble *these* \n> > into blobs (read, 'files')?  A good chunk size would fit evenly into some \n> > number of disk blocks (no wasted space!).\n>\n> I actually considered that. I ended up not doing it, because it's not \n> obvious how to \"block\" things up (and even more so because while I like \n> the notion, it flies in the face of the other issues I had: performance \n> and simplicity).\n\nI don't think it's as bad as you think.\n\nLet's conceptually have two types of files - Pobs (Proxy Objects, or\nPointer Objects), and chunks. Both are stored and referenced by their\ncontent hash, as usual. Pobs just contain a list of hashes referencing\nthe chunks in a file. When a file is initially stored, we chunk it so\neach chunk fits comfortably in a block, but otherwise we aren't too\ncritical about sizes. When a file is changed (say, a single line edit),\nwe update the chunk that contains that line, hash it and store it with\nits new name, and update the Pob, which we rehash and restore. If a\nchunk grows to be very large (say > 2 disk blocks), we can rechunk it\nand update the Pob to include the new chunks.\n\n> The problem with chunking is:\n>  - it complicates a lot of the routines. Things like \"is this file \n>    unchanged\" suddenly become \"is this file still the same set of chunks\",\n>    which is just a _lot_ more code and a lot more likely to have bugs.\n\nYou're half right; it will be more complex, but I don't think it's as\nbad as you think. Pobs are stored by hash just like anything else. If\nsome chunks are different, the pob is different, which means it has a\ndifferent hash. It's exactly the same as dealing with changed file now.\nSure, when you have to fetch the data, you have to read the pob and get\na list of chunks to concatenate and return, but your example given\ndoesn't change.\n\n>  - you have to find a blocking factor. I thought of just going it fixed \n>    chunks, and that just doesn't help at all. \n\nJust use the block size of the filesystem. Some filesystems do tail\npacking, so space isn't an issue, though speed can be. We don't actually\ncare how big a chunk is, except to make it easy on the filesystem.\nIndividual chunks can be any size.\n\n>  - we already have wasted space due to the low-level filesystem (as \n>    opposed to \"git\") usually being block-based, which means that space \n>    utilization for small objects tends to suck. So you really want to \n>    prefer objects that are several kB (compressed), and a small block just\n>    wastes tons of space.\n\nIf a chunk is smaller than a disk block, this is true. However, if we\nsize it right this is no worse than any other file. Small files (less\nthan a block) can't be made any larger, so they waste space anyway.\nLarge files end up wasting space in one block unless they are a perfect\nmultiple of the block size.\n\nWhen we increase the size of a chunk, it will waste space, but we would\nhave created an entire new file, so we win there too.\n\nAdmittedly, Pobs will be wasting space too.\n\nOn the other hand, I use ReiserFS, so I don't care. ;-)\n\n>  - there _is_ a natural blocking factor already. That's what a file \n>    boundary really is within the project, and finding any other is really \n>    quite hard.\n\nNah. I think I've made a good case it isn't.\n\n> So I'm personally 100% sure that it's not worth it. But I'm not opposed to\n> the _concept_: it makes total sense in the \"filesystem\" view, and is 100%\n> equivalent to having an inode with pointers to blocks. I just don't think \n> the concept plays out well in reality.\n\nWell, the reason I think this would be worth it is that you really win\nwhen you have multiple parallel copies of a source tree, and changes are\ncheaper too. If you store all the chunks for all your git repositories\nin one place, and otherwise treat your trees of Pobs as the real\nrepository, your copied trees only cost you space for the Pobs.\nObviously this also applies for file updates within past revisions of a\ntree, but I don't know how much it would save. It fits beautifully into\nthe current abstraction, and saves space without having to resort to\nrolling hashes or xdeltas.\n\nThe _real_ reason why I am excited about git is that I have a vision of\nusing this as the filesystem (in a FUSE wrapper or something) for my\nhome directory. MP3s and AVIs aside, it will make actual work much\neasier for me. I have a dream; a dream where I save files using the same\nname, safe in the knowledge that I can get to any version I want. I will\nlive in a world of autosaves, deletes without confirmation, and /etcs\nimmune from the vagaries of my package management systems, not to\nmention users not asking me leading questions about backups. *sigh*\n*sniff* Excuse me, I think I have to go now.\n\n-Ray\n\n\n"},{"id":"296","messageId":"Pine.LNX.4.62.0504160526530.21837@qynat.qvtvafvgr.pbz","threadId":"37","inReplyTo":"1113593583.29624.46.camel@maze.mythral.org","subject":"Re: space compression (again)","fromName":"David Lang","fromEmail":"david.lang@digitalinsight.com","sentAt":"2005-04-16T12:29:02Z","receivedAt":"2005-04-16T12:29:02Z","isPatch":false,"sender":{"key":"david.lang@digitalinsight.com","avatar":null},"body":"we alrady have the concept of objects that contain objects and therefor \ndon'e need to be re-checked (directories), the chunks inside a file could \nbe the same type of thing.\n\ncurrently we say that if the hash on the directory is the same we don't \nneed to re-check each of the files in that directory, this would be that \nif the hash on the file hasn't changed we don't need to re-check the \nchunks inside that file.\n\nDavid Lang\n\n\n  On Fri, 15 Apr 2005, Ray Heasman wrote:\n\n> Date: Fri, 15 Apr 2005 12:33:03 -0700\n> From: Ray Heasman <lists@mythral.org>\n> To: git@vger.kernel.org\n> Subject: Re: space compression (again)\n> \n> For for this email not threading properly, I have been lurking on the\n> mail list archives and just had to reply to this message.\n>\n> I was planning to ask exactly this question, and Scott beat me to to. I\n> even wanted to call them \"chunks\" too. :-)\n>\n> It's probably worthwhile for anyone discussing this subject to read this\n> link: http://www.cs.bell-labs.com/sys/doc/venti/venti.pdf . I know it's\n> been posted before, but it really is worth reading. :-)\n>\n> On Fri, 15 Apr 2005, Linus Torvalds wrote:\n>> On Fri, 15 Apr 2005, C. Scott Ananian wrote:\n>>>\n>>> Why are blobs per-file?  [After all, Linus insists that files are an\n>>> illusion.]  Why not just have 'chunks', and assemble *these*\n>>> into blobs (read, 'files')?  A good chunk size would fit evenly into some\n>>> number of disk blocks (no wasted space!).\n>>\n>> I actually considered that. I ended up not doing it, because it's not\n>> obvious how to \"block\" things up (and even more so because while I like\n>> the notion, it flies in the face of the other issues I had: performance\n>> and simplicity).\n>\n> I don't think it's as bad as you think.\n>\n> Let's conceptually have two types of files - Pobs (Proxy Objects, or\n> Pointer Objects), and chunks. Both are stored and referenced by their\n> content hash, as usual. Pobs just contain a list of hashes referencing\n> the chunks in a file. When a file is initially stored, we chunk it so\n> each chunk fits comfortably in a block, but otherwise we aren't too\n> critical about sizes. When a file is changed (say, a single line edit),\n> we update the chunk that contains that line, hash it and store it with\n> its new name, and update the Pob, which we rehash and restore. If a\n> chunk grows to be very large (say > 2 disk blocks), we can rechunk it\n> and update the Pob to include the new chunks.\n>\n>> The problem with chunking is:\n>>  - it complicates a lot of the routines. Things like \"is this file\n>>    unchanged\" suddenly become \"is this file still the same set of chunks\",\n>>    which is just a _lot_ more code and a lot more likely to have bugs.\n>\n> You're half right; it will be more complex, but I don't think it's as\n> bad as you think. Pobs are stored by hash just like anything else. If\n> some chunks are different, the pob is different, which means it has a\n> different hash. It's exactly the same as dealing with changed file now.\n> Sure, when you have to fetch the data, you have to read the pob and get\n> a list of chunks to concatenate and return, but your example given\n> doesn't change.\n>\n>>  - you have to find a blocking factor. I thought of just going it fixed\n>>    chunks, and that just doesn't help at all.\n>\n> Just use the block size of the filesystem. Some filesystems do tail\n> packing, so space isn't an issue, though speed can be. We don't actually\n> care how big a chunk is, except to make it easy on the filesystem.\n> Individual chunks can be any size.\n>\n>>  - we already have wasted space due to the low-level filesystem (as\n>>    opposed to \"git\") usually being block-based, which means that space\n>>    utilization for small objects tends to suck. So you really want to\n>>    prefer objects that are several kB (compressed), and a small block just\n>>    wastes tons of space.\n>\n> If a chunk is smaller than a disk block, this is true. However, if we\n> size it right this is no worse than any other file. Small files (less\n> than a block) can't be made any larger, so they waste space anyway.\n> Large files end up wasting space in one block unless they are a perfect\n> multiple of the block size.\n>\n> When we increase the size of a chunk, it will waste space, but we would\n> have created an entire new file, so we win there too.\n>\n> Admittedly, Pobs will be wasting space too.\n>\n> On the other hand, I use ReiserFS, so I don't care. ;-)\n>\n>>  - there _is_ a natural blocking factor already. That's what a file\n>>    boundary really is within the project, and finding any other is really\n>>    quite hard.\n>\n> Nah. I think I've made a good case it isn't.\n>\n>> So I'm personally 100% sure that it's not worth it. But I'm not opposed to\n>> the _concept_: it makes total sense in the \"filesystem\" view, and is 100%\n>> equivalent to having an inode with pointers to blocks. I just don't think\n>> the concept plays out well in reality.\n>\n> Well, the reason I think this would be worth it is that you really win\n> when you have multiple parallel copies of a source tree, and changes are\n> cheaper too. If you store all the chunks for all your git repositories\n> in one place, and otherwise treat your trees of Pobs as the real\n> repository, your copied trees only cost you space for the Pobs.\n> Obviously this also applies for file updates within past revisions of a\n> tree, but I don't know how much it would save. It fits beautifully into\n> the current abstraction, and saves space without having to resort to\n> rolling hashes or xdeltas.\n>\n> The _real_ reason why I am excited about git is that I have a vision of\n> using this as the filesystem (in a FUSE wrapper or something) for my\n> home directory. MP3s and AVIs aside, it will make actual work much\n> easier for me. I have a dream; a dream where I save files using the same\n> name, safe in the knowledge that I can get to any version I want. I will\n> live in a world of autosaves, deletes without confirmation, and /etcs\n> immune from the vagaries of my package management systems, not to\n> mention users not asking me leading questions about backups. *sigh*\n> *sniff* Excuse me, I think I have to go now.\n>\n> -Ray\n>\n>\n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n\n-- \nThere are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.\n  -- C.A.R. Hoare\n"}]}