<commit_before>package org.realityforge.replicant.client;

import java.util.Collections;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.realityforge.replicant.client.transport.CacheService;
import org.realityforge.replicant.client.transport.ClientSession;
import org.realityforge.replicant.client.transport.RequestEntry;
import org.realityforge.replicant.client.transport.RequestManager;
import org.realityforge.replicant.client.transport.SessionContext;
import org.realityforge.replicant.server.transport.BadSessionException;

/**
 * Class from which to extend to implement a service that loads data from a change set.
 * Data can be loaded by bulk or incrementally and the load can be broken up into several
 * steps to avoid locking a thread such as in GWT.
 */
public abstract class AbstractDataLoaderService<T extends ClientSession>
{
  private static final int DEFAULT_CHANGES_TO_PROCESS_PER_TICK = 100;
  private static final int DEFAULT_LINKS_TO_PROCESS_PER_TICK = 100;
  protected static final Logger LOG = Logger.getLogger( AbstractDataLoaderService.class.getName() );
  @Inject
  private ChangeMapper _changeMapper;
  @Inject
  private EntityChangeBroker _changeBroker;
  @Inject
  private EntityRepository _repository;
  @Inject
  private CacheService _cacheService;

  private int _lastKnownChangeSet;

  /**
   * The set of data load actions that still need to have the json parsed.
   */
  private final LinkedList<DataLoadAction> _pendingActions = new LinkedList<>();
  /**
   * The set of data load actions that have their json parsed. They are inserted into
   * this list according to their sequence.
   */
  private final LinkedList<DataLoadAction> _parsedActions = new LinkedList<>();
  /**
   * Sometimes a data load action occurs that is not initiated by the server. These do not
   * typically need to be sequenced and are prioritized above other actions.
   */
  private final LinkedList<DataLoadAction> _oobActions = new LinkedList<>();
  private DataLoadAction _currentAction;
  private int _updateCount;
  private int _removeCount;
  private int _linkCount;
  private int _changesToProcessPerTick = DEFAULT_CHANGES_TO_PROCESS_PER_TICK;
  private int _linksToProcessPerTick = DEFAULT_LINKS_TO_PROCESS_PER_TICK;

  private T _session;

  protected void setSession( final T session )
  {
    _session = session;
    // This should probably be moved elsewhere ... but where?
    SessionContext.setSession( session );
  }

  protected final CacheService getCacheService()
  {
    return _cacheService;
  }

  protected final EntityChangeBroker getChangeBroker()
  {
    return _changeBroker;
  }

  protected final ChangeMapper getChangeMapper()
  {
    return _changeMapper;
  }

  public final T getSession()
  {
    return _session;
  }

  protected final String getSessionID()
  {
    final T session = getSession();
    if( null == session )<commit_msg>Add some javadocs to getSessionID()<commit_after>package org.realityforge.replicant.client;

import java.util.Collections;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.realityforge.replicant.client.transport.CacheService;
import org.realityforge.replicant.client.transport.ClientSession;
import org.realityforge.replicant.client.transport.RequestEntry;
import org.realityforge.replicant.client.transport.RequestManager;
import org.realityforge.replicant.client.transport.SessionContext;
import org.realityforge.replicant.server.transport.BadSessionException;

/**
 * Class from which to extend to implement a service that loads data from a change set.
 * Data can be loaded by bulk or incrementally and the load can be broken up into several
 * steps to avoid locking a thread such as in GWT.
 */
public abstract class AbstractDataLoaderService<T extends ClientSession>
{
  private static final int DEFAULT_CHANGES_TO_PROCESS_PER_TICK = 100;
  private static final int DEFAULT_LINKS_TO_PROCESS_PER_TICK = 100;
  protected static final Logger LOG = Logger.getLogger( AbstractDataLoaderService.class.getName() );
  @Inject
  private ChangeMapper _changeMapper;
  @Inject
  private EntityChangeBroker _changeBroker;
  @Inject
  private EntityRepository _repository;
  @Inject
  private CacheService _cacheService;

  private int _lastKnownChangeSet;

  /**
   * The set of data load actions that still need to have the json parsed.
   */
  private final LinkedList<DataLoadAction> _pendingActions = new LinkedList<>();
  /**
   * The set of data load actions that have their json parsed. They are inserted into
   * this list according to their sequence.
   */
  private final LinkedList<DataLoadAction> _parsedActions = new LinkedList<>();
  /**
   * Sometimes a data load action occurs that is not initiated by the server. These do not
   * typically need to be sequenced and are prioritized above other actions.
   */
  private final LinkedList<DataLoadAction> _oobActions = new LinkedList<>();
  private DataLoadAction _currentAction;
  private int _updateCount;
  private int _removeCount;
  private int _linkCount;
  private int _changesToProcessPerTick = DEFAULT_CHANGES_TO_PROCESS_PER_TICK;
  private int _linksToProcessPerTick = DEFAULT_LINKS_TO_PROCESS_PER_TICK;

  private T _session;

  protected void setSession( final T session )
  {
    _session = session;
    // This should probably be moved elsewhere ... but where?
    SessionContext.setSession( session );
  }

  protected final CacheService getCacheService()
  {
    return _cacheService;
  }

  protected final EntityChangeBroker getChangeBroker()
  {
    return _changeBroker;
  }

  protected final ChangeMapper getChangeMapper()
  {
    return _changeMapper;
  }

  public final T getSession()
  {
    return _session;
  }

  /**
   * Return the id of the session associated with the service.
   *
   * @return the id of the session associated with the service.
   * @throws BadSessionException if the service is not currently associated with the session.
   */
  protected final String getSessionID()
    throws BadSessionException
  {
    final T session = getSession();
    if( null == session )
{'fraction_non_alphanumeric': 0.06730618021701526, 'fraction_numerical': 0.0018870891649630445, 'mean_word_length': 4.459227467811159, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7062456', 'n_tokens_mistral': 1785, 'n_tokens_neox': 1742, 'n_words': 580}