YapDatabaseExtensions icon indicating copy to clipboard operation
YapDatabaseExtensions copied to clipboard

Feature/separate value and metadata

Open JimRoepcke opened this issue 9 years ago • 3 comments

Dan, thanks for making YapDatabaseExtensions!

This PR contains some sutble but signficant changes I consider important for improving the performance and flexibility of this framework.

Metadata changes

This PR improves the handling metadata by YapDatabaseExtensions. I see there have been some previous attempts at reforming the metadata handling but none had been merged yet. I hope this solution is found to be acceptable.

The var metadata property and associatedtype MetadataType as been removed from the Persistable protocol.

YapDatabase does not place a constraint on the types of metadata that can be associated with values, and this is a useful feature. Having a single MetadataType per Persistable type reduced this flexibility.

An important performance design aspect of metadata in YapDatabase is the ability able to read and write it independently of the value. Unfortunately, with the current design, when you have a Persistable with a MetadataType, all reads will do an extra read for the metadata and then set the metadata on the value. This means twice the number of reads (even when the metadata isn't needed after the read) and creating a copy of the value when value types are used, as value types are immutable. If one used objects for their Yap values they'd have to make them mutable which isn't compatible with Yap's sharing policy. In practice, values and metadata do tend to be written together, but for reads the opposite is true.

It is still possible to read/write a value and a metadata at the same time - the methods in the "With[Object|Value]Metadata" files have been renamed to have "with metadata" in the name. For example, write is now writeWithMetadata. These "with metadata" methods take and return a YapItem<Value, Metadata>, which is a simple new struct akin to a tuple, containing the value, metadata and their associated type information since it's generic. This is preferable to a tuple because anonymous tuple types cannot be extended, while structs obviously can. By using this type-rich YapItem, the desirable type-safety features in YapDatabaseExtensions are not impacted.

Additional changes

Additionally, the methods that query for multiple YapDB.Index (such as readAtIndexes) no longer flatMap the return value, so it is now easy to determine which YapDB.Index were not found in the database. If one doesn't need this information they can easily flatMap the return value.

How to test

All tests have been updated and pass.

I merged danthorpe:development into my branch just before submitting this PR. It merged with no conflicts.

JimRoepcke avatar Oct 08 '16 20:10 JimRoepcke

Hi @JimRoepcke - I'm sort of right in the middle of updating to Swift 3.0 at the moment. Will look through your proposal tomorrow. Thanks so much for your contribution!

danthorpe avatar Oct 08 '16 21:10 danthorpe

Thanks Dan - FYI I'm happy to reformulate my diff for Swift 3 once it's merged. Since the changes are so repetitive I can probably do most of them with a few regexes :)

JimRoepcke avatar Oct 08 '16 21:10 JimRoepcke

One thing I forgot to mention in the description is that with the removal of the metadata property, it's now easier to adapt any value type to becoming Persistable, because it's trivial to implement collection and identifier in an extension, but not possible to implement metadata in an extension.

This means we can keep our domain types free of Yap-isms, and add them at the layer of our architecture where we concern ourselves with persistence by introducing YapDatabase, ValueCoding and YapDatabaseExtensions.

JimRoepcke avatar Oct 18 '16 21:10 JimRoepcke