Changeset 7036


Ignore:
Timestamp:
Dec 4, 2015, 11:41:17 AM (6 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1977: Improve performance of "All items" list

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/User.java

    r7016 r7036  
    2626import net.sf.basedb.core.data.BasicData;
    2727import net.sf.basedb.core.data.GroupData;
     28import net.sf.basedb.core.data.NameableData;
    2829import net.sf.basedb.core.data.QuotaIndex;
    2930import net.sf.basedb.core.data.RoleData;
     
    3839import net.sf.basedb.core.query.Restrictions;
    3940import net.sf.basedb.core.query.Hql;
     41import net.sf.basedb.core.query.Orders;
    4042import net.sf.basedb.core.query.EntityQuery;
    4143import net.sf.basedb.core.query.ResultList;
     
    11771179    Permission permission, Restriction restriction)
    11781180  {
     1181    if (itemTypes == null || itemTypes.size() == 0) itemTypes = Metadata.getOwnableItems();
     1182   
    11791183    DbControl dc = getDbControl();
    11801184    SessionControl sc = dc.getSessionControl();
    11811185    org.hibernate.Session session = dc.getHibernateSession();
    1182  
     1186   
    11831187    // Check if this is the logged in user -- add a sharing filter otherwise
    11841188    if (this.getId() != sc.getLoggedInUserId())
     
    12081212    }
    12091213
    1210     List<OwnableData> ownedBy = null;
    1211     if (itemTypes != null && itemTypes.size() > 0)
    1212     {
    1213       ownedBy = new ArrayList<OwnableData>();
    1214       for (Item item : itemTypes)
     1214    boolean useLimit = firstItem >= 0 && maxItems > 0;
     1215    List<OwnableData> ownedBy = new ArrayList<OwnableData>();
     1216    List<ItemProxy> proxies = new ArrayList<ItemProxy>();
     1217
     1218    for (Item item : itemTypes)
     1219    {
     1220      if (OwnableData.class.isAssignableFrom(item.getDataClass()))
    12151221      {
    1216         if (OwnableData.class.isAssignableFrom(item.getDataClass()))
     1222        // Query to load all ownable items of a specific subclass
     1223        AbstractHqlQuery hql =
     1224          new AbstractHqlQuery(item.getDataClass().getName(), "item", false){};
     1225        hql.select(Selects.expression(Hql.alias("item"), null, true));
     1226        hql.restrict(Hql.restriction("item.owner = :user", null));
     1227        hql.setParameter("user", getId(), Type.INT);
     1228        if (restriction != null) hql.restrict(restriction);
     1229        if (NameableData.class.isAssignableFrom(item.getDataClass()))
    12171230        {
    1218           // Query to load all ownable items of a specific subclass
    1219           AbstractHqlQuery hql =
    1220             new AbstractHqlQuery(item.getDataClass().getName(), "item", false){};
    1221           hql.select(Selects.expression(Hql.alias("item"), null, true));
    1222           hql.restrict(Hql.restriction("item.owner = :user", null));
    1223           hql.setParameter("user", getId(), Type.INT);
    1224           if (restriction != null) hql.restrict(restriction);
    1225           /*
    1226             SELECT item
    1227             FROM <class> item
    1228             WHERE item.owner = :user
    1229             [AND restriction]
    1230           */
     1231          hql.order(Orders.asc(Hql.property("name")));
     1232        }
     1233        hql.order(Orders.asc(Hql.property("id")));
     1234        /*
     1235          SELECT item
     1236          FROM <class> item
     1237          WHERE item.owner = :user
     1238          [AND restriction]
     1239        */
     1240        if (useLimit)
     1241        {
     1242          // Load proxies if we are just going to load a part of the items (it is a lot quicker!)
     1243          for (Integer id : HibernateUtil.loadList(Integer.class, hql.getIdHqlQuery(dc), sc))
     1244          {
     1245            proxies.add(new ItemProxy(id, item));
     1246          }
     1247        }
     1248        else
     1249        {
     1250          // Load all items
    12311251          ownedBy.addAll(HibernateUtil.loadList(OwnableData.class, hql.getMainHqlQuery(dc), sc));
    12321252        }
    12331253      }
    12341254    }
    1235     else
    1236     {
    1237       AbstractHqlQuery hql =
    1238         new AbstractHqlQuery("net.sf.basedb.core.data.OwnableData", "item", false){};
    1239       hql.select(Selects.expression(Hql.alias("item"), null, true));
    1240       hql.restrict(Hql.restriction("item.owner = :user", null));
    1241       hql.setParameter("user", getId(), Type.INT);
    1242       if (restriction != null) hql.restrict(restriction);
    1243       /*
    1244         SELECT item
    1245         FROM net.sf.basedb.core.data.OwnableData item
    1246         WHERE item.owner = :user
    1247         [AND restriction]
    1248       */
    1249       ownedBy = HibernateUtil.loadList(OwnableData.class, hql.getMainHqlQuery(dc), sc);
    1250     }
     1255   
    12511256    // Disable filters
    12521257    HibernateUtil.disableFilter(session, "sharedTo");
     
    12541259   
    12551260    // Create items and apply limits
    1256     List<Ownable> items = new ArrayList<Ownable>(ownedBy.size());
    1257     int index = 0;
     1261    List<Ownable> items = new ArrayList<Ownable>(useLimit ? maxItems : ownedBy.size());
    12581262    int totalItems = 0;
    1259     boolean useLimit = firstItem >= 0 && maxItems > 0;
    1260     int lastItem = firstItem + maxItems;
    1261     for (OwnableData od : ownedBy)
    1262     {
    1263       BasicData data = (BasicData)od;
    1264       try
     1263    if (useLimit)
     1264    {
     1265      totalItems = proxies.size();
     1266      int lastItem = Math.min(firstItem + maxItems, totalItems);
     1267      for (int index = firstItem; index < lastItem; index++)
    12651268      {
    1266         BasicItem item = dc.getItem(BasicItem.class, data);
    1267         if (!useLimit || (index >= firstItem && index < lastItem))
     1269        try
    12681270        {
     1271          BasicItem item = proxies.get(index).getItem(dc);
    12691272          items.add((Ownable)item);
    12701273        }
    1271         index++;
    1272         totalItems++;
     1274        catch (PermissionDeniedException ex)
     1275        {
     1276          // We do not correct for permissions since that would make it impossible to
     1277          // implement paging. We accept that some pages may contain fewer items.
     1278        }
    12731279      }
    1274       catch (PermissionDeniedException ex)
    1275       {}
    1276     }
     1280    }
     1281    else
     1282    {
     1283      totalItems = ownedBy.size();
     1284      for (OwnableData sd : ownedBy)
     1285      {
     1286        try
     1287        {
     1288          BasicItem item = dc.getItem(BasicItem.class, (BasicData)sd);
     1289          items.add((Ownable)item);
     1290        }
     1291        catch (PermissionDeniedException ex)
     1292        {
     1293          totalItems--;
     1294        }
     1295      }
     1296    }
     1297
    12771298    return new UnmodifiableResultList<Ownable>(items, totalItems);
    12781299  }
Note: See TracChangeset for help on using the changeset viewer.