Skip to content

Post migration to JDK 8: Functions, lambdas and others #83

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

Closed
wants to merge 0 commits into from

Conversation

guidomedina
Copy link

@guidomedina guidomedina commented Oct 24, 2016

Post migration to JDK 8:

  • Functions, lambdas and use of computeIfAbsent to behave like a true cache.
  • Migrate date formatters and calendars to Java 8 JSR-310.

There is a new class org.quickfixj.SimpleCache, is it at the right place?

@guidomedina guidomedina force-pushed the master branch 6 times, most recently from 85befc5 to a0a9308 Compare October 24, 2016 16:43
c.set(year, month - 1, day);
return c.getTimeInMillis();
});

Copy link
Author

@guidomedina guidomedina Oct 24, 2016

Choose a reason for hiding this comment

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

This is an interesting function, I think we don't need a calendar for that, if it could be migrated to JDK 8 to avoid such instantiation.

Also, JDK 8 JSR-310 date & time formatters are now thread safe, I'll see if I can add more of that stuff on Friday, busy days ahead on my other project.

Maybe migrated to JDK 8 will make it faster than calculating the hash for a String look in a Map

@chrjohn
Copy link
Member

chrjohn commented Oct 27, 2016

Hi @guidomedina , thank you, I will look at it later this week or weekend.

public V computeIfAbsent(K key) {
/*
* We could computeIfAbsent directly but for CPUs < 32 pre-scanning is faster.
*/
Copy link
Member

Choose a reason for hiding this comment

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

Just curious: Shouldn't we then have a code path that directly uses computeIfAbsent if number of CPUs is greater than 32 (for the very rare case ;)).

Copy link
Author

@guidomedina guidomedina Oct 27, 2016

Choose a reason for hiding this comment

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

Maybe is not worth the effort, look at 1st comment on the question:
http://stackoverflow.com/questions/33901070/java-8-concurrent-hash-map-get-performance-alternative

This is actually the recommendation by the Doug Lea the author of ConcurrentHashMap for Java 8 (aka CHMv8):
http://jsr166-concurrency.10961.n7.nabble.com/Re-ConcurrentHashMap-computeIfAbsent-td11687.html

@guidomedina
Copy link
Author

Rebased and added some plugin updates, I was looking at the date time stuff and it will take some effort to do so I think what has been done is good enough for now, later we can comeback to it and migrate more stuff to Java 8.

@chrjohn
Copy link
Member

chrjohn commented Nov 16, 2016

Sorry, did not have time yet to take a deeper look, but anyway thanks for the PR. 👍

Just a quick question: does the conversion from for-each-loop to the functional style have any benefit? I do not find it easier to understand. I mean, maybe there are cases where it might be handy, but in this commit it is just the same logic but with a different header.

@guidomedina
Copy link
Author

guidomedina commented Nov 16, 2016

I didn't change any for-each, I explicitly left these out, the only functional changes are anonymous classes and functional interfaces which are interfaces with one method that are inferred as functional by Java 8 hence allow you to omit boiler plate code.

Almost two years ago I found difficult to understand Java 8, then it becomes very easy.

@guidomedina
Copy link
Author

guidomedina commented Dec 11, 2016

I have a custom QFJ 1.7.x compiled version, running what is on master in production for weeks now, no issues, I also introduced a NullStore to avoid storing market data messages which are not needed to be resend, I should probably PR it, WDYT?

import org.slf4j.LoggerFactory;
import quickfix.*;

import java.util.Collection;
import java.util.Date;

public class NullStore implements MessageStore {

  public static final class NullStoreFactory implements MessageStoreFactory {

    @Override
    public MessageStore create(SessionID sessionID) {
      return new NullStore(sessionID);
    }
  }

  private final SessionID sessionID;

  private Date creationTime = new Date();
  private int nextSenderMsgSeqNum = 1;
  private int nextTargetMsgSeqNum = 1;

  public NullStore(SessionID sessionID) {
    this.sessionID = sessionID;
  }

  public void get(int startSequence, int endSequence, Collection<String> messages) {
  }

  public Date getCreationTime() {
    return creationTime;
  }

  public int getNextSenderMsgSeqNum() {
    return nextSenderMsgSeqNum;
  }

  public int getNextTargetMsgSeqNum() {
    return nextTargetMsgSeqNum;
  }

  public void incrNextSenderMsgSeqNum() {
    nextSenderMsgSeqNum++;
  }

  public void incrNextTargetMsgSeqNum() {
    nextTargetMsgSeqNum++;
  }

  public void reset() {
    creationTime = new Date();
    nextSenderMsgSeqNum = 1;
    nextTargetMsgSeqNum = 1;
  }

  public boolean set(int sequence, String message) {
    return true;
  }

  public void setNextSenderMsgSeqNum(int next) {
    nextSenderMsgSeqNum = next;
  }

  public void setNextTargetMsgSeqNum(int next) {
    nextTargetMsgSeqNum = next;
  }

  public void refresh() {
    final String text = "null store does not support refresh!";
    if (sessionID != null) {
      final Session session = Session.lookupSession(sessionID);
      session.getLog().onErrorEvent("ERROR: " + text);
    } else {
      LoggerFactory.getLogger(quickfix.MemoryStore.class).error(text);
    }
  }
}

@chrjohn
Copy link
Member

chrjohn commented Dec 12, 2016

Hi @guidomedina,

yes, please open a separate PR. You could also use the PersistMessages=N option to not persist any messages.
But I like your implementation anyway since it is even doing less processing than a MemoryStore used in conjunction with PersistMessages=N.

Cheers,
Chris.

@chrjohn
Copy link
Member

chrjohn commented Dec 12, 2016

Hi @guidomedina , could you please reopen this? I didn't yet merge the JDK8 changes.
Thanks

@chrjohn
Copy link
Member

chrjohn commented Dec 12, 2016

OK, just saw #88 :)

@guidomedina
Copy link
Author

I split them so that one doesn't interfere with the other.

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