Skip to content
This repository was archived by the owner on Nov 6, 2023. It is now read-only.

Conversation

@cschanaj
Copy link
Collaborator

@cschanaj cschanaj commented Sep 15, 2017

@cowlicks this replaces and closes #12494. thanks!

P.S. eslint error is unexpected, but it should be fine to fix it here.

const nullIterable = Object.create(null, {
[Symbol.iterator]: {
value: function* () {
// do nothing
Copy link

@ghost ghost Sep 15, 2017

Choose a reason for hiding this comment

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

This can be done in a simpler way.

const nullIterator = {
  next() {
    return { done: true };
  }
};

const nullIterable = {
  [Symbol.iterator]: function () {
    return nullIterator;
  }
};

Will also save memory since it will not create a new iterator each time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Having just one name is nice. How about just:

const nullIterable = Object.create(null, {
  [Symbol.iterator]: {
    value: () => ({
      next() {
        return {done: true};
      }
    })
  }
});

Copy link

Choose a reason for hiding this comment

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

@cowlicks const nullIterable = (function* () {})() would be better.

Copy link

Choose a reason for hiding this comment

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

@cowlicks why use Object.create(null, { ...?

Copy link

@ghost ghost Sep 15, 2017

Choose a reason for hiding this comment

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

@cowlicks This will create a new instance of { next() { return { done: true } } } each time.

Copy link

@ghost ghost Sep 15, 2017

Choose a reason for hiding this comment

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

Currently I have this code:

const nullIterator = {
  next() {
    return { done: true };
  }
};

const nullIterable = {
  size: 0,
  [Symbol.iterator]: function () {
    return nullIterator;
  }
};

Copy link
Contributor

Choose a reason for hiding this comment

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

@koops76 see #12577 (comment)

re: new instance of ... thing - that is fine, it should get GC'd immediately anyway

};

const nullIterable = {
[Symbol.iterator]: function *() {
Copy link

Choose a reason for hiding this comment

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

what?

Copy link

Choose a reason for hiding this comment

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

*

Copy link

Choose a reason for hiding this comment

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

Simply change it into () => nullIterator I guess.

Copy link
Collaborator Author

@cschanaj cschanaj Sep 15, 2017

Choose a reason for hiding this comment

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

without * it does not work for me (it is a generator function).

See also https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

Copy link

@ghost ghost Sep 15, 2017

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

Remove the * after fixing this issue.

Copy link

Choose a reason for hiding this comment

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

Remove the * now.


// Empty iterable singleton to reduce memory usage (#12494).
const nullIterator = {
next : () => { done: true }
Copy link

Choose a reason for hiding this comment

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

next: () => ({ done: true })

Copy link

Choose a reason for hiding this comment

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

or next() { return { done: true } }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thanks!

@ghost
Copy link

ghost commented Sep 15, 2017

(function* () {})() is the shortest code for empty Iterable. Use it.

next : () => ({ done: true })
};

const nullIterable = {
Copy link

@ghost ghost Sep 15, 2017

Choose a reason for hiding this comment

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

Simply replace this entire code with const nullIterable = (function* () {})(). Calling a generator function will return a Generator instance which implements both Iterator and Iterable.

Copy link
Contributor

Choose a reason for hiding this comment

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

I choose to create Object.creat(null, ... because the created object wouldn't have extra properties, so it would be harder to misuse. This seemed important because we are using it alongside real data.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, using Object.create(... lets us specify other properties we might want, like size in this case.

Copy link

Choose a reason for hiding this comment

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

Would simply doing { size: 0 } cause a conflict?

Copy link

Choose a reason for hiding this comment

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

Ah, it makes it read only.

log(DBUG, "Ruleset cache hit for " + host + " items:" + cached_item.length);
if (this.ruleCache.has(host)) {
let cached_item = this.ruleCache.get(host);
let len = cached_item && cached_item != nullIterable ? cached_item.size : 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

just add a size property to the nullIterable thing.

@ghost
Copy link

ghost commented Sep 15, 2017

@cowlicks Look at this code:

const nullIterator = Object.create(null, {
  next: { value: function() { return { done: true }; } }
});

const nullIterable = Object.create(null, {
  [Symbol.iterator]: { value: function() { return nullIterator; } }
});

Is it okay to use in your opinion?

// Copy the host targets so we don't modify them.
results = results.concat(this.targets.get(host));
let results = this.targets.get(host);
results.map(result => resultSet.add(result));
Copy link
Contributor

@cowlicks cowlicks Sep 15, 2017

Choose a reason for hiding this comment

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

I'm a little confused by having both results and resultsSet variables. You can just do:

if (this.targets.has(host)) {
  results = new Set([...results, this.targets.get(host)]);
}

if (host.indexOf("..") != -1 || host.length > 255) {
log(WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host);
return null;
if (host.length > 255 || host.indexOf("..") != -1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes sense 👍

}

// Replace each portion of the domain with a * in turn
var segmented = host.split(".");
Copy link
Contributor

Choose a reason for hiding this comment

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

Please avoid renaming and changing this code unless its necessary to the PR. This algorithm is important, but isn't well tested unfortunately.

for (let i=0; i < segmented.length; i++) {
let tmp = segmented[i];
segmented[i] = "*";
results = results.concat(this.targets.get(segmented.join(".")));
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be something like my above comment, (https://github.com/EFForg/https-everywhere/pull/12577/files#r139258106) or maybe a ternary expression like

results = (this.targets.has(segmented.join('.')) ? 
  (new Set([...results, ...this.targets.get(segmented.join('.')]) :
  results);

// check *.z.google.com and *.google.com (we did *.y.z.google.com above)
for (var i = 2; i <= segmented.length - 2; ++i) {
var t = "*." + segmented.slice(i,segmented.length).join(".");
results = results.concat(this.targets.get(t));
Copy link
Contributor

Choose a reason for hiding this comment

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

Please revert this rename. Then just use one of the methods I suggested above to update the results


// Clean the results list, which may contain duplicates or undefined entries
var resultSet = new Set(results);
resultSet.delete(undefined);
Copy link
Contributor

Choose a reason for hiding this comment

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

Keep a results.delete(undefined) around to be safe.

Copy link

Choose a reason for hiding this comment

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

what

@cowlicks
Copy link
Contributor

@koops76 re: #12577 (comment)

It depends on the context. I'd prefer to avoid using 2 names here. I don't think it creating an iterator when iterated matters. It should be garbage collected immediately, and js engines are pretty good at optimizing simple functions like this.

@cschanaj with the size property it would look like:

const nullIterable = Object.create(null, {
  [Symbol.iterator]: {
    value: () => ({
      next() {
        return {done: true};
      }
    })
  },
  size: {value: 0},
});

@cowlicks
Copy link
Contributor

@cschanaj in the future, please try to keep revisions to PR's as the same PR. This makes reviewing easier for me. It is hard to track what changed and what didn't between two similar PR's so I end up re-reading a lot of code. (I'm referring to this and #12494).

There is no need to worry about force pushes or anything.

@cschanaj
Copy link
Collaborator Author

cschanaj commented Sep 16, 2017

@cowlicks modified accordingly, please check. thanks!!

@cschanaj
Copy link
Collaborator Author

@cowlicks Sorry for force pushing a few times. This PR is ready for review and merging now. thanks!

@cschanaj
Copy link
Collaborator Author

cschanaj commented Sep 18, 2017

@cowlicks @Hainish I did not realize that you are modifying rules.js as well. I will rebase this branch in the weekend...

P.S. I have made a mistake in rebasing this. Please do not merge the current branch.

@cowlicks
Copy link
Contributor

@cschanaj I can rebase this if you'd like.

@cschanaj
Copy link
Collaborator Author

thanks!!

@cschanaj
Copy link
Collaborator Author

@cowlicks please merge this if it looks good for you. thank you!!

} else {
util.log(DBUG, "Ruleset cache miss for " + host);
}
util.log(util.DBUG, "Ruleset cache miss for " + host);
Copy link
Contributor

Choose a reason for hiding this comment

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

There are some issues with how this was merged, this line should have been kept (it should be util.DBUG).

@cschanaj
Copy link
Collaborator Author

cschanaj commented Sep 23, 2017

@cowlicks Travis all passing now, please merge this if it looks good. (It has been sort of annoying to rebase a few time and keeping up with the incompatible changes).

@cschanaj
Copy link
Collaborator Author

@cowlicks could you please merge this before the next release?

@cowlicks
Copy link
Contributor

cowlicks commented Oct 3, 2017

@cschanaj sorry we won't have time! It will be in the next release. Totally my fault, I forgot to check back on this after you rebased :(

Thank you for your work!

@cschanaj
Copy link
Collaborator Author

cschanaj commented Oct 6, 2017

@cowlicks Never mind. Please be sure to merge this PR before the next release. 😄

@cowlicks
Copy link
Contributor

merged in #13208 thank you!

@cowlicks cowlicks closed this Oct 17, 2017
@cschanaj cschanaj deleted the user-nullIterable branch October 24, 2017 11:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants