About
Friends
-
Loading…updates about 1 month ago -
Loading…giania 5 days ago -
Loading…maledei 2 days ago -
Loading…maxchad over 2 years ago -
Loading…Echolicht 9 days ago -
Loading…heather 15 days ago -
Loading…yarnivore over 2 years ago -
Loading…c3o 1 day ago -
Loading…brianamerige 8 months ago -
Loading…warbler 8 months ago
Click here to check if anything new just came in.
January 19 2012
“Getting Into Modeling With CouchCocoa”
I gave a webcast last month for O’Reilly, and it’s up on YouTube now so you can watch it at your leisure. Here’s the abstract:
It can be very liberating to store your Couchbase app’s data as free-form dictionaries, free of the rigid schema of a relational database. But there’s a lot to be said for the syntactic comforts and conveniences of modeling your data as native Cocoa objects with predeclared @properties, the way CoreData does. Don’t fret – the CouchCocoa framework lets you do both, even in the same database. During this webcast I’ll show you how to acquire the glamor of an object model, while still letting your NoSQL freak-flag fly.
December 19 2011
Announcing TouchDB
[I just posted this to the Couchbase Mobile community mailing list.]
TouchDB is a project I’ve been feverishly working on for a few weeks. It’s an investigation into the feasibility of a CouchDB-compatible database rewritten from the ground up for mobile apps. The comparison I like to make is that “if CouchDB is MySQL, then TouchDB is SQLite”. In fact, it uses SQLite as its underlying storage engine. You can read a longer justification for it on its wiki, as well as an FAQ and design document.
— It speaks CouchDB’s replication protocol. I’m pretty serious about that; I’m even documenting the protocol.
— It also understands a large subset of the REST API, enough so that it works with CouchCocoa. I’ve got a clone of Grocery Sync working as one of the demo apps in the project.
— The current implementation is for iOS. If the investigation pans out we’ll port it to Android, and possibly other platforms.
TouchDB is certainly not ready for prime-time yet, but here are some current statistics to whet your appetite:
• Code size of an ‘empty’ iOS app with nothing in it but TouchDB: ~150k.
• Time to initialize TouchDB and open a database, on iPad 2: ~100ms (cold) or ~60ms (warm).
• Size of source code: ~4000 lines of Objective-C (plus another ~2500 lines from some existing utility libraries.)
What’s left to do? Probably a lot — that infamous “second 90%”. Prominently:
• Attachments
• Reduce functions and grouping
• Filters for views and replication
• Performance tuning
See the issue tracker for more.
So, what does this mean for Couchbase Mobile? Honestly, we don’t know yet. It may be that TouchDB turns out to be so awesome that it replaces embedded-CouchDB entirely in Couchbase Mobile on iOS and Android. It may be that there are still scenarios where embedded-CouchDB works better and is worth the extra overhead for some developers, in which case we’ll still support it. This is not a product announcement; it’s a technical announcement of something that isn’t a product yet, because we like to do our development in the open. We’d love your feedback or even contributions.
November 10 2011
My presentation from Keeping It Realtime
I gave another talk about Couchbase/CouchDB at the Keeping It Realtime conference this week in Portland. This one is titled “_ch_ch_changes: CouchDB/Couchbase Notifications And Replications”, and the slides are now up on slideshare.
I had a great time. The conference itself was pretty exciting, even if some of the content was over my head (I’m not primarily a web developer, server-side isn’t how I roll, and I’ve only just started learning about node.js this week!) Plus: Portland. OMG, I love Portland.
August 10 2011
Couchbase news (and my preso)
My new employer is doing well:
MOUNTAIN VIEW, Calif. – August 10, 2011 – Couchbase, the leading NoSQL database company, today announced it has secured $14 million in a Series C round of financing led by venture capital firm Ignition Partners with participation from the company’s existing investors Accel Partners, Mayfield Fund, and North Bridge Venture Partners. The company has also reserved an additional $1 million for investment from strategic customers and partners. The new funding will be used to further invest in NoSQL product development, support the adoption and growth of Couchbase in enterprise organizations, and support international expansion.
On the heels of its inaugural CouchConf developer conference, held July 29 in San Francisco with more than 300 attendees from around the world, Couchbase announced a Series C round of financing, bringing the company’s total funding to $30 million.
CouchConf was a great time. I really enjoyed meeting developers, and learning more about Couchbase from the other presentations. The slides from my own talk on Couchbase Mobile for iOS are now online (minus the gratuitous Keynote transitions) if you’d like to take a look.
May 16 2011
Fudge
I’ve just released a new open-source project, a small one—Fudge-Cpp, a fast C++ library for reading and writing Fudge messages.
I hadn’t heard of Fudge either, till a few weeks ago, but it’s a type of thing that’s always interested me: a generic structured binary data format. A quick elevator pitch would be “it’s sorta like JSON, except more compact and faster to parse”. (It’s also sorta like Mac property-lists, YAML, etc.) So, it lets you turn collections of scalars, strings, arrays and dictionaries into a standardized blob of data that can be sent over a network or stored on disk or whatever.
From the Fudge website:
“Fudge is primarily useful in situations where you have:
- Data exchanging between nodes in a distributed system; where
- You want to be able to do meaningful work with data without knowing at compile time the precise message format; and
- Performance and message size are important; or
- A requirement to encode data and translate between efficient binary encodings, and more accepted text encodings (XML, JSON) depending on the communications channel.”
The obvious advantage of a binary format for this is that it’s faster to parse. Instead of having to tokenize the input and walk through it counting braces and commas, and converting sequences of digits into numbers, you just read big-endian numbers from the stream and interpret them as types and byte-counts. This can also make the data smaller, if the format is careful to use the smallest number of bytes to represent a number (which Fudge does). It’s especially compact for messages containing payloads of binary data like images, audio, or digital signatures, since those blobs don’t have to be converted to Base64 (which is 25% larger.)
A more subtle advantage is that the library can use less memory. In fact, Fudge-Cpp basically allocates no memory at all from the heap. How does it manage this? When the library returns the caller an object representing a data value from the parsed message (a scalar, string, array, etc.) it doesn’t allocate that object on the heap. Instead, it just returns a pointer to where that value is stored in the binary message itself. This really is a valid C++ object pointer; it’s just that the object’s members have the exact same layout as the corresponding Fudge data.
(Now, there is a bit of impedance mismatch that adds overhead to accessing the data this way. For one thing, on a little-endian CPU every multi-byte numeric value will need to be byte-swapped when accessed. And random access to dictionaries and object arrays is O(N) since they are basically linked lists. But the overhead is low.)
This library isn’t a world-changing project; it was more of a fun diversion for me over a few weekends. I’ve done this sort of thing before—Ottoman uses similar memory-saving pointer tricks, and AEGizmos was literally the first code I ever wrote at Apple back in 1991—and it’s always fun to twiddle bits this way.
April 17 2011
MYCrypto update (0.5)
I’ve been making little updates to the MYCrypto library for a few months, and after the latest batch I did some housekeeping—fixing iOS and 64-bit build errors, updating the docs—and decided to dignify them with a new version number, 0.5.
Notable improvements:
- More certificate I/O functionality. You can now import and export PKCS12 (.p12) files, which are encrypted archives that contain a private key as well as its cert.
- More certificate trust validation APIs, including read/write access to user trust settings.
- Access to X.509 cert extensions like key-usage.
- Can verify signatures that use algorithms other than SHA-1, and parse certs that use such algorithms.
- MYMockKey, a testing fixture that lets you test code that uses digital signatures without having to generate or use real key-pairs.
If you infer from this list that I’ve been working on an app that manages X.509 certs, I won’t deny it :) Maybe I’ll have more to say about that soon.
March 15 2011
Dudes, this is so not REST
The documentation for Rdio’s new API begins:
It’s simple to make requests to Rdio’s REST API. It’s built on widely used standards and conventions so there are libraries for most common web development platforms. All method calls are made as POST requests to http://api.rdio.com/1/. Arguments are sent as application/x-www-form-urlencoded, just like when a browser submits a form. The name of the method is passed as the ‘method’ argument. [Emphasis mine.]
What’s wrong with this? Well, the first bolded point is immediately contradicted by the ones that follow. Specifically, this cannot be a REST API, because it uses only one URL and one HTTP method. Two of the key features of HTTP-based REST are that
- It’s object-oriented, where objects are identified by URLs. Each request’s URL identifies what object it operates on.
- The methods to invoke on the objects are primarily indicated by the request’s method (GET, PUT, POST, DELETE). In fact this is why Tim Berners-Lee used the word “method” in the HTTP protocol in the first place.
So in a real REST API there would be a URL representing “my friends”, and a client could GET that URL to retrieve a list of friends, POST to it to add a friend (resulting in a new URL/resource representing that friend), PUT to a friend’s URL to update details, and DELETE to that URL to remove the friend relation. Instead, the actual Rdio API has a couple of dozen ad-hoc verbs including “addFriend” and “removeFriend”. I didn’t see one to get a list of friends or get info about a friend, but there is an Rdio-specific “get” verb that might work for those things. “Get” seems nicely general, but then for some reason there are also sixteen other specific getters ranging from “getActivityStream” to “getTracksInCollection”.
So it’s clear that Rdio’s “REST” API, like many other recent “REST” APIs such as DropBox’s*, isn’t REST at all. It’s more of an ad-hoc RPC scheme, which is ironic because there’s traditionally been a lot of enmity between REST proponents vs. those of RPC protocols like XML-RPC and SOAP. The SOAP boffins must be chortling behind their WSDLs at this.
Maybe we should just give up on the term REST, since it’s become so diluted as to mean nothing more than “HTTP API that’s not as hard to use as SOAP”?
- The hacky DropBox API especially annoys me because there’s already a perfectly good standardized and widely adopted REST API for most of what DropBox does.
March 12 2011
May 02 2010
py2rb: A Python-to-Ruby Porting Assistant
I’ve never figured out whether I prefer Python or Ruby, so I’ve written things in both languages. Sometimes I start in one, then change my mind and decide I’d rather use the other. Unfortunately, changing over is painful, even though both have fairly similar syntax. For instance, converting to Ruby means inserting zillions of “end” statements!
Having a need to do this recently, I lazily looked around for a script that would do the grunt-work of Python-to-Ruby translation. I couldn’t find one, so I ended up writing one myself. And I’ve uploaded it for the benefit of others who might have the same need, and who might even improve it.
So here it is: py2.rb. Use it wisely. In particular, pay attention to the caveat found in the file’s header comments:
This script just does the obvious, easy transformations, giving you more time to work on the harder ones :) It is NOT a real parser, just a bunch of kludgy regex operations, so it can’t do anything fancy. It may get some things wrong, and won’t even attempt some other things that it’s very likely to get wrong. The output will definitely have to be hand edited by someone familiar with both languages, before it can be expected to compile as Ruby, much less run correctly. The goal is simply to require less hand editing, and less mechanical replacing, than you would have had to do without this script.
It’s in the public domain. “Do what thou wilt” shall be the whole of the law.
Note: Please don’t comment with Python advocacy or, worse, anti-Ruby flames. That’s not the point. I like Python fine; I just prefer to remain promiscuous. And I think it’s ultimately in everyone’s interest for ideas to be able to flow from one form of expression to another.
February 09 2010
December 08 2009
Ottoman Status
Yes, I’m still working on Ottoman (my append-only multiversion-concurrent storage library). As the code grows in size and complexity, so it grows in its resistance to being changed, but as Piet Hein said and I never tire of quoting:
Problems worthy of attack
Prove their worth by fighting back.
I just pushed my latest changes up to bitbucket.org. What’s new?
Variable-sized top-level index. Previously, the hash data structure used a top level array of 256 hashtables. I’ve now made that ‘256’ a variable that scales with the number of records. This saves a lot of room for smaller datasets. (Sounds easy, right? I thought so too. But it ended up triggering significant changes to the file format and algorithms and took a lot of debugging.)
The return of the trees! part un. I started this as a project to learn about B+trees, but when I got to the point of implementing the append-only multiversion stuff I did it with hashtables first because it’s more straightforward that way, and the tree code went into the freezer. Well, it’s back now. There is a “new” Tree class that can be used to read and write persistent B+trees. It’s not yet integrated into the top-level Ottoman class, though, so you can only use it on its own, not intermixed with hash-tables, and without the API for tracking versions.
The next task is of course to integrate the tree API into the Ottoman class. But more than that, it will be entwined with the hashtable such that trees will serve as searchable indexes into the data store. So the hashtable will provide extremely fast but unordered access via a unique “record ID”, but you can build as many indexes as you like that will use ordered secondary keys (of your choice) to look up hash values.
At that point, I believe Ottoman will be ready to serve as a substrate for HTML local data storage, for implementing a CouchDB-compatible database (a la JSONDB), or for other fun databasey purposes.
November 29 2009
ZSync
ZSync is a new Mac/iPhone library that uses my BLIP P2P networking protocol:
“ZSync is an open source syncing library designed to allow easy syncing of data between an iPhone/iPod Touch and the OS X Desktop.
ZSync utilizes the BLIP library and Apple’s Sync Services to allow easy and seamless syncing of data.”
It’s still in early development though, with a first public release expected in January:
Right now the code is in a private GitHub repository while the initial framework and protocols are fleshed out. This is expected to go public in January of 2010. Until then we are keeping the development team very small so that we can flesh out the design without a lot of overhead.
This looks like it’ll be super useful for iPhone apps that want to integrate with their Mac siblings, especially since their design won’t require you to have the Mac app running while you sync.
November 07 2009
Dogfooding Chrome
As everyone knows who works in the pet-food industry (or computer software for that matter), it can be hard to start eating your own dogfood. Case in point: I just this week set Chrome to be my default browser, though I’ve been working on it for four months now.
Partly that’s because when I started in July the Mac version of Chrome was too immature; and partly it’s because a web browser is something you need to have running and working all the time—especially since the Chrome project’s bug tracker and code-review tool are web-based.
But Mac Chrome is quite stable enough to use now, and as I haven’t been doing much Chrome development on this MacBook Pro lately (it takes too long to compile compared to my souped-up Mac Pro) I’ve installed the latest dev-channel build and replaced Safari with it in my Dock and as my default browser.
It’s hard to get used to a new browser, after all these years. I remember that I dropped IE 5 like a hot rock as soon as Safari became useable, but that’s because IE sucked so badly on OS X (as you youngsters may not remember.) But Safari is a great browser. Chrome’s great too, but in different ways, and the Mac version’s not finished yet so there are some missing bits.
I should note that I generally don’t work on the user-visible parts of Chrome, rather the underlying WebKit engine; so I haven’t been focusing on the UI much, or noticing the features being added, until experiencing them as an end-user.
In Chrome’s favor:
- It definitely feels faster. At work I’ve been obsessing over some micro-benchmarks, but in regular use what I notice is simply that pages come up more quickly. I think a lot of this has to do with DNS pre-fetching, because DNS query times here at home can often be slow.
- The UI of the tabs is better than Safari’s. I like that they take up less room (though without eliminating the title bar the way the Safari 4 beta did), and the transition animations when opening/closing/detaching tabs are extremely slick, definitely Apple-quality.
- The downloads shelf at the bottom of the window is more visible than Safari’s little Downloads window, which always gets hidden behind the browser.
- The list of recently-closed tabs at the bottom of the new-tab page is very thoughtful and handy. In general I find the new-tab page more useful than Safari’s, if less flashy.
Rough edges (remember, this is a pre-beta build):
- PDF display doesn’t work well. There’s no way to switch pages yet (making multi-page documents unusable), there’s no zooming, the Save command doesn’t work, and often the renderer process starts redrawing constantly and eating up CPU time.
- The only indication you have that a page is loading is the little 16×16-pixel spinning circle that replaces the tab’s icon. I like the visual design of this, but it’s too hard to find. I still miss the big progress bar in the address bar from Safari 1-3. (Cursor feedback would be nice—wasn’t there a browser once that put a little wristwatch badge on the arrow cursor?)
- The bookmarking UI is still unfinished and unpolished. In particular, there’s no way to edit/move/delete bookmarks yet. I love the idea of being able to quickly bookmark by clicking a Google-y star icon, but in practice it pops up a floating panel for choosing a folder, which makes me think about where to put it just like Safari’s bookmark sheet does. I’d rather the star button just added it to an “Unsorted” folder that I could open and organize later.
- Autofill doesn’t seem to work as well as in Safari. For example, it won’t autofill login forms until I type in the username; I think this may be a security feature, but I find it annoying.
I’ve been impressed by Chrome’s stability too, for a pre-beta development build. The app hasn’t crashed once, and I haven’t even gotten the “Oh, snap!” page that shows that a renderer process crashed. (I’ve seen plugins crash a few times, but that’s probably Flash’s fault, and as in Safari on 10.6, this doesn’t affect the browser or even the rest of the page.)
One thing I’m really looking forward to is extensions. Safari’s a closed system, and I’ve long been envious of the plethora of cool plug-ins available for Firefox. I’m looking forward to using, and maybe developing, extensions for Chrome. (In the current dev channel Mac release, extensions can be installed, but the ones I’ve tried don’t do anything yet.)
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
