Skip to content

Commit 503737d

Browse files
MichaelCuevasfacebook-github-bot
authored andcommitted
format: apply lints to markdown files
Summary: # Context I was really annoyed w/ the variable formatting of Markdown files. I decided to apply formatting to all the markdown files to make things consistent. # This diff Formats all the markdown files to be consistent. The next diff will enable an option in linttool to enforce formatting in all Markdown files under `eden/fs/**/*` Reviewed By: zertosh Differential Revision: D59930918 fbshipit-source-id: 20964f531fbe6be919e8cc391caf148d5c107ae1
1 parent a92eb43 commit 503737d

30 files changed

Lines changed: 1636 additions & 1586 deletions

eden/fs/benchmarks/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# "Macro" Benchmarks
22

3-
This directory contains benchmarks of EdenFS through its filesystem
4-
and Thrift APIs. Several of these benchmarks allow comparison of
5-
EdenFS's performance to native filesystems.
3+
This directory contains benchmarks of EdenFS through its filesystem and Thrift
4+
APIs. Several of these benchmarks allow comparison of EdenFS's performance to
5+
native filesystems.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# C++ Language Benchmarks
22

3-
Sometimes it's useful to microbenchmark the compiler and standard
4-
library itself. These microbenchmarks allow us to compare fundamental
5-
costs across operating systems, compilers, and standard libraries.
3+
Sometimes it's useful to microbenchmark the compiler and standard library
4+
itself. These microbenchmarks allow us to compare fundamental costs across
5+
operating systems, compilers, and standard libraries.

eden/fs/docs/Caching.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Caching in Eden
2-
===============
1+
# Caching in Eden
32

43
[This captures the state of Eden as of November, 2018. The information below may
54
change.]
@@ -32,10 +31,10 @@ quick succession, and reloading the blob each time would be inefficient.
3231

3332
The design of this cache attempts to satisfy competing objectives:
3433

35-
* Minimize blob reloads under Eden's various access patterns
36-
* Fit in a mostly-capped memory budget
37-
* Avoid performance cliffs under pathological access patterns
38-
* Maximize memory available to the kernel's own caches, since they have the
34+
- Minimize blob reloads under Eden's various access patterns
35+
- Fit in a mostly-capped memory budget
36+
- Avoid performance cliffs under pathological access patterns
37+
- Maximize memory available to the kernel's own caches, since they have the
3938
highest leverage.
4039

4140
The cache has a maximum size (default 40 MiB as of this writing), and blobs are
@@ -50,7 +49,7 @@ experimentation.
5049
One interesting aspect of the blob cache is that Eden has a sense of whether a
5150
request is likely to occur again. For example, if the kernel does not support
5251
caching readlink calls over FUSE, then any symlink blob should be kept in Eden's
53-
cache until evicted. If the kernel *does* cache readlink, then the blob can be
52+
cache until evicted. If the kernel _does_ cache readlink, then the blob can be
5453
released as soon it's been read, making room for other blobs.
5554

5655
A more complicated example is that of a series of reads across a large file.
@@ -61,11 +60,11 @@ blob, Eden evicts the blob from its cache.
6160

6261
Blobs are evicted from cache when:
6362

64-
* The blob cache is full and exceeds its minimum entry count.
65-
* The blob has been read by the kernel and the kernel cache is populated.
66-
* A file inode is materialized and future requests will be satisfied by the
63+
- The blob cache is full and exceeds its minimum entry count.
64+
- The blob has been read by the kernel and the kernel cache is populated.
65+
- A file inode is materialized and future requests will be satisfied by the
6766
overlay.
68-
* The kernel has evicted an inode from its own inode cache after reading some of
67+
- The kernel has evicted an inode from its own inode cache after reading some of
6968
the blob.
7069

7170
## Blob Metadata

eden/fs/docs/Data_Model.md

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1-
Data Model
2-
==========
1+
# Data Model
32

43
EdenFS is designed to serve file and directory state from an underlying source
5-
control system. In order to do this, it has two parallel representations of the
4+
control system. In order to do this, it has two parallel representations of the
65
state: one that tracks the original immutable source control state, and one that
76
tracks the current mutable file and directory structure being shown in the
87
checkout.
98

10-
Source Control Model
11-
====================
9+
# Source Control Model
1210

1311
EdenFS's model of source control state mimics the model used by
14-
[Git](https://git-scm.com/) and EdenSCM. The source control repository is
15-
viewed as an object storage system with 3 main object types: commits, trees
16-
(aka directories), and blobs (aka files).
12+
[Git](https://git-scm.com/) and EdenSCM. The source control repository is viewed
13+
as an object storage system with 3 main object types: commits, trees (aka
14+
directories), and blobs (aka files).
1715

1816
The Git documentation has an
1917
[in-depth overview of the object model](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects).
2018

2119
EdenFS expects to be able to look up objects by ID, where an object ID is an
22-
opaque 20-byte key. In practice, both Git and EdenSCM are content-addressed
20+
opaque 20-byte key. In practice, both Git and EdenSCM are content-addressed
2321
object stores, where the object IDs are computed from the object contents.
2422
However, EdenFS does not strictly care about this property, and simply requires
2523
being able to look up an object from its ID.
2624

2725
These 3 types of objects are chained together in a
2826
[DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph) to allow
29-
representing the full commit history in a repository. Each commit contains the
27+
representing the full commit history in a repository. Each commit contains the
3028
ID(s) of its parent commit(s), the ID of the tree that represents its root
3129
directory, plus additional information like the commit message and author
3230
information.
@@ -35,52 +33,50 @@ information.
3533

3634
Commit objects are referenced by variable-width identifiers whose meaning is
3735
defined by the concrete BackingStore implementation. For example, in Mercurial
38-
and Git, they're 20-byte binary (40-byte hex) strings. Each mount remembers
39-
its parent root ID across EdenFS restarts.
36+
and Git, they're 20-byte binary (40-byte hex) strings. Each mount remembers its
37+
parent root ID across EdenFS restarts.
4038

41-
Tree objects represent a directory and contain a list of the directory
42-
contents. Each entry in the directory has the name of the child entry as well
43-
as the object ID, which refers either to another tree object for a subdirectory
44-
or to a blob object for a regular file. Each entry also contains some
45-
additional information, such as flags tracking whether the entry is a file or
46-
directory, whether it is executable, etc.
39+
Tree objects represent a directory and contain a list of the directory contents.
40+
Each entry in the directory has the name of the child entry as well as the
41+
object ID, which refers either to another tree object for a subdirectory or to a
42+
blob object for a regular file. Each entry also contains some additional
43+
information, such as flags tracking whether the entry is a file or directory,
44+
whether it is executable, etc.
4745

4846
Additionally, tree entry objects can also contain information about the file
49-
size and hashes of the file contents. This allows EdenFS to efficiently
50-
respond to file attribute requests without having to fetch the entire blob data
51-
from source control. Note that these fields are not present in Git's object
52-
model, but are available when the underlying data is fetched from an EdenSCM
53-
Mononoke server.
47+
size and hashes of the file contents. This allows EdenFS to efficiently respond
48+
to file attribute requests without having to fetch the entire blob data from
49+
source control. Note that these fields are not present in Git's object model,
50+
but are available when the underlying data is fetched from an EdenSCM Mononoke
51+
server.
5452

5553
![Example Tree Object](img/tree_object.svg)
5654

57-
The blob type is the final object type and is the simplest. The blob object
58-
type simply contains the raw file contents. Note that blob objects are used to
59-
represent both regular files as well as symbolic links. For symbolic links, the
55+
The blob type is the final object type and is the simplest. The blob object type
56+
simply contains the raw file contents. Note that blob objects are used to
57+
represent both regular files as well as symbolic links. For symbolic links, the
6058
blob contents are the symlink contents.
6159

6260
![Example Blob Object](img/blob_object.svg)
6361

6462
EdenFS's classes representing these source control objects can be found in the
65-
[`eden/fs/model`](../model) directory. The `Tree` class represents a source
63+
[`eden/fs/model`](../model) directory. The `Tree` class represents a source
6664
control tree, and the `Blob` class represents a source control blob.
6765

6866
Note that EdenFS is primarily concerned about showing the current working
69-
directory state, and this mainly only requires using Tree and Blob objects. In
67+
directory state, and this mainly only requires using Tree and Blob objects. In
7068
general, EdenFS does not need to process source control history related
7169
operations, and therefore does not deal much with commit objects.
7270

71+
# Parallels with the Inode State
7372

74-
Parallels with the Inode State
75-
==============================
76-
77-
The classes in `eden/fs/model` represent source control objects. These objects
73+
The classes in `eden/fs/model` represent source control objects. These objects
7874
are immutable, as once a commit is checked in to source control it cannot be
7975
modified, only updated by a newer commit.
8076

8177
In order to represent the current file and directory state of a checkout, EdenFS
82-
has a separate set of inode data structures. These generally parallel the
83-
source control model data structures: a `TreeInode` represents a directory, and
84-
its contents may be backed by a `Tree` object loaded from source control. A
85-
`FileInode` represents a file, and its contents may be backed by a `Blob`
86-
object loaded from source control.
78+
has a separate set of inode data structures. These generally parallel the source
79+
control model data structures: a `TreeInode` represents a directory, and its
80+
contents may be backed by a `Tree` object loaded from source control. A
81+
`FileInode` represents a file, and its contents may be backed by a `Blob` object
82+
loaded from source control.

eden/fs/docs/Futures.md

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,73 @@
11
# Futures and Asynchronous Code
22

3-
This document assumes some working knowledge of folly::Future and folly::SemiFuture. Please read the [Future overview](https://github.com/facebook/folly/blob/master/folly/docs/Futures.md) first.
3+
This document assumes some working knowledge of folly::Future and
4+
folly::SemiFuture. Please read the
5+
[Future overview](https://github.com/facebook/folly/blob/master/folly/docs/Futures.md)
6+
first.
47

58
## Why Future?
69

7-
EdenFS is largely concurrent and asynchronous. The traditional way to write this kind of code would be explicit state machines with requests and callbacks. It's easy to forget to call a callback or call one twice under rarely-executed paths like error handling.
10+
EdenFS is largely concurrent and asynchronous. The traditional way to write this
11+
kind of code would be explicit state machines with requests and callbacks. It's
12+
easy to forget to call a callback or call one twice under rarely-executed paths
13+
like error handling.
814

9-
To make asynchronous code easier to reason about, Folly provides `folly::Future` and `folly::Promise`. Each Future and Promise form a pair, where `folly::Future` holds the eventual value and Promise is how the value is published. Readers can either block on the result (offering their thread to any callbacks that may run) or schedule a callback to be run when the value is available. `folly::Promise` is fulfilled on the writing side.
15+
To make asynchronous code easier to reason about, Folly provides `folly::Future`
16+
and `folly::Promise`. Each Future and Promise form a pair, where `folly::Future`
17+
holds the eventual value and Promise is how the value is published. Readers can
18+
either block on the result (offering their thread to any callbacks that may run)
19+
or schedule a callback to be run when the value is available. `folly::Promise`
20+
is fulfilled on the writing side.
1021

1122
## Why SemiFuture?
1223

13-
The biggest problem with Future is that callbacks may run either on the thread calling `Future::then` or on the thread calling `Promise::set`. Callbacks have to be written carefully, and if they acquire locks, any site that calls `Future::then` or `Promise::set` must not hold those locks.
24+
The biggest problem with Future is that callbacks may run either on the thread
25+
calling `Future::then` or on the thread calling `Promise::set`. Callbacks have
26+
to be written carefully, and if they acquire locks, any site that calls
27+
`Future::then` or `Promise::set` must not hold those locks.
1428

15-
`folly::SemiFuture` is a reaction to these problems. It's a Future without a `SemiFuture::then` method. Assuming no use of unsafe APIs (including any `InlineExecutor`), callbacks will never run on the thread that calls `Promise::set`. Any system with an internal thread pool that cannot tolerate arbitrary callbacks running on its threads should use `SemiFuture`.
29+
`folly::SemiFuture` is a reaction to these problems. It's a Future without a
30+
`SemiFuture::then` method. Assuming no use of unsafe APIs (including any
31+
`InlineExecutor`), callbacks will never run on the thread that calls
32+
`Promise::set`. Any system with an internal thread pool that cannot tolerate
33+
arbitrary callbacks running on its threads should use `SemiFuture`.
1634

1735
## Why ImmediateFuture?
1836

19-
`folly::Future` and `folly::SemiFuture` introduce significant overhead. A `Future`/`Promise` pair hold a heap-allocated, atomic refcounted `FutureCore`. In EdenFS, it's common to make an asynchronous call that hits cache and can answer immediately. Heap allocating the result is comparatively expensive. We introduced `facebook::eden::ImmediateFuture` for those cases. ImmediateFuture either stores the result value inline or holds a SemiFuture.
37+
`folly::Future` and `folly::SemiFuture` introduce significant overhead. A
38+
`Future`/`Promise` pair hold a heap-allocated, atomic refcounted `FutureCore`.
39+
In EdenFS, it's common to make an asynchronous call that hits cache and can
40+
answer immediately. Heap allocating the result is comparatively expensive. We
41+
introduced `facebook::eden::ImmediateFuture` for those cases. ImmediateFuture
42+
either stores the result value inline or holds a SemiFuture.
2043

2144
## When should I use which Future?
2245

2346
There are reasons to use each Future.
2447

25-
  | `Future` | `SemiFuture` | `ImmediateFuture`
26-
--- | --- | --- | ---
27-
Storage is heap-allocated | yes | yes | no
28-
Callbacks run as early as the result is available | yes | no | no
29-
Callbacks may run on the fulfiller's thread | yes | no | no
30-
Callbacks may run immediately or asynchronously | yes | no | yes
31-
sizeof, cost of move() | void* | void* | Depends on sizeof(T) with minimum of 40 bytes as of Oct 2021
48+
|   | `Future` | `SemiFuture` | `ImmediateFuture` |
49+
| ------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------ |
50+
| Storage is heap-allocated | yes | yes | no |
51+
| Callbacks run as early as the result is available | yes | no | no |
52+
| Callbacks may run on the fulfiller's thread | yes | no | no |
53+
| Callbacks may run immediately or asynchronously | yes | no | yes |
54+
| sizeof, cost of move() | void\* | void\* | Depends on sizeof(T) with minimum of 40 bytes as of Oct 2021 |
3255

33-
`folly::Future` should be used when it's important the callback runs as early as possible. For example, measuring the duration of internal operations.
56+
`folly::Future` should be used when it's important the callback runs as early as
57+
possible. For example, measuring the duration of internal operations.
3458

35-
SemiFuture or ImmediateFuture should be used when it's important that chained callbacks never run on internal thread pools.
59+
SemiFuture or ImmediateFuture should be used when it's important that chained
60+
callbacks never run on internal thread pools.
3661

37-
ImmediateFuture should be used when the value is small and avoiding an allocation is important for performance. Large structs can use unique_ptr or shared_ptr.
62+
ImmediateFuture should be used when the value is small and avoiding an
63+
allocation is important for performance. Large structs can use unique_ptr or
64+
shared_ptr.
3865

39-
It's important to note that, when a callback and its closures hold reference counts or are larger than the result value, it can be worth using Future, because the callbacks are collapsed into a value as early as possible. SemiFuture, even if the SemiFuture is held by an ImmediateFuture, will not collapse any chained callbacks until the SemiFuture is attached to an executor.
66+
It's important to note that, when a callback and its closures hold reference
67+
counts or are larger than the result value, it can be worth using Future,
68+
because the callbacks are collapsed into a value as early as possible.
69+
SemiFuture, even if the SemiFuture is held by an ImmediateFuture, will not
70+
collapse any chained callbacks until the SemiFuture is attached to an executor.
4071

4172
## Safetyness and caveats
4273

@@ -73,14 +104,16 @@ As a general rule of thumb, any use of `folly::InlineLikeExecutor` is widely
73104
unsafe and should never be used. This is primarily due to forcing `Promise::set`
74105
to execute the `folly::Future` callbacks in the context of the fulfiller' thread
75106

76-
For instance, if we re-use the previous example, but where the `threadPool` is an
77-
`InlineLikeExecutor` the `setValue` will also execute both continuation before
78-
returning.
107+
For instance, if we re-use the previous example, but where the `threadPool` is
108+
an `InlineLikeExecutor` the `setValue` will also execute both continuation
109+
before returning.
79110

80111
This has been known to cause deadlocks in the past. This includes:
81-
- `folly::SemiFuture::toUnsafeFuture` and any `Unsafe` methods as these are merely wrappers on `.via(&InlineExecutor::instance())`,
82-
- `folly::Promise::getFuture` for the same reason,
83-
- `folly::SemiFuture::via(&QueuedImmediateExecutor::instance())`
112+
113+
- `folly::SemiFuture::toUnsafeFuture` and any `Unsafe` methods as these are
114+
merely wrappers on `.via(&InlineExecutor::instance())`,
115+
- `folly::Promise::getFuture` for the same reason,
116+
- `folly::SemiFuture::via(&QueuedImmediateExecutor::instance())`
84117

85118
`folly::InlineLikeExecutor` also have the downside to be incompatible with
86119
`folly::coro::Task` which is Folly's coroutine implementation.
@@ -98,5 +131,6 @@ execute eagerly unless attached to an executor (and thus becoming
98131

99132
## TODO
100133

101-
* Unsafely mapping ImmediateFuture onto Future with .via(QueuedImmediateExecutor)?
102-
* What about coroutines?
134+
- Unsafely mapping ImmediateFuture onto Future with
135+
.via(QueuedImmediateExecutor)?
136+
- What about coroutines?

eden/fs/docs/Globbing.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
EdenFS supports glob patterns through the following interfaces:
44

5-
* Ignore files (e.g. `.gitignore`)
6-
* `globFiles` Thrift API
5+
- Ignore files (e.g. `.gitignore`)
6+
- `globFiles` Thrift API
77

88
## Ignore Files
99

10-
EdenFS uses *ignore files* to exclude files in the `getScmStatus` Thrift API
10+
EdenFS uses _ignore files_ to exclude files in the `getScmStatus` Thrift API
1111
(used by `hg status`, for example). The syntax for EdenFS' ignore files is
1212
compatible with the syntax for [`gitignore` files][gitignore] used by the Git
1313
version control system, even when an EdenFS checkout is backed by a Mercurial
@@ -17,12 +17,12 @@ repository.
1717

1818
EdenFS interprets the following tokens specially within glob patterns:
1919

20-
* `**`: Match zero, one, or more path components.
21-
* `*`: Match zero, one, or more valid path component characters.
22-
* `?`: Match exactly one valid path component characters.
23-
* `[`: Match exactly one path component character in the given set of
20+
- `**`: Match zero, one, or more path components.
21+
- `*`: Match zero, one, or more valid path component characters.
22+
- `?`: Match exactly one valid path component characters.
23+
- `[`: Match exactly one path component character in the given set of
2424
characters. The set is terminated by `]`.
25-
* `[!`, `[^`: Match exactly one path component character *not* in the given set
25+
- `[!`, `[^`: Match exactly one path component character _not_ in the given set
2626
of characters. The set is terminated by `]`.
2727

2828
EdenFS glob patterns are compatible with [`gitignore` patterns][gitignore] used

0 commit comments

Comments
 (0)