Skip to content
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

[jruby] cleanup/refactor extension code #1934

Merged

Conversation

kares
Copy link
Contributor

@kares kares commented Oct 16, 2019

There's some anti-patterns regarding JRuby ext / Java to revisit (still an ongoing effort).
The Java ext part is confusing at times - initializing parts twice (e.g. XmlDocument's node).

Relevant changes :

  • avoid ns-cache being double backed by a map + another key list (use just map backing)
    also introduce a cache-key as using arrays was weird - potentially leaky on some scenarios
  • do not construct ext wrapper objects when internally XML API objects are sufficient
  • cleaner and more explicit way of initializing (document) internals for XmlNodeSets
  • align with JRuby's toJava convention (will also now work for any Node not just Document)
  • review some of the internals and remove dead-code
  • do not silently swallow potentially fatal exception from backend

Nokogiri is a bit heavy on memory on times - there's a few attempts to reduce allocations here.

NOTE: includes #1930 (to avoid potential conflict resolution) should be without conflicts after its merged.

This also could use some raw performance numbers.

}

try{
int res = node.compareDocumentPosition(otherNode);
if ((res & FIRST_PRECEDES_SECOND) == FIRST_PRECEDES_SECOND) {
return context.getRuntime().newFixnum(-1);
return context.runtime.newFixnum(-1);
Copy link

Choose a reason for hiding this comment

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

Avoid too many return statements within this method.

@@ -116,7 +117,7 @@ private static Object fromRubyToObject(final Ruby runtime, IRubyObject obj) {
}
if (obj instanceof XmlNodeSet) return obj;
if (obj instanceof RubyArray) {
return XmlNodeSet.newXmlNodeSet(runtime.getCurrentContext(), ((RubyArray) obj).toJavaArray());
return XmlNodeSet.newNodeSet(runtime, ((RubyArray) obj).toJavaArray());
Copy link

Choose a reason for hiding this comment

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

Avoid too many return statements within this method.

} catch (Exception ex) {
return context.getRuntime().newFixnum(-2);
return context.runtime.newFixnum(-2);
Copy link

Choose a reason for hiding this comment

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

Avoid too many return statements within this method.

}

return context.getRuntime().newFixnum(-2);
return context.runtime.newFixnum(-2);
Copy link

Choose a reason for hiding this comment

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

Avoid too many return statements within this method.

this.href = href;
}

@Override
Copy link

Choose a reason for hiding this comment

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

Method equals has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.

@codeclimate
Copy link

codeclimate bot commented Oct 16, 2019

Code Climate has analyzed commit 604a0db and detected 37 issues on this pull request.

Here's the issue category breakdown:

Category Count
Complexity 13
Duplication 24

The test coverage on the diff in this pull request is 100.0% (80% is the threshold).

This pull request will bring the total coverage in the repository to 46.3%.

View more on Code Climate.

... since it does (unwanted) auto-conversion toJava
every time a new XML document is being created, since it causes
class-path scanning (considerable slow-downs esp. in multi-threaded
envs)
interestingly the String[] key was pretty much a leak
not perfect but at least more performing than before
potentially avoid double initialization of document node
also make document cache explicit - no null side effects
and Document.wrap impls - override toJava on XmlNode
that way any node type can unwrap its Java 'backend'
just loop node-list children directly internally
make it explicit that node-set needs to initialize (@document)
+ cleanup some of the internal helpers
@kares kares force-pushed the jruby-review-8_DETACHED-merge-back branch from 40bfade to 604a0db Compare October 16, 2019 18:40
visitor.leave(node);
}

void acceptChildren(ThreadContext context, IRubyObject[] nodes, SaveContextVisitor visitor) {
Copy link

Choose a reason for hiding this comment

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

Method acceptChildren has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.

private void addElements(Node n, List<Node> nodes, boolean isFirstOnly) {
NodeList children = n.getChildNodes();
if (children.getLength() == 0) return;
private static List<Node> getElements(Node node, final boolean firstOnly) {
Copy link

Choose a reason for hiding this comment

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

Method getElements has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.

private void stabilzeAttrValue(Node node) {
if (node == null) return;

private static void stabilizeAttrs(Node node) {
Copy link

Choose a reason for hiding this comment

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

Method stabilizeAttrs has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.

clearXpathContext(getNode());
return this;
}

private void removeNamespceRecursively(ThreadContext context, XmlNode xmlNode) {
private void removeNamespaceRecursively(XmlNode xmlNode) {
Copy link

Choose a reason for hiding this comment

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

Method removeNamespaceRecursively has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring.

String prefixValue = prefix.isNil() ? "" : (String) prefix.toJava(String.class);
String hrefValue = (String) href.toJava(String.class);
Ruby runtime = prefix.getRuntime();
static XmlNamespace createImpl(Node owner, IRubyObject prefix, String prefixStr, IRubyObject href, String hrefStr) {
Copy link

Choose a reason for hiding this comment

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

Method createImpl has 5 arguments (exceeds 4 allowed). Consider refactoring.

@flavorjones
Copy link
Member

@kares Thanks so much for all the work that went into this patch set. Very much appreciated!

@flavorjones flavorjones merged commit 8a1c981 into sparklemotion:master Nov 26, 2019
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.

2 participants