 No, no, no, no, no. So welcome, thank you for coming. This talk is going to be on kind of some API features of Swift. This is the third time we've been in this room today and it is packed, which is awesome. Actually third Swift talk I've seen today, which is packed, which is really great. I love that. My name is John Dickinson. You can find me on Twitter and IRC at NotMyName and I am the Project Technical Lead for OpenStack Swift. Really happy to be here. This is my 12th OpenStack Summit and it's kind of crazy to see all of this. So today we're going to talk about Swift features that go beyond just standard read, write, delete sort of things. So very much on the application side rather than the technical side. But first question, although this is a very intro sort of topic is, I mean, a question here should briefly cover it is, what is Swift and why are we here? Swift is an object storage system that stores data, multi-petabyte scale, globally distributed, all that kind of stuff, which is really, really great. And in fact, a little kind of interesting point here is yesterday was the fifth anniversary of it being in production at pretty large scale, which is pretty cool. So happy birthday Swift yesterday. So this is Swift. Swift is a system that separates out the data that you have from the media upon which it is stored and that separation is incredibly powerful because it means that no longer do you have to worry about the fact that this particular CD or this particular cassette or tape or even physical hard drive or something like that is intrinsically tied to the data. I mean, hundreds of years ago people said they wanted to kill the information so they burned the books but that's just the media, it's not really the idea. And here's this is the same sort of thing in the modern world, we've got the data separated from the media itself, which means that you can start swapping things out and you can take advantage of some, not having to worry about a lot of storage problems. So the point is that Swift is built for scale to store a ton of data on a ton of different hard drives and it's going to be optimized for durability, availability and concurrency across the entire data set. So basically it's really, really good at storing web content, mobile content, videos, backups, all this kind of really large unstructured data that can grow without bound. The API is stateless, it's based on HTTP so it's not going to be super chatty, but that's about the limit I'm going to talk about on that. We're going to kind of go beyond, I'm going to assume that you have a little bit understanding of Swift before we go. And I've talked many, many times on kind of what Swift is and how it works, but most of the time I kind of spend on the right hand side here about how does it actually store data and what's the data placement, how does it recover from failures and all that kind of stuff. But today we're going to talk about the client API side. We're going to talk about what are the things that really matter for the application. Because here's the truth of it, nobody cares about storage in particular, all you really care about is that you have your data and you can get it back and it doesn't go away. What you really care about is you've got an application and you want to focus on adding value to your application. You don't want to focus on, well, how did I manage concurrency across access and this particular thing across a wide geographic area especially when there might be hard drive failures in here and what about the network switches and how's the network saturation going on and all that kind of stuff, you don't care. All you really want to think about is I've got a picture, let's put it in the storage system. Later on somebody else is going to access it and I need to make sure that it's right there and it's the same picture I originally stored. So that's what we're talking about and one of the kind of, the things where you start really seeing this a lot is especially in the proliferation of the last decade of web and mobile apps and think about what you're doing. You've got your phones, iPhones, Android app, phones, whatever it may be and you don't want to think about the storage. You never want to go take a picture and worry about, well, I ran out of space. You never want to have to figure out how do I make sure that I copied the photos over from my camera over to my laptop and that's also accessible when I'm at work but I also need to give some to my wife so she can go see what's going on when I'm up here in Vancouver. If you ever start having to think about that you get really annoyed because you shouldn't have to think about it. All you really should think about is I've got some data, now give it back to me. So we need something that allows, the storage system has to be able to handle that so that the people who are writing apps don't have to worry about it. So if you're reading a new story you don't really care how they're organizing stuff. If you're taking pictures or playing games you really don't care about where that data is stored. All you care is that you have access to it. And it's not just say phones although I think that's a really great example. This is a use case that came across a year or so ago with looking at website data. This is a website, adrift.org.au that is run in the Australian National Research Cluster and what it does is tracks debris in the ocean which is kind of cool. So you pull up their website, you click on any piece of water here and it will show you over the next 10 years if you dumped something in the ocean right there where is it going to be later on. And since this is running on their national research network there that's all based on OpenStack which is cool in and of itself. And the way they had their site running is that they would have a web server as one does. They would load, serve up the web content and then somebody would click on that, they would go back to the web server, the web server would make a request into Swift and pull out that data and then it was sent back to the client to run the animation and render it. Well it turned out that there were some news stories about some planes going down and everybody started wondering where in the world could the plane be and we need to look for debris. So if a piece of debris is in the ocean here where should we look for it and this kind of tool became super helpful for that and a few people heard about it, started looking at it and promptly killed the web servers and so that was like oh so what do we do here? Well clearly the people who are running these sort of things don't want to have to think, they want to serve up their content. They don't want to have to think about these hard problems of concurrency of the storage, of the hard problems of storage like the massive concurrency and scaling needed for that but the thing is they've already got all the data in Swift and Swift can speak HTTP which is what websites, web browsers speak so why not just have the client go ask directly to Swift? It's not secret data so just mark this as publicly available and go get the data which is exactly what they did and boom their scaling problems were gone. Now the clients would get the website from the web server which would load the little JavaScript and things like that. They would click on the ocean and that would make a request to back to Swift and it would load it back in and scaling problems were gone. So that was just kind of this really cool thing about how Swift was able to improve the user experience and improve the operator experience for people writing apps that were providing some pretty cool information simply by using all the features of a storage system. So that's kind of the intro of where we're at, what Swift is doing, kind of some places where it really is good. So hold on, now we're going to go kind of fast. We're going to talk about several features of Swift that go beyond just let me go get the data and what are the kind of things that can help actually make your application better. So I'm going to assume a little bit of a basic understanding of Swift. Swift uses basic HTTP verbs, response codes, we've got things called accounts, containers, and objects. But if you're not intimately familiar with all of that, that's OK, you'll still be able to follow along in general as far as what we're going. So first cool feature of Swift, we'll start basic and then we'll get to some really cool stuff later. First big things, listings. The most important thing you can think of for a storage system is that it actually stores the data. But after you've done that, the next question people ask is, what data do I actually have stored? So they start asking about the metadata. They start asking about, well, can you show me all the pictures that are blue, or can you show me everything that's changed since a certain date? And that kind of functionality is available from various vendors who are deploying Swift. And in fact, this week in some of the design sessions, we're going to be talking about, are there some ways that we can enhance and add things to Swift's API to directly support some metadata searching? Don't know what's going to happen there yet? That's why we're going to have the conversation later this week. But the most simple kind of metadata you can think about is really just, what's the name of the object? And how can we get a list of all of the things that are in this particular container inside of Swift? So I'm going to cover this one first because we're going to build on top of it for some features later. So let's suppose this. I've got some books. And I want to organize them basically by genre and then by author. So if I've got these things, a few by Edgar Allen Poe and some comics, Far Side Comics and Calvin and Hobbes and all the classics, I want to put those into Swift. And so I'm going to create a couple of containers, one called horror and one called comics. And then my object name you can see here on the first one is Poe, Pit in the Pendulum. And the last one there, I'm in the comics container. And I have put it for, I prefixed it with Watterson because it's Bill Watterson who wrote Calvin and Hobbes and The Magical World, the last comic book that he put together there. So I've put these objects into Swift. I put it into two containers. And now I want to start getting lists of these sort of things. Importantly note that the object names here actually have slashes in them. So we're going to build on that. So if we do a basic listing, we send a get request to a particular container. If we just do a listing of the horror things here, we'll just get a list of everything that's possibly there. But actually it's not quite everything because Swift is going to be by default limited to a page size of 10,000 items. So what happens if you have a million? What are you going to do there? Well, maybe you want to give it a smaller limit. We'll get bigger later. So we have a smaller limit. You can see here that if I did the basic listing, I've got three things that are going to come back here. By two authors and I've got a total of three objects. But if I give it a limit of two, just put a hook at the end of the request and limit equals two, then I'm going to get the first two things. So you can arbitrary the limit to say that I don't want to load over the network or something like that more than, I don't know, 100 at a time, 1,000 at a time. And that way you can start doing some pagination in your own app as far as allowing to view what's actually in there. So once you've got the limit, you can maybe modify it in some slightly different ways. Maybe you want to give a particular marker and you say, you know what, I just want everything after this particular point. So if we go in there and put in a marker, and this I just chose is O'Henry. It says something I don't have stored here. And it kind of lexigraphically sorts between the two things that I do. Then I'm only going to see the things that sort after O'Henry. So in this case, I've got a listing for everything that's in my container. But I've told it to go to an arbitrary point and just start giving me everything after. Now the interesting thing here is if you started combining this with a limit to get like a page size, well then, when you do your page size, and if we did a limit of 2, if I put in the next request a marker for Poe, or the Mask of the Red Death, then at that point, I'm going to start getting everything after that in the container. And I would go get that third item that's in the container. So we've got marker. But sometimes you just don't want to talk about, OK, go to this point and give me everything after it. Maybe you want to start with an end marker. You want to say, give me everything up to this other point. And so now you're starting to see that inside of the listing requests inside of Swift, you've got some powerful tools, some powerful constraints that you could put on the actual listing that you do. So in this case, I give it an end marker, and it's exactly what you would think. That if you say give me an end marker of everything by Poe that starts with an end, then it's going to give me everything that sorts before that. And so yeah, you can combine these. You could say give me 100 things that start from here and go to here. And we're just going to start paginating over those particular constraints. Couple of the things on the listings, specifically on how you can continue to modify those, you can start giving it a delimiter, which is an arbitrary character that will allow you to give pseudo directories. Inside of Swift, you're not able to nest your containers. But you can, like you can see in this example, put in objects that have a slash in them, and they give it a delimiter of a slash. And now your listing result starts looking like directories. So you can say that here's everything in the delimiter with the delimiter of slash. So now I've sorted it into Gram-Smith and Poe. And so if I wanted to use the next one, say for example a prefix, I would be able to start walking into a particular pseudo directory. So in this case, I went ahead and just did the prefix requests. It starts with the g. That could have been a whole Gram-Smith or whatever you need. And this will return anything that has that at the beginning, anything that has that as a prefix. So in this case, I'm looking for anything that starts with p. And I'm returning the classic work by Gram-Smith called Pride and Prejudice and Zombies. So that's listings. So let's move on. Next cool feature in Swift. Temporals. One of my favorite features in Swift. This is really powerful. And it allows, OK, we'll just keep on. So what's an account in Swift? An account is a place where you, it's a storage area. And you can set particular pieces of metadata on your account. You could say this is going to be used by the accounting department or something like that. There's a kind of metadata that you can set on an account called a temporal key. This is a secret key. And you can set that key on there. And then once you have that key, you can generate a signed URL, which basically puts some parameters on the end of the request. And anybody that has that URL is able to access the data. So you get a signed URL. And it's basically just an HMAC SHA-1 of your secret plus a couple of parameters associated with the actual request. You can create these on a per object basis. You can create them on a particular verb. So you don't need any sort of remote access to create these. You can do these completely locally. And you can start passing them out like candy to anywhere. So you could give somebody a request that says, this particular crafted URL is only allowed to write to this object name right here. And they're not allowed to do anything else. Or maybe there's a different one that says, they can read this particular object over here. So the last thing about temporals is that they are temporary. They are time limited. So you could use them to prevent hot linking. Or even you could use them to allow uploads or downloads from otherwise untrusted users. So imagine this. Imagine you're selling some piece of software or media or something like that. And just like adrift.org, you want to serve the content directly, the sold content directly from Swift. Well, now you can craft a URL that's only going to be valid for the next 30 seconds that can download only this one particular item. You give them that. And it doesn't really matter if they share that, because it's no longer going to be valid for use. So it's something that allows you to give you a really cheap way to give untrusted users temporary access to a very specific part of Swift. And it becomes pretty powerful when you start thinking about the different use cases there. The last thing about it is that you actually have two keys that you can set, which means that you can start rotating the keys. And you can change the key without having to invalidate existing things that are out there. So for example, if you know that you have never created a temporal key that's longer than one hour, then you can change one key. And then an hour later, you can change the other key. And now you've done a key rotation without breaking any links that are already out there. So how do you do this? Well, if you use the Swift command line utility, you ask it to create a temporal. You give it a verb, a time, and the particular thing you're trying to request, and then the shared secrets. And once you do that, you get something that looks kind of like this. You get a request that is, in this case, myobject.dat. It has a temporal on it and the XBerry time. And when you hand this out, then you are able to, they're able to access that particular thing. And in this case, that was a get request for it. So they're fast, they're easy, they're super scalable, they don't require any extra dependencies. You can rotate them over time. And even in the key release, we have enhanced this feature such that you can set a temporal key on a container. And in this case, imagine if you own an account in Swift, but you have users who are isolated to a particular container. Well, you can actually allow them to set a temporal key on a container, and they themselves can start creating temporals that are only valid for data that's in that container. So this kind of allows you a nice tiering and just really great access controls on that. So I love this feature. It's a really great, really great thing to do. Next thing, going quickly here, static websites. Static websites are, well, there's websites that you're not going to have to do some sort of per session computation or something like that. So Swift speaks HTTP natively, so why not let it serve an entire site out? Why not, let's not think about just static text or a generated webpage, but even entire client-side apps. If you can just serve the HTML, which references the JavaScript, which is also stored in Swift, which then calls data that could also be stored in Swift. And you've got entire website, entire almost server-side or client-side app, I'm sorry, that could be entirely served out of Swift. So what's the problem? Why can't we just do that anyway? Well, there's a few things. One is that when you go to a website, I can guarantee you you never go in there and type slash eight index.html. You just let the browser take care of that. But the problem is if you didn't do that and the site was served from Swift, then Swift is gonna look at it and say, well, you asked for slash nothing. So what are we gonna do? So Swift needs to know a way that, well, when you don't give it something, go to this default index page, whatever that may be, so that you can actually start requesting and get a good browser-like experience for that. The other thing you're probably gonna want is what happens if somebody fatfingers the URL or there's a mistake someplace. You want to have nicely configured error messages. So it sure would be nice if you wouldn't have to just throw up a really, really ugly 404 message, but give them something cute and clever that's a nice web page that says, oh, that was the wrong page. Maybe you should go look over here. Other things that are common with web servers that are designed to serve websites would be like an auto-generated listing of what's available at that resource. Generally, that's not the final form of what people actually use, but it is still something that's pretty handy and Swift supports all of these things. So on a container, you can set some metadata and one of the things you can set is the web index and you can give it a name. So you can give it index.html, you can give it skippythewonderdog.txt and that's gonna be the thing that is default served if nothing is explicitly specified. And you can even give it some error pages. So if you wanted a 404 error, you could say that the suffix set on the metadata is say error.html and if there's a 404 error, then Swift will automatically serve up 404 error.html. Therefore you kind of get this automatic handling of a good whole site user experience. We can turn on and off web listings, those auto-generated web listings to kind of a true, false, yes, no toggle on that metadata and you can even style the particular listings that are out there. You can also style some of the other pages as well. So what does put this together in the most simple form? What does it look like? Looks like that. I uploaded some desktop pictures that I had on my computer and served it out of a static website. So I put that in a container called C and I hit that with static web turned on after I set those pieces of metadata and that's what Swift produced. I didn't generate any code to do this. It automatically tells me here's all the links, automatic links to every object that's there. What's the size of them? What's the date when they were created without having to do anything else? So what we get there without having, what we now have with static websites inside of Swift is the ability to serve up to deal with nested directories. You can see the very first one there has a nested directory. It's again using that same sort of prefix sort of in delimiter listing functionality. You've got the auto redirect. You can see the location bar at the top there. It doesn't have an index.html. We've got the auto-generated websites and this allows you to have whole websites and whole client side applications served directly from Swift with zero external dependencies and if you're using Swift to store your data, which you should be anyway, then that's it, you're done. You can automatically do this and you don't have to have any extra servers because your site is not gonna be just a scale of what Swift itself. So let's go beyond that. I've now got a really great static website but what if I want people to put data into Swift? How are we gonna do that? Swift is great for serving content over the web so what about accepting it? Well, there's a couple of hard parts associated with that as well. The Swift API is built such that when you explicitly give it a name of an object to create and then you'd use the HTTP put verb to do that. So you put a particular object into Swift. Unfortunately, that's not the way browsers work. Browsers say, I want to post this particular content and here's some, here's a whole document that describes the various objects that I'm gonna post to this website. The other thing is that just like all of the other OpenStack projects, you generally need some sort of auth token to pass around with a quest but that's done on a header and the browsers aren't in the habit of allowing somebody to click on a link and automatically injecting headers into the request. So we've got to figure out how to do that kind of things. And the final problem here is that if you're allowing somebody to upload a new image, say a headshot for whatever it may be or images, pictures, videos, whatever it can, maybe you don't know what they're gonna be called. So you can't actually know when you're rendering that page for them to do that. You couldn't, for example, create a temporal for that because you don't know exactly what they're gonna create unless you just start getting arbitrary things but nobody wants to go to read an object that is named some big SHA1 hash of whatever could be, some random number or something like that. You would really like to have cat.jpg, not some big hexadecimal string. So we've got to kind of solve that and that is what the form post does. It allows you to create a, it allows you to create an HTML form that takes care of all of those pieces for you and then on the server side, on Swift itself, it will translate those pieces back so that you can easily get all of that data into Swift. And this is how you create it, pretty easy. We've got a script that is included with Swift called SwiftFormSignature and in this case, we're gonna give it a prefix name. We're gonna, this path inside of my account, my uploads container and I called a pre underscore. So every object that's created will be prefixed with pre underscore. And we're going to give it a, the next thing here, the example.com slash done is the redirect link. So after the form post is submitted, where do you want Swift to redirect you? What's the final page that's gonna be there? You wanna give it the maximum number of, well the next one is the maximum object size. So in this case, I just put one megabyte and then how many potential objects are allowed to be uploaded at one time? Because you could actually use this to upload say three, five, 10, 30 objects all at once. And the time limit that this is gonna be good for and then the shared secret. This is again using an HMAG very, very similarly to the temporal feature. So when you run this, you're gonna get out this. Here's an HTTP, HTTP, I'm sorry, an HTML snippet of a form that you could just drop into your webpage. So you can see here, we've got the post method that's going to encrypt this, I'm just gonna encode this form data. And it's gonna submit it to the proper place and it puts in the correct form fields and specifically you get this signature that gives you the authorization to do so and you can add in the different file types that you need and it gives you a nice little input button at the bottom. And so from this, you now have the ability to render an entire site inside of Swift and can even have the possibility of saying, hey great, you can now store your data in Swift again without having to proxy that through some other web server that is accepting all of this content. And if you started combining this with other things kind of on the server side, I said I wasn't gonna get into that, but you could start transforming your data on the server side and indexing it and doing some of that kind of cool stuff. And then you've got Swift as your entirety, the storage engine itself is actually solving a lot of these basic problems so that you don't have to worry about it. You can worry about all of the things around it. Next up, I don't like this feature because it's confusing and hard. Cores stands for cross origin resource sharing and it is a browser thing. So we're talking about all these websites and browsers so we have to start playing in that world really well. And it's a mechanism that allows code that is running in the browser and this thing, that JavaScript, that to make requests to some other domain name, some other site out there. And normally you don't wanna do that. Browsers will restrict that. Think about it. It's actually a really good thing that this restriction is in place. You don't want some sort of phishing site to be calling out to your bank's website and running code that your bank wrote to make it look like they're actually your bank. You don't want that. So browsers in general say no. You can only execute code or the code that you're executing locally is only gonna be able to access things from the same origin. It's kind of the same origin security model. And that's something that's common across web browsers. But there's a way you can get around it and it's called cores. It's a mechanism, it's a protocol that is defined between a server and the browser such that the server can assert that, no, it's okay. I am actually owned by that other domain over there. It's okay, we can execute things. So it's complicated. And I'll be the first person to tell you that. The spec is tedious to read and complicated. But it's still a good thing. You want this and being able to support this means that you can have more full-featured modern apps. So how do you do this? There's not a lot to do actually because Swift is implementing most of the hard parts itself. But you can set a few pieces of container metadata. They're really long. So I trimmed off the X container meta prefix on all of those. You set, here's the allowed origins for this particular container. Here's the maximum age that the pre-flight requests for cores can do. And then you can say these are the keys that the code that's running in the browser are actually gonna have access to. And in this case, what that basically means is that the browser is gonna make a request to check that, hey, is everything okay? And if it's all okay, what am I going to let this code have access to? It doesn't just give it carte blanche to read everything. So the server can come back and say, well, no, you can only read keys A, B, and C, but not D, E, and F, and et cetera. So when you set these, basically you're done. Now, as a web dev, you can use Swift for storage inside of your normal workflow. You don't really have to start thinking about the extra pieces you have to do for this. You set the appropriate cores values, configuration values on a container, and then it works. This one is really cool. I love this feature. And I even love it more now that as I was preparing for this talk, I started just being reminded, yeah, this is really cool. So we're gonna move away from some of the web stuff and we're gonna talk about another huge use case for Swift and that's backups. So many backups are just, you're gonna have something and if you're not using some proprietary tool or something like that, you're probably going to, at some point in the workflow of creating a backup, you're gonna use tar, and you're gonna create this archive. So wouldn't it be kind of cool if you could just upload that archive and have all the pieces available to Swift? Yes it would and yes you can. Here's how it works. So if you have tar, the command line utility, and you create a compressed archive output to standard out of whatever the file is in the local directory, pipe that directly to curl, give it an auth token. I'm gonna put it in this container called C and I'm gonna give it a parameter say extract archive, this is a tar.gz archive. And at that point, that's it. Now this is what I get inside of Swift. Well actually, this is my tar file example. Go back to my desktop images, had that folder handy. So I've got this, this is my tar file, this is my directory listing that I have locally. This is what I end up with in Swift. So remember I did that extract archive inside of Swift, now it just put all of these pieces inside of Swift. I mean the extract archive command was, had the container C. So in this case everything was put into that container. But if I wouldn't have given that, if I wouldn't have given it in a container, desktop images would have been made a container and every top level directory would have been made a new container created inside of the storage system itself. So this one I really love because it's just kinda like wow, the one line I can upload a thousand things to Swift and I can compress it during the transport and it'll be stored uncompressed and I can even, what's the thing I was gonna say? Oh yeah, so you can have access. So you do a, so you're gonna back up your Etsy file, your Etsy directory on your Linux server. So at that point you now have direct access to any particular one of those config files in Swift so you can restore each one of them individually, which is pretty cool I think. So large objects. Swift normally has a limit of five gigabytes for a particular object. So we sometimes wanna get around that. So we have this feature called large objects and large object, yeah, that's what it's for. That was what it was originally created for but it's probably more generically better called just indirection objects and we've got two different kinds. But the basic idea is that you can store one object in Swift that is going to reference one other object or a set of other objects. That gives you some really interesting tools. So let's talk about those two different kinds. We got one called dynamic large objects, sometimes called DLOs. In this case, we create this object called say 2014.logs and we tell it that we're gonna reference these other log files. So here's an interesting example. Let's say that every minute you or every five minutes, every hour, whatever the case may be, you take across all of your servers, your logs, you rotate your logs and then you're gonna upload those rotated logs up to Swift. Now, you create an indirection object that says that, okay, this is the set of logs that came from all of my servers over this particular hour. And the way these dynamic large objects work is that they are built on top of container listings. So the large object is, the dynamic large object is built specifically on the prefix listing that we saw earlier. So in this case, if I would say that my prefix is 2014 dash, then when I access this large object, it's gonna find all of the things that are in the listing with that particular prefix and start returning them to you sequentially in whatever the order is on the names that they have. So if you had, say for example, four log files and you had them named like this, they're gonna lexicographically sort here, I'm gonna reference just the indirection object and I'm gonna get back the concatenation just as one continuous stream of the contents of all of those different things. So, more generally, you can say, remember, you're okay, you're archiving your log files, you're rotating your logs, you're uploading those to Swift, and now you can create the indirection objects that say for every hour, for every day, for every month, for every year. And if you're naming your logs when you're uploading them that way, all that is is a simple change on the, it's identifying what the appropriate prefix is. And more importantly, you create the indirection object once and every single time you're uploading these things, the contents of that is changing so that it's just whatever's available right now and it makes them very dynamic. So that's really cool, I like that one a lot. There's a different mechanism that we can use, static large objects. So static large objects are not dynamic as you may have guessed. They explicitly reference particular segments, particular other objects. And so, instead of identifying, say, a container prefix listing, they have an explicit manifest in JSON that is their contents and it will go and get the first one that's listed and then the second one that's listed and the third one that's listed. And I tried to show that here by saying that I don't have a common prefix among these pieces of data, these reference segments, they're not in any particular order, it's just I'm gonna go get this one, I'm gonna go get segment 33, then part 46, then piece 17, then part 46 again. And so you can start saying no explicitly in this case, it's gonna be this one, this one, this one, that one again, then this and this and this one. So there's a couple of interesting things here. Imagine that you're dealing with videos and you have a 20 gigabyte video that you wanna upload. Split that into 21 gigabyte pieces, create a manifest file that says, okay, it's these pieces in this order, upload that. And now you have access to those individual chunks. You can currently upload them and download, which gives you some interesting speed, but you still have the indirection object, the static large object manifest that presents it to a client as here's just this one giant 20 gigabyte video. And so you can start doing some interesting things along those lines. I tried to hint at this other thing which is kind of interesting, is that you could refer to a segment multiple times. So you could even kind of build your own dedupe scheme on this out of this sort of feature. In almost every case, when you're using large objects, you wanna use static large objects. Explicit is better than implicit. There's some interesting use cases for doing dynamic large objects, but almost always you're gonna wanna use static large objects. So like I said, these are some of the features that I really like in Swift. They're pretty cool, but where do we go from here? What are we looking at? So we wanna make some improvements, obviously, into the Swift API because that's what we're doing, but how do we come up with those? We talked about, I mean you could talk about the indirection objects. It's almost approaching something kind of like a sim link in a file system. Swift isn't a file system and they're not quite sim links, but it turns out that later this week we will in fact be talking about that very concept. Can we have a simplified stripped down version of an indirection object that is specifically just for sim linking one to one sort of thing? So that should be an interesting conversation to have this week and something that we can work on over the next few months. Metadata, there's a patch out there now or being worked on, I think it's been submitted, to allow you to set more metadata on that archive like that tar archive so that it's appropriately set on the exploded objects out there. We just added the container level temporal keys. Like I said earlier, we're gonna be continuing to talk about doing metadata, more functionality with metadata, both kind of externally in the ecosystem and also figuring out how we can do that in the Swift storage system itself. But the basic concept here is that we're always gonna be looking to the apps. We're gonna be looking to what are these websites doing? What are these mobile apps doing? What are these backup application doings? What are these server tools doing? And what do they need? Because I truly believe that the purpose of Swift is to offload the hard problems of storage so that you don't have to think about it. All you need to say is, here's my data, give it back to me later and it will take care of the rest. So you can actually focus on building into the value of your application because that's how, that's what you're about. You don't care about storage. Nobody is excited about a hard drive but putting this stuff together with Swift and having a globally distributed file sync and share thing, that's pretty cool. So that's what we're gonna be doing there. If you wanna hear more about what's going on, in room 110 next door, I'm gonna be talking a little bit tomorrow about some of the kind of community stuff about Swift. We've got some other talks in here tomorrow and Wednesday, some cool things, including some stuff on genome sequencing and dumping that into Swift. I'm gonna be giving in the expo hall tomorrow an overview on Arisha codes in Swift. We've got some books to give away at the Swift stack booth. Anyway, so it seems like here is a good place to learn all about Swift and storage and things like that this week, except for a couple of the other things I've indicated. What questions do you have? I think we have a few minutes left, about five minutes left. We're out of time? Completely out of time. I'll be around, I will talk to you later. Thank you for coming. Thank you.