-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why so many traits? #27
Comments
While refactoring iterator code (see PR #28) I realized you probably wanted to avoid duplication (thinking inheritance-based OOP?). This could be achieved more cleanly using contain and delegate pattern. I'm willing to refactor it if you agree. |
Phew, so, if you have a look at the initial commit date (March 22, 2014), this library not only predates Rust 1.0, but was also the first larger library I wrote on. So you can flag a lot of parts as "learning to build interfaces over C libs". It is (mostly) an exercise. The trait separation is indeed not to fake inheritance, but to separate independent interfaces. It makes sure that things only rely on a subset of the rest of the library. I don't quite agree that traits are only for abstraction, but that's certainly up for debate. I would probably not write this interface again, though. The full reasoning for this? Well, probably lost in time. :) I deliberately didn't want this library as a low-level leveldb interface with external crates providing a higher one, this is the road https://github.com/andrew-d/leveldb-rs takes. As a quick fix for user annoyance, probably a prelude module for simple import of everything would make sense. I agree that this could be more general (a hint of that can be found in the fact that the key type is in its own library). But mostly, I stopped developing this library and just maintain whatever patches come into it. This is mostly due to leveldb itself being superseded by rocksdb anyways and me rarely using it :). I also wouldn't like to fundamentally break the interface before doing some kind of major jump. That being said, if you'd like to take the library and work on improvements, I'll happily do reviews and answer questions. I can also give you commit access if you want to. |
Out of curiosity, I just looked it up: the design of this interface even predates associated types, which landed around January 2015. So, considering it "somewhat antique" is probably a good way of approaching it ;). https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md |
Hmm, I'm not sure if Fortunately, this project of mine isn't too urgent. |
I'd be very happy with any kinds of API extensions that make the library more useful, especially in data-heavy environments. The only thing I have is that I'd like to not slowly break the interface for existing users, but this could certainly be done by deciding to mark a stable interface at some point and then moving towards a 2.0. |
Can I just add on to this that abstraction isn't really necessary for a low-level library like leveldb, especially if development stopped and you do not plan to add support for, let's say, RocksDB. If you would be willing to accept a pull request, I can help and try to clean up the library a little. If you are too worried about breaking the API, I could also just fork it. |
@kaimast leveldb-sys is the library you are looking for then as a base library, which I still maintain. leveldb is mostly in this state because of broad usage. The abstraction is entirely intentional though at a lot of places, as the leveldb C api exposes a lot of concepts in a very low level fashion that Rust has high-level concepts for. Iterators are the prime example and the (documentation-mandated) lifetime relationship between the LevelDB core type and the things it produces (like the iterators), too. My main gripe about the current interface is using traits where not needed, the library should not define traits that no one else implements. On the rocksdb note: there are rocksdb crates out there and I don't feel like a unified interface over both is useful. Final products will use one over the other for reasons other than the Rust interface and switching between the two is done for effect. The practical benefit of maintaining support for both is small in my reading. TBH, I don't believe the current leveldb interface is gradually amendable and starting fresh is probably better. Happy to answer questions, also through another channel (I'm @skade on discord and |
Maybe not. Disclaimer: I'm not an expert on their interfaces so it still might not make sense. |
@Kixunil RocksDB has a much expanded API over LevelDB. Just as an illustration, the number of exported types is quite a bit larger. https://github.com/facebook/rocksdb/blob/master/include/rocksdb/c.h#L71-L127 Also, functions as basic as Any library wanting to support both will have to go for the lowers common denominator. Given that you usually choose rocksdb because of the extended functionality, I don't feel this merits a lot of work, |
Thanks for explaining! IDK why I got the impression that the difference is just performance. |
I'm wondering why there are so many traits in the crate. Traits are used for abstractions, but from what I've seen they don't abstract anything. Wouldn't it be simpler to not have them? Or, if abstraction is desirable, move the traits into separate crate and generalize them little bit more. This way they could be implemented for various databases. (So people who want to use other databases don't need to have leveldb in their dependencies.)
I imagine something like this:
The text was updated successfully, but these errors were encountered: