Commit Graph

567 Commits

Author SHA1 Message Date
Stefan Filip
c305e13566 manfiest: mark FileMetadata as Copy
Summary:
`Node` is marked as `Copy`. `FileMetadata` is not much more than `Node` so it
seems pretty clear that it should be marked `Copy`.

Reviewed By: DurhamG

Differential Revision: D14347657

fbshipit-source-id: 939abf88087bc8c6f942047a08d6a4a0d61e053f
2019-03-07 11:20:07 -08:00
Stefan Filip
5b370ffb72 manifest: move tree link to a separate file
Summary:
Cleaning up the `mod.rs` file so that it provides more signal.
`Link` is an internal implementation detail that other internal components may depend on so it is a great candidate to be moved to a dedicated file.

Differential Revision: D14347654

fbshipit-source-id: e5b5a42faf1e9f9c4a0591e5bd94182391ed511f
2019-03-07 11:20:07 -08:00
Stefan Filip
6d9dc154ca manifest: add flush function to manifests
Summary:
Save, finalize, flush, they mean about the same thing.

The first thing to note is that this implementation is not complete because
the parents are not correctly passed into the hashing function.

The second thing is that store failures make the code a little more complex
than it would have been otherwise.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292713

fbshipit-source-id: 807d7a385a62cb5f4948f1781d3146eaa6502ca9
2019-03-05 16:12:48 -08:00
Stefan Filip
25edcc014b manifest: inline store_entry_to_links
Summary:
This function is a bit on it's own with the removal of the pair conversion.
Since it is used in only one place it makes sense to inline it.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292712

fbshipit-source-id: abbf1dc70d61c0ad039f5bc5ed5277d0770e3899
2019-03-05 16:12:48 -08:00
Stefan Filip
c5cc253234 manifest: refactor tests to use store::Entry::from_elements
Summary:
Working on the save mechanism I realized that links_to_store_entry is not that
useful because we can avoid the failure states where we would try to serialize
an ephemeral node. I am removing that function and converting the code that was
using that function to using the Entry constructor directly.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292714

fbshipit-source-id: 54ef46670319c27d90fc78511a1eb6abf47d3acf
2019-03-05 16:12:48 -08:00
Stefan Filip
43fb573c23 types: add explicit conversions from owned paths types to unsized ref
Summary:
There are scenarios where an &PathComponentBuf or a &RepoPath will show up.
An example when using get from a HashMap. These are not the references that we
are looking for. We want &PathComponent and &RepoPath respectively. Adding
explicit conversions.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292711

fbshipit-source-id: 29f4de25c2ffebf7f009e4f2515e0ba8f0371ae0
2019-03-05 16:12:47 -08:00
Stefan Filip
765659d505 manifest: update tree manifest to take owneship of Store
Summary:
This is what Rust is telling us to do. The situation that triggers this update is
writing to the store. Particularly when the store is an in memory hashmap we
need to have a mutable borrow to the hashmap to insert into it. From a general
point of view this means that any sharing of the store between different
instances of a manifest will have to be handled by the struct that implements
the `Store` trait.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292716

fbshipit-source-id: 6e789527dbdf3cd3ffe967f4900251bf31f7d6b2
2019-03-05 16:12:47 -08:00
Stefan Filip
fcc560357a types: add RepoPathBuf::pop()
Summary:
The practical aspect of this method comes when iterating over a tree and having
to maintain the current path. When going deep we will be pushing path
components and when coming back we will be poping path components.

I am not sure if it makes sense to return the path component or not. However I
believe that we should return some sort of error when RepoPath is empty.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14292715

fbshipit-source-id: 4ef1e10de7a60775340063b5baa317d3d626bc64
2019-03-05 16:12:47 -08:00
Stefan Filip
14f26aa355 manifest: add remove implementation for tree
Summary:
Removes a file from the manifest. Nothing special for it.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14276645

fbshipit-source-id: 85e8ffd6cffee426c73eb627484dfa5a866a364b
2019-03-05 16:12:47 -08:00
Stefan Filip
1e9b7fafe9 manifest: refactor get_link out of manifest::get to allow code reuse
Summary:
It is going to be useful in tests to check how certain internal nodes change
so adding an api that allows fetching an internal node.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276642

fbshipit-source-id: 9a3e488be6031f7b4727a8643f64970dcec8c400
2019-03-05 16:12:47 -08:00
Stefan Filip
e2b06628cd manifest: update Tree::get() to use RepoPath::parents()
Summary:
This removes the need for the local buffer for the parent.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276648

fbshipit-source-id: a9378ea592d502ddf2dcdc35fe6ffa9ba213bc14
2019-03-05 16:12:47 -08:00
Stefan Filip
3c2c09f431 manifest: update tree::Manifest::insert
Summary:
Using the recently added path utilities so that we don't keep a secondary
parent buffer around.
Updating the file insert logic so that it is readable and intuitive.

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D14276649

fbshipit-source-id: 8e7e835814f0039645601abbf1b701e8c1ed3697
2019-03-05 16:12:47 -08:00
Stefan Filip
dd2bfc6c04 types: add test for to_owned() on Path types
Summary:
I had an issue where I incorrectly ended up with a &&RepoPath. While debugging
I added this tests to validate my sanity. I think that keeping these tests is
useful for the future.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276640

fbshipit-source-id: d7e1cedc80b3a0ecb97e5a0c80fc4eea110e943f
2019-03-05 16:12:47 -08:00
Stefan Filip
f71814f8e2 types: add dedicated iterator type for RepoPath::components()
Summary:
The current implementation has some gotchas that are related to how the `split`
method is implemented for `&str`. The new implementation is more clear for how
we construct path components

(Note: this ignores all push blocking failures!)

Differential Revision: D14276639

fbshipit-source-id: 1a22c177ba570915b7952eee78ed9191f7b72976
2019-03-05 16:12:47 -08:00
Stefan Filip
27c0d1c991 types: add RepoPath::last_component()
Summary:
Return the last component of the path. The empty path, `RepoPath::empty()`
does not have any components so `None` is returned in that case.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276643

fbshipit-source-id: 9c4caf455891e77d03f22d81b39e3a34ae61ffcc
2019-03-05 16:12:47 -08:00
Stefan Filip
ed6e6245ad types: add RepoPath::parent()
Summary:
`RepoPath::parent` returns the parent of the path. The empty path,
`RepoPath::empty()` does not have a parent so `None` is returned in that case.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276641

fbshipit-source-id: fc60da9750dc76e4f598dd483a63adc180135cb4
2019-03-05 16:12:47 -08:00
Stefan Filip
736cfe89bd types: add RepoPath::split_last_component()
Summary:
Tries to split the current `RepoPath` in a parent path and a component. If the
current path is empty then None is returned. If the current path contains only
one component then the pair that is returned is the empty repo path and a path
component that will match the contents `self`.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276644

fbshipit-source-id: e85a22f65cc267e48f12af6bf6b40c7673b7eaaa
2019-03-05 16:12:47 -08:00
Stefan Filip
68b6897a78 types: Add RepoPath::parents()
Summary:
An iterator for the parent directories of a path.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276646

fbshipit-source-id: 2b580ee8d762db5113110ec9b09ec3a093a1063a
2019-03-05 16:12:47 -08:00
Stefan Filip
ffffdd2a44 types: Add RepoPath::empty()
Summary:
This diff defines the empty `RepoPath`. This path is equivalent with the root
of the repository.
Also adding a method to check whether a `RepoPath` matches this special path.

(Note: this ignores all push blocking failures!)

Differential Revision: D14276647

fbshipit-source-id: 6e9ad5957ad39a711a1680bd084f448bb9d73f87
2019-03-05 16:12:47 -08:00
Arun Kulshreshtha
e6909b217b edenapi: pretty print keys in debug output
Summary: Now that `Key` has a `Display` implementation that produces useful output (namely the filenode and path as strings rather than bytes), we can use it to get better debug output.

Differential Revision: D14310544

fbshipit-source-id: ace5b76f07aa1216b5e9aae22dc7b6bd561e9560
2019-03-04 19:22:19 -08:00
Xavier Deguillard
5ede544f83 asyncpacks: remote unecessary Arc<Mutex> from the mutable packs
Summary:
Since all the methods of an aync mutable pack are taking the ownership of self,
there can only be one accessor to self, and therefore the Mutex is not
required. For the same reasons, the Arc can be removed.

This saves a bunch of atomic operation when operating on the mutable packs.

Reviewed By: kulshrax

Differential Revision: D14287252

fbshipit-source-id: 792bc41aa0dc372e2114dfca4895cca7083f3a56
2019-03-04 13:48:11 -08:00
Xavier Deguillard
073c33a933 asyncpacks: AsyncWrapper only accept Sync types
Summary:
Since most of the datastore/historystore types are already Sync, we don't
really need to wrap them in a Mutex. For the ones that aren't Sync, we can
easily wrap them in a Mutex and pass that to AsyncWrapper.

Reviewed By: kulshrax

Differential Revision: D14287253

fbshipit-source-id: 0f5c04c651592561403caa6e4627017ab1731d0a
2019-03-04 13:48:11 -08:00
Arun Kulshreshtha
2ab9df3b9d types: implement Display for Key
Summary: Implement the `Display` trait for `Key`. This is important for human-readable output for debugging since both filenode and path inside the `Key` are stored as byte arrays, which are just printed out as numbers by the derived `Debug` implementation.

Differential Revision: D14294970

fbshipit-source-id: a601dc9a0c23ac40894ec27135171928f5635507
2019-03-04 12:11:23 -08:00
Stefan Filip
82bbd0326f manifest: improve store imports in tree/mod.rs
Summary:
We currently alias many of the imports from the store submodule. It is nicer
if we just import the submodule name and prefix with the submodule.

Differential Revision: D14276638

fbshipit-source-id: 6661df7f9cb5d976b11153003f653a1f66301c9a
2019-03-03 12:35:50 -08:00
Arun Kulshreshtha
6181da2178 edenapi: add method to get file history
Summary: Add a `get_history()` method to the `EdenApi` trait that queries the API server's `getfilehistory` endpoint and writes the resulting history entries to a historypack in the user's cache.

Differential Revision: D14223269

fbshipit-source-id: bf69c767f5a89177c36e755250330dbbbc219e4f
2019-02-28 15:42:17 -08:00
Arun Kulshreshtha
1f6435f6c1 asyncpacks: add add_entry() function
Summary: Add an `add_entry()` method, similar to D14162781 which did the same for non-async packs.

Differential Revision: D14246980

fbshipit-source-id: 8c8f507f2e0133d80d826d04345df7b41d6013a3
2019-02-28 12:47:13 -08:00
Arun Kulshreshtha
a430c04f81 revisionstore: use AsRef<Path> in constructors
Summary: `AsRef<Path>` is more ergonomic than `&Path` since the former can accept `PathBuf`, `String`, etc.

Differential Revision: D14223167

fbshipit-source-id: 12d26adaa63855c339e04734c19d6697624f9c9e
2019-02-27 12:43:43 -08:00
Stefan Filip
d543e91b45 types: order imports in path.rs
Summary:
The order of imports we're trying to follow is: std, remote crates
(ie: crates.io), local crates (ie: fbcode crates), and crate local. A new line
in between each group can be used to prevent rustfmt from re-ordering them.

Reviewed By: singhsrb

Differential Revision: D14243163

fbshipit-source-id: fbbb07693af14b13ae6b3f4e788972d99193fd64
2019-02-27 10:00:40 -08:00
Stefan Filip
6825832b19 manifest: order imports
Summary:
The order of imports we're trying to follow is: std, remote crates
(ie: crates.io), local crates (ie: fbcode crates), and crate local. A new line
in between each group can be used to prevent rustfmt from re-ordering them.

Reviewed By: singhsrb

Differential Revision: D14243162

fbshipit-source-id: 6fc2cceb3d6834b602be20b8b8f74e0f61b227e1
2019-02-27 10:00:40 -08:00
Stefan Filip
b20f22f0a7 manifest: implement tree entry serialization/deserialization
Summary:
This diff focuses on addding deserialization. Because the most effective way
 of testing deserialization is doing round-trip conversions we also implement
 serialization.

 `manifest::tree::store::Entry` is the structure that is in charge of perfroming
 serialization and deserialization. We update the Store trait to interface with
 this new object.

Differential Revision: D14178264

fbshipit-source-id: bb12262c181a518ba4111d40c079d6836ec44301
2019-02-27 10:00:40 -08:00
Stefan Filip
5809294733 manifest: replace crate lazy-init with once_cell
Summary:
The `once_cell` crate is more flexible than `lazy-init`. It has more types,
a richer api, recent updates and more features.

Differential Revision: D14232727

fbshipit-source-id: 14aeb34a96e094069bb8dc3fb5efcf5b5707ce8c
2019-02-27 10:00:40 -08:00
Stefan Filip
29e6198309 manifest: make FileMetadata members public
Summary:
The purpose of `FileMetadata` is to be a data container. Using the
`FileMetadata` implies accessing the underlying values. That means that the
underlying values need to be `public`.

Differential Revision: D14178260

fbshipit-source-id: 8b8e5ead23d47962498f991152c2a5fd94ac3c74
2019-02-22 15:42:45 -08:00
Stefan Filip
59ce91e857 manifest: add Arbitrary implementation for FileType and FileMetadata
Summary: These implementations are going to used in quickcheck tests.

Differential Revision: D14178259

fbshipit-source-id: 0bded67deab3422b4aad53666c14cf195ea1b0d4
2019-02-22 15:42:45 -08:00
Stefan Filip
e496e01d8f types: Add as_byte_slice() to RepoPath and PathComponent
Summary:
`as_bytes` is useful for interacting with code that is written in reference
to a `slice` or when attempting to serialize them. It is fine to serialize
these paths using their underlying representation because we request that they
be normalized.

Reviewed By: quark-zju

Differential Revision: D14178263

fbshipit-source-id: 36529e2ae47580ae4014ae279df98b35eac5484a
2019-02-22 15:42:45 -08:00
Stefan Filip
5c04aead8f types: add Arbitrary implementations for RepoPathBuf & PathComponentBuf
Summary:
Implementing these traits allows easy use of `RepoPath` and friends in
quickcheck tests.
It is tricky to implement `PathComponentBuf`. I believe that most strings will
end up being a valid `PathComponent` so I think that it is reasonable to loop
until a valid string is found. To note generating Arbitrary Unicode `char`s is
implemented using a loop where random bytes are validated against the `char`
constructor.

Reviewed By: quark-zju

Differential Revision: D14178262

fbshipit-source-id: 759486a2053b851f8259d7cc03eee1cd69893f9f
2019-02-22 15:42:44 -08:00
Stefan Filip
49e7e99131 types: add public constant functions Node::{len, hex_len}
Summary:
These constant can be useful for parsing byte streams that we expect to contain
`Node`s. These constant should replace all potential hardcoding of values that
intend to represent the byte lengths for `Node`.

Differential Revision: D14178261

fbshipit-source-id: 34471151b5d253504e32a9e8b039608c1d4943fe
2019-02-22 15:42:44 -08:00
Xavier Deguillard
91b1a56c3a radixbuf: make it compile on windows
Summary:
Instead of using the rand crate imported into quickcheck, we can use the
rand crate directly.

Reviewed By: quark-zju

Differential Revision: D14174653

fbshipit-source-id: c848f139765b9e458d374790227399f0ad836af6
2019-02-22 10:22:30 -08:00
Xavier Deguillard
9f05c94729 watchman_client: fix windows build
Summary:
The watchman_client crate relied on unix-only crates for both
unix_socket_transport and command_line_transport. Let's not compile
these on windows.

Reviewed By: quark-zju

Differential Revision: D14174654

fbshipit-source-id: 67d26d1799e71a1bf20af1a57a687249f5dce227
2019-02-22 10:22:30 -08:00
Xavier Deguillard
ee8c0812fd revisionstore: fix test on windows
Summary: Changing the permission on the packfile failed due to the file being opened.

Reviewed By: quark-zju

Differential Revision: D14174652

fbshipit-source-id: 356ac4748fd69e660a6cb9e63367a87489755e5e
2019-02-22 10:22:30 -08:00
Xavier Deguillard
7c34139c06 revisionstore: fix compilation warnings
Summary:
Rust tells us that Rng::choose and Rng::shuffle should be replaced by
SliceRandom::choose and SliceRandom::shuffle, so let's do it.

Reviewed By: singhsrb

Differential Revision: D14178565

fbshipit-source-id: 586eb2891f1c2cab0a3435c1b4ae8f870e7a3c25
2019-02-21 18:39:21 -08:00
Arun Kulshreshtha
09d3ade23a types: use untagged serialization for Parents
Summary:
Tell serde to use an [untagged representation](https://serde.rs/enum-representations.html#untagged) of this enum. This means that `Parents::None` will map to a null value, `Parents::One` will map to an array representing a `Node`, and a `Parents::Two` will map to an array of 2 arrays representing `Node`.

Using CBOR serialization, this means that these variants are 1 byte, 21 bytes, and 43 bytes respectively.

Differential Revision: D14174309

fbshipit-source-id: 0217a23c4ee5409ab293525d7b6e5ae969b5504d
2019-02-21 16:34:25 -08:00
Arun Kulshreshtha
eb3b97d91a types: implement FromIterator and IntoIterator for Parents
Summary: Add implementations for `FromIterator` and `IntoIterator` for the `Parents` type to make it more ergonomic to use.

Reviewed By: quark-zju

Differential Revision: D14172511

fbshipit-source-id: 5ba848c1dfbb8cc23ed19c9dc816616f5ed7af5f
2019-02-21 14:39:04 -08:00
Arun Kulshreshtha
942d9d984a revisionstore: allow adding a PackHistoryEntry to a MutableHistoryPack
Summary: Add a convenience function to `MutableHistoryPack` to add an entry from a `PackHistoryEntry` struct.

Differential Revision: D14162781

fbshipit-source-id: a0e07f34b9231011a339ce63adcef8ab55a0555e
2019-02-21 14:39:04 -08:00
Arun Kulshreshtha
3344341ad9 types: split HistoryEntry into two types
Summary:
This changes the way we represent history entries for the Eden API by splitting them into two types and putting them into a new `historyentry` module.

- `PackHistoryEntry` is the same as the old `HistoryEntry`, containing the fields required to add this entry to a `MutableHistoryPack` (namely a `Key` and a `NodeInfo`).
- `LooseHistoryEntry` is a history entry containing the information that would normally be present in a line of the history text in the remotefilelog loose file format.

There are several reasons why it makes sense to have both of these types:

- The existing remotefilelog code in Mononoke uses a type very similar to `LooseHistoryEntry` internally, and as such having a similar type for API calls simplifies code on the server side.

- `PackHistoryEntry` contains redundant information (in particular, the file path may be duplicated up to 3 times). While it's structure is ideal for `revisionstore`'s in-memory data structures, for transmitting data, this redundancy is undesirable, especially since the client already has the file path (it is required to make the request in the first place).

- Conversions between these two representations include some subtle details that are tricky to get right. By putting the conversion in one canonical place, we can avoid having to duplicate this conversion logic in multiple places.

Differential Revision: D14162783

fbshipit-source-id: 63e0a060709916f21613442b75370f4d34a04f04
2019-02-21 14:39:04 -08:00
Arun Kulshreshtha
45a299b82d types: add Parents type representing a node's parents
Summary:
Add a type representing a node's parents. Mercurial nodes can have zero, one, or two parents; this is normally represented as an array of two node hashes, with any absent parents denoted with a null hash. This representation is not particularly Rustic because it allows for invalid combinations (such as a null p1 and non-null p2) to be represented. By using an enum, invalid values are unrepresentable, making code using this type simpler (due to not requiring validation logic).

This type will be used later in the stack to represent parents in history entries.

Reviewed By: quark-zju

Differential Revision: D14162782

fbshipit-source-id: dfff3ecc76dea114e0044839216d080b7f34a506
2019-02-21 14:39:04 -08:00
Stefan Filip
65ea22225b manifest: add Durable variant for Links
Summary:
`Durable` nodes are inner nodes that come from storage. Their contents can be shared between multiple instances of Tree. They are lazily evaluated. Their children list will be read from storage only when it is accessed.

The inner structure of a durable link poses an interesting question related to handling failures: what do we do when we have a failure when reading from storage?
We can cache the failure or we don't cache it. Caching it is mostly fine if we had an error reading from local storage or when deserializing. It is not the best option if our storage is remote and we hit a network blip. On the other hand we would not want to always retry when there is a failure on remote storage, we'd want to have a least an exponential backoff on retries. Long story short is that caching the failure is a reasonable place to start from.

The lazy-init crate is useful for modeling the lazy initialization model that we have for durable node links. See docs at https://docs.rs/lazy-init/0.3.0/lazy_init/

Reviewed By: quark-zju

Differential Revision: D14142928

fbshipit-source-id: 077f708b38e2ace772f30b3392445326ce17f47c
2019-02-21 12:01:28 -08:00
Stefan Filip
d1317c251c manifest: add store trait
Summary:
The store abstracts the data that we need from the store for TreeManifest. This is not a long term abstraction, mostly something that we can code against until we write the real parsing logic from the real data store.

Adding a TestStore implementation that we can use in tests and debug.

Reviewed By: quark-zju

Differential Revision: D14142930

fbshipit-source-id: 7f2d4f05a7b7e63758db9247cdbcd51541c88ec0
2019-02-21 12:01:28 -08:00
Stefan Filip
0f567c8a11 manifest: move tree implementation to module
Summary: Preparing to add the store abstraction for the tree manifest. This store implementations are going to be tied to the tree implementation and should be made private from the rest of the crate. To do this we move the tree to a module.

Reviewed By: quark-zju

Differential Revision: D14142929

fbshipit-source-id: 588d597e1248fc2e632c9efe03f08ba3d491e8cd
2019-02-21 12:01:28 -08:00
Stefan Filip
bab2c60c1d manifest: move Link::methods into Tree functions
Summary: manifest::tree::Link has several convenience functions. In the grand scheme of things this is something that we will want because they are common operations. The problems is that the node structure is currently changing rapidly and the additional layer of abstraction is hindering iteration. I don't know the exact shape that the nodes will have and trying different things out is easier when the Tree functions use the nodes directly.

Reviewed By: quark-zju

Differential Revision: D14142926

fbshipit-source-id: 5e4e8f4d3e1b19fd14dcc290a3dea4271b502d97
2019-02-21 12:01:28 -08:00
Arun Kulshreshtha
4dfba9862d Add conversions from Mononoke to Mercurial history entries
Summary: Add conversions between the `HgFileHistoryEntry` type produced by Mononoke and the `edenapi_types::HistoryEntry` type shared between Mercurial and Mononoke. The latter can be serialized and sent from the API server to the Mercurial client, and will be used for HTTP history fetching.

Reviewed By: quark-zju

Differential Revision: D14079338

fbshipit-source-id: 2123c88310f633f87d8c92405382d5046874dfee
2019-02-20 15:29:22 -08:00