Skip to content

fix: allow mtime and mode to be optional #38

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

Merged
merged 10 commits into from
Dec 19, 2019

Conversation

achingbrain
Copy link
Member

@achingbrain achingbrain commented Dec 12, 2019

Upgrades protons to take advantage of new hasFoo type methods to detect if the user has set mode and mtime or not.

Also updates the constructor:

// old
new UnixFS('file', buf)

// new
new UnixFS('file', buf) // still supported
new UnixFS() // defaults to 'file' without data
new UnixFS({ // all fields are optional, apart from `type`
  type: 'file',
  data: buf,
  blockSizes: [],
  mode: parseInt('0755', 8),
  mtime: new Date()
})

This is to not have the boolean-trap style constructor of:

new UnixFS(type, data, bufferSizes, mode, mtime)

Uses protobuf messages to enable having mode and mtime as actually
optional values.
@@ -79,37 +79,33 @@ describe('unixfs-format', () => {
expect(data.blockSizes).to.not.deep.equal(unmarshalled.blockSizes)
})

it('default mode for files', () => {
it('mode', () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way I can convince you to make the spec follow golang's fileMode() specification: golang/go#25422 (comment), or alternatively the less-rigorously defined POSIX st_mode struct?

Having already paid for transporting a 32bit value, it seems so odd to not populate the rest of the bits if we have them. In js-ipfs you can of course simply mask them off, the point is for the spec to allow it...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything in the spec that prevents us filling the higher bits with subsequent PRs?

From my understanding all we've done so far is specify the equivalent of the file mode component of st_mode but the datatype can fit all of st_mode so there's nothing to stop us going further in the future.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@achingbrain yes you are correct. I crossed wires with not explicitly masking off future bits for when we do add them, I left a comment to the effect above

@achingbrain achingbrain force-pushed the make-mtime-and-mode-optional branch from f6e99c9 to 04ea7a1 Compare December 12, 2019 16:21
src/index.js Outdated
const obj = new Data(types[decoded.Type], decoded.Data)
obj.blockSizes = decoded.blocksizes

if (decoded.mode) {
obj.mode = decoded.mode
obj.mode = decoded.mode.value

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per ipfs/specs#231, this needs to mask off with 07777

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not in the spec yet, will do a further PR if it gets added.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, let's be careful. If we get a file that has extra bits, we should round-trip those bits. Otherwise, it's hard to add features later.

@achingbrain achingbrain marked this pull request as ready for review December 17, 2019 10:55
src/index.js Outdated
const DEFAULT_FILE_MODE = parseInt('0644', 8)
const DEFAULT_DIRECTORY_MODE = parseInt('0755', 8)

function Data (arg1, arg2) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we be more descriptive in the name of the args ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arg0, arg1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kid!

src/index.js Outdated
return new Data(arg1, arg2)
}

if (arg1 == null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need to support null ? can't it be just

function Data (arg1 = { type: 'file }, arg2)

src/index.js Outdated

return new Data({
type: types[decoded.Type],
data: decoded.hasData() ? decoded.Data : undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
data: decoded.hasData() ? decoded.Data : undefined,
data: decoded.getData(),

src/index.js Outdated
type: types[decoded.Type],
data: decoded.hasData() ? decoded.Data : undefined,
blockSizes: decoded.blocksizes,
mode: decoded.hasMode() ? decoded.mode : undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mode: decoded.hasMode() ? decoded.mode : undefined,
mode: decoded.getMode(),

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe getMode returns 0 if unset. We want it to actually be unset.

Note: Actually, do we not want to return the default mode for the file type (then remove it on serialize)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getMode does indeed return 0 if unset. We pass undefined here so we'll get 0755 for directories and 0644 for files.

The setting of defaults is done in the constructor so we don't have to duplicate it here as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

humm the protons readme seems to suggest undefined maybe i read it wrong

src/index.js Outdated
data: decoded.hasData() ? decoded.Data : undefined,
blockSizes: decoded.blocksizes,
mode: decoded.hasMode() ? decoded.mode : undefined,
mtime: decoded.hasMtime() ? new Date(decoded.mtime * 1000) : undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mtime: decoded.hasMtime() ? new Date(decoded.mtime * 1000) : undefined
mtime: decoded.getMtime()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto above.

README.md Outdated
}

message Metadata {
optional string MimeType = 1;
required string MimeType = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, will remove.

src/index.js Outdated
type: types[decoded.Type],
data: decoded.hasData() ? decoded.Data : undefined,
blockSizes: decoded.blocksizes,
mode: decoded.hasMode() ? decoded.mode : undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe getMode returns 0 if unset. We want it to actually be unset.

Note: Actually, do we not want to return the default mode for the file type (then remove it on serialize)?

src/index.js Outdated
data: decoded.hasData() ? decoded.Data : undefined,
blockSizes: decoded.blocksizes,
mode: decoded.hasMode() ? decoded.mode : undefined,
mtime: decoded.hasMtime() ? new Date(decoded.mtime * 1000) : undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto above.

Co-Authored-By: Alan Shaw <alan.shaw@protocol.ai>
@achingbrain achingbrain merged commit 2f02eb5 into master Dec 19, 2019
@achingbrain achingbrain deleted the make-mtime-and-mode-optional branch December 19, 2019 17:05
achingbrain added a commit that referenced this pull request Feb 19, 2020
* perf: concurrent file import

Adds two new options:

`fileImportConcurrency`

This controls the number of files that are imported concurrently.
You may wish to set this high if you are importing lots of small
files.

`blockWriteConcurrency`

This controls how many blocks from each file we write to disk at
the same time.  Setting this high when writing large files will
significantly increase import speed, though having it high when
`fileImportConcurrency` is also high can swamp the process.

It also:

1. Flattens module options because validating deep objects was
  clunky and the separation of access to config sub objects within
  this module isn't very good
1. Replaces `superstruct` and `deep-extend` with `merge-options`
  which is better suited for merging options and is smaller
1. Replaces `async-iterator-*` modules with the more zeitgeisty
  `it-*` namespace

Supersedes #38, sort of. No batching but atomicity guarantees are 
maintained and performance gains are broadly similar with the right
tuning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants