Skip to content

Commit da9fa64

Browse files
committed
Multiple fixes as discussed:
- Settle on UnixTime, remove mention of epoch entirely - Better explain fixed32 rationale for the fractional part
1 parent 3205ce5 commit da9fa64

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

UNIXFS.md

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,16 @@ message Data {
6161
optional uint64 hashType = 5;
6262
optional uint64 fanout = 6;
6363
optional uint32 mode = 7;
64-
optional TimeSpec mtime = 8;
64+
optional UnixTime mtime = 8;
6565
}
6666
6767
message Metadata {
6868
optional string MimeType = 1;
6969
}
7070
71-
message TimeSpec {
72-
required int64 EpochSeconds = 1;
73-
74-
optional fixed32 EpochNanoseconds = 2;
71+
message UnixTime {
72+
required int64 Seconds = 1;
73+
optional fixed32 FractionalNanoseconds = 2;
7574
}
7675
```
7776

@@ -96,9 +95,9 @@ UnixFS currently supports two optional metadata fields:
9695
- The remaining 20 bits are reserved for future use, and are subject to change. Spec implementations **MUST** handle bits they do not expect as follows:
9796
- For future-proofing the (de)serialization layer must preserve the entire uint32 value during clone/copy operations, modifying only bit values that have a well defined meaning: `clonedValue = ( modifiedBits & 07777 ) | ( originalValue & 0xFFFFF000 )`
9897
- Implementations of this spec must proactively mask off bits without a defined meaning in the implemented version of the spec: `interpretedValue = originalValue & 07777`
99-
* `mtime` -- A two-element structure ( `EpochSeconds`, `EpochNanoseconds` ) representing the modification time in seconds relative to the unix epoch `1970-01-01T00:00:00Z`. In contexts where an mtime is mandatory ( e.g. FUSE interfaces ) implementations must treat an unspecified mtime as `0`.
100-
- `EpochSeconds` represents the amount of seconds after **or before** the epoch. Implementations must be able to gracefully handle negative mtime, even if such a value is not applicable within their domain ( e.g. a POSIX filesystem )
101-
- `EpochNanoseconds` represents the fractional part of the mtime as the amount of nanoseconds. The valid range for this value is the integer range `[1, 999999999]`. If a fractional part outside of this range is encountered, implementations should consider the entire metadata block invalid and abort processing it. Note that **a fractional value of `0` is NOT valid** - omit the nanosecond value altogether to represent whole seconds.
98+
* `mtime` -- A two-element structure ( `Seconds`, `FractionalNanoseconds` ) representing the modification time in seconds relative to the unix epoch `1970-01-01T00:00:00Z`. In contexts where an mtime is mandatory ( e.g. FUSE interfaces ) implementations must treat an unspecified mtime as `0`.
99+
- `Seconds` represents the amount of seconds after **or before** the epoch. Implementations must be able to gracefully handle negative mtime, even if such a value is not applicable within their domain ( e.g. a POSIX filesystem )
100+
- `FractionalNanoseconds` represents the fractional part of the mtime as the amount of nanoseconds. The valid range for this value is the integer range `[1, 999999999]`. If a fractional part outside of this range is encountered, implementations should consider the entire metadata block invalid and abort processing it. Note that **a fractional value of `0` is NOT valid** - omit the nanosecond value altogether to represent whole seconds.
102101

103102
### Deduplication and inlining
104103

@@ -200,20 +199,20 @@ This scheme would see metadata stored in an external database.
200199

201200
The downsides to this are that metadata would not be transferred from one node to another when syncing as [Bitswap] is not aware of the database, and in-tree metadata
202201

203-
### TimeSpec protobuf datatype rationale
204-
205-
#### EpochSeconds
202+
### UnixTime protobuf datatype rationale
206203

207-
The integer portion of the epoch is represented on the wire using a varint encoding. While this is inefficient for
208-
negative values, it avoids introducing zig-zag encoding. Negative epoch values will be exceedingly rare, and there
209-
could very well be value in having such cases stand out, while at the same keeping the "usual" positive values easy
210-
to eyeball. The varint representing the time of writing this text is 5 bytes long. It will remain so until
211-
October 26, 3058 ( 34,359,738,367 )
204+
#### Seconds
212205

213-
#### EpichNanoseconds
214-
Since fractional values will very often be > 2^28 nanoseconds, that part is represented as a 4-byte `fixed32`,
215-
[as per google's recommendation](https://developers.google.com/protocol-buffers/docs/proto#scalar).
206+
The integer portion of UnixTime is represented on the wire using a varint encoding. While this is
207+
inefficient for negative values, it avoids introducing zig-zag encoding. Values before the year 1970
208+
will be exceedingly rare, and it would be handy having such cases stand out, while at the same keeping
209+
the "usual" positive values easy to eyeball. The varint representing the time of writing this text is
210+
5 bytes long. It will remain so until October 26, 3058 ( 34,359,738,367 )
216211

212+
#### FractionalNanoseconds
213+
Fractional values are effectively a random number in the range 0 ~ 999,999,999. Such values will exceed
214+
2^28 nanoseconds ( 268,435,456 ) in most cases. Therefore, the fractional part is represented as a 4-byte
215+
`fixed32`, [as per google's recommendation](https://developers.google.com/protocol-buffers/docs/proto#scalar).
217216

218217
[multihash]: https://tools.ietf.org/html/draft-multiformats-multihash-00
219218
[CID]: https://docs.ipfs.io/guides/concepts/cid/

0 commit comments

Comments
 (0)