Changeset 7025


Ignore:
Timestamp:
Nov 25, 2015, 9:36:19 AM (7 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1973: Improve performance of project items list

If max number of items has been specified we only load IDs in the first step and use proxies to load the final items one by one only for the visible page.

Since this would impact performance for other code that wants to load all items in the project the old way of directly loading complete items exists (except that we now only load one item type at a time).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.6-stable/src/core/net/sf/basedb/core/Project.java

    r6875 r7025  
    500500  {
    501501    if (include == null) include = EnumSet.of(Include.NOT_REMOVED, Include.MINE, Include.OTHERS);
     502    if (itemTypes == null || itemTypes.size() == 0) itemTypes = Metadata.getShareableItems();
    502503   
    503504    DbControl dc = getDbControl();
     
    576577    }
    577578   
    578     List<ShareableData> inProject = null;
    579     if (itemTypes != null && itemTypes.size() > 0)
    580     {
    581       inProject = new ArrayList<ShareableData>();
    582       for (Item item : itemTypes)
    583       {
    584         if (ShareableData.class.isAssignableFrom(item.getDataClass()))
    585         {
    586           // Query to load all shareable items of a specific subclass
    587           AbstractHqlQuery hql =
    588             new AbstractHqlQuery(item.getDataClass().getName(), "item", false){};
    589           hql.select(Selects.expression(Hql.alias("item"), null, true));
    590           if (restriction != null) hql.restrict(restriction);
    591           /*
    592             SELECT item
    593             FROM <class> item
    594             [WHERE restriction]
    595           */
     579    boolean useLimit = firstItem >= 0 && maxItems > 0;
     580    List<ShareableData> inProject = new ArrayList<ShareableData>();
     581    List<ItemProxy> proxies = new ArrayList<ItemProxy>();
     582   
     583    for (Item item : itemTypes)
     584    {
     585      if (sc.hasPermission(Permission.DENIED, item)) continue;
     586     
     587      if (ShareableData.class.isAssignableFrom(item.getDataClass()))
     588      {
     589        // Query to load all shareable items of a specific subclass
     590        AbstractHqlQuery hql =
     591          new AbstractHqlQuery(item.getDataClass().getName(), "item", false){};
     592        hql.select(Selects.expression(Hql.alias("item"), null, true));
     593        if (restriction != null) hql.restrict(restriction);
     594        /*
     595          SELECT item[.id]
     596          FROM <class> item
     597          [WHERE restriction]
     598        */
     599        if (useLimit)
     600        {
     601          // Load proxies if we are just going to load a part of the items (it is a lot quicker!)
     602          for (Integer id : HibernateUtil.loadList(Integer.class, hql.getIdHqlQuery(dc), sc))
     603          {
     604            proxies.add(new ItemProxy(id, item));
     605          }
     606        }
     607        else
     608        {
     609          // Load all items
    596610          inProject.addAll(HibernateUtil.loadList(ShareableData.class, hql.getMainHqlQuery(dc), sc));
    597611        }
    598612      }
    599613    }
    600     else
    601     {
    602       // Query to load all shareable items
    603       AbstractHqlQuery hql =
    604         new AbstractHqlQuery("net.sf.basedb.core.data.ShareableData", "item", false){};
    605       hql.select(Selects.expression(Hql.alias("item"), null, true));
    606       if (restriction != null) hql.restrict(restriction);
    607       /*
    608         SELECT item
    609         FROM net.sf.basedb.core.data.ShareableData item
    610         [WHERE restriction]
    611       */
    612       inProject = HibernateUtil.loadList(ShareableData.class, hql.getMainHqlQuery(dc), sc);
    613     }
     614     
    614615    // Disable filters
    615616    HibernateUtil.disableFilter(session, "ownedByOrInProject");
     
    620621    HibernateUtil.disableFilter(session, "denyAll");
    621622   
    622     List<Shareable> items = new ArrayList<Shareable>(inProject.size());
    623     int index = 0;
     623    List<Shareable> items = new ArrayList<Shareable>(useLimit ? maxItems : inProject.size());
    624624    int totalItems = 0;
    625     boolean useLimit = firstItem >= 0 && maxItems > 0;
    626     int lastItem = firstItem + maxItems;
    627     for (ShareableData sd : inProject)
    628     {
    629     BasicData data = (BasicData)sd;
    630     try
    631     {
    632       BasicItem item = dc.getItem(BasicItem.class, data);
    633       if (!useLimit || (index >= firstItem && index < lastItem))
    634       {
    635         items.add((Shareable)item);
    636       }
    637       index++;
    638       totalItems++;
    639     }
    640     catch (PermissionDeniedException ex)
    641     {}
    642     }
     625    if (useLimit)
     626    {
     627      totalItems = proxies.size();
     628      int lastItem = Math.min(firstItem + maxItems, totalItems);
     629      for (int index = firstItem; index < lastItem; index++)
     630      {
     631        try
     632        {
     633          BasicItem item = proxies.get(index).getItem(dc);
     634          items.add((Shareable)item);
     635        }
     636        catch (PermissionDeniedException ex)
     637        {
     638          // We do not correct for permissions since that would make it impossible to
     639          // implement paging. We accept that some pages may contain fewer items.
     640        }
     641      }
     642    }
     643    else
     644    {
     645      totalItems = inProject.size();
     646      for (ShareableData sd : inProject)
     647      {
     648        try
     649        {
     650          BasicItem item = dc.getItem(BasicItem.class, (BasicData)sd);
     651          items.add((Shareable)item);
     652        }
     653        catch (PermissionDeniedException ex)
     654        {
     655          totalItems--;
     656        }
     657      }
     658    }
     659
    643660    return new UnmodifiableResultList<Shareable>(items, totalItems);
    644661  }
Note: See TracChangeset for help on using the changeset viewer.