1. #11
    Ext GWT Premium Member icfantv's Avatar
    Join Date
    Sep 2011
    Location
    Superior, CO
    Posts
    411
    Vote Rating
    21
    Answers
    20
    icfantv will become famous soon enough icfantv will become famous soon enough

      0  

    Default


    We don't have a use case, which is why I was asking about a SortedSet. A List implies some order but not uniqueness whereas a Set implies uniqueness but no order. To me, a SortedSet is the happy medium because it implies both some type of ordering and uniqueness among elements.

    I still can't think of a scenario whereby I would have two duplicate model objects but each one would return a different key value - to me, this implies that the models are not the same, and thus, not duplicates.

    Additionally, you talked about performance. Using the right SortedSet implementation can be significantly faster than a List. Java's implementation of TreeSet uses its implementation of TreeMap, which is a red-black tree. Red-black trees have a best and worst O(log n) for searching, inserting, and deleting (sorting is done on insert) whereas a list has at best an O(n log(n)) for sorting.

    References:
    http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
    http://en.wikipedia.org/wiki/Sorting_algorithm

  2. #12
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,734
    Vote Rating
    90
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    In Java, you'd be exactly right, and I'd be foolish to not look into at least considering these changes, but in GWT/Java, where ArrayList is compiled to create JS Array instances, the game is a little different.

    JavaScript has native arrays and objects, and ArrayList is re-implemented to use them, as opposed to Java's array type. From com.google.gwt.emul.java.lang.ArrayList:

    /**
    * Resizeable array implementation of the List interface. <a
    * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html">[Sun
    * docs]</a>
    *
    * <p>
    * This implementation differs from JDK 1.5 <code>ArrayList</code> in terms of
    * capacity management. There is no speed advantage to pre-allocating array
    * sizes in JavaScript, so this implementation does not include any of the
    * capacity and "growth increment" concepts in the standard ArrayList class.
    * Although <code>ArrayList(int)</code> accepts a value for the initial
    * capacity of the array, this constructor simply delegates to
    * <code>ArrayList()</code>. It is only present for compatibility with JDK
    * 1.5's API.
    * </p>
    *
    * @param <E> the element type.
    */
    The implementation then is almost entirely JSNI wrapping around standard JS Array methods, and will be pretty efficient, especially for iterating through them, which is the main use case in Stores where performance is important, visiting each item to render it.

    Can you suggest a class that should be a good SortedSet implementation to try backing the ListStore with, and is available in the available JRE classes in GWT? I might try a quick implementation, see what happens performance-wise.

  3. #13
    Ext GWT Premium Member icfantv's Avatar
    Join Date
    Sep 2011
    Location
    Superior, CO
    Posts
    411
    Vote Rating
    21
    Answers
    20
    icfantv will become famous soon enough icfantv will become famous soon enough

      0  

    Default


    Ack! I'd forgotten that we're dealing with Java --> J/S conversion.

    I see TreeSet/TreeMap implementations in GWT SVN: http://code.google.com/p/google-web-...emul/java/util, is this what's used to generate J/S versions of java.util.[TreeSet/TreeMap]? I don't think this is what you're talking about though.

    I'm perusing the google-collections framework (apparently, now known as Guava) and they have plenty of GWT Compatible (annotated with GwtCompatible) collections. But, this would introduce a transient dependency on GXT API users and it looks like their SortedMultiset collection allows duplicates (however duplicate here means occurrences of the same single element).

    Additionally, it appears that the LightweightCollections effort was killed as well due to "the GWT implementaiton of teh Java libraries performed reasonably well, even when compared to a simple encapsulation of J/S datastructures. HashMap even provides specialized behavior for String keys.

    I would be curious as to the performance of Google's code, but to answer your question, I don't have an alternative implementation.

  4. #14
    Sencha User
    Join Date
    Jul 2014
    Posts
    2
    Vote Rating
    0
    agna.desai is on a distinguished road

      0  

    Default How to provide hashcode for object in ModelKeyProvider?

    How to provide hashcode for object in ModelKeyProvider?


    can you explain how to provide hashcode for object using model key provider? I am stuck with the same problem. See my example below. Thank you for the help.

    Sample of JSON file
    {"dbEntity":


    [{"ChipType":"EXPERIMENT","ExperimentDescription":"PanDefSNRIncreased_1.55", "ProjId":"PanDefSNRIncreased_1.55","PlateSize":"96"},
    {"ChipType":"EXPERIMENT","ExperimentDescription":"PanDefPeakSNR5_1.55","ProjId":"PanDefPeakSNR5_1.55","PlateSize":"96"},
    {"ChipType":"EXPERIMENT","ExperimentDescription":"PanDefPeakSNR4_1.55","ProjId":"PanDefPeakSNR4_1.55","PlateSize":"96"},

    ]}
    ---------------------------------------------------------------------------------------
    JSONGrid.java

    package com.test.JSON.client;


    import java.util.ArrayList;
    import java.util.List;


    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.editor.client.Editor.Path;
    import com.google.gwt.http.client.RequestBuilder;
    import com.google.gwt.user.client.ui.IsWidget;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.google.gwt.user.client.ui.Widget;
    import com.google.web.bindery.autobean.shared.AutoBean;
    import com.google.web.bindery.autobean.shared.AutoBeanFactory;
    import com.sencha.gxt.core.client.ValueProvider;
    import com.sencha.gxt.data.client.loader.HttpProxy;
    import com.sencha.gxt.data.shared.ListStore;
    import com.sencha.gxt.data.shared.ModelKeyProvider;
    import com.sencha.gxt.data.shared.PropertyAccess;
    import com.sencha.gxt.data.shared.loader.ListLoadResultBean;
    import com.sencha.gxt.data.shared.loader.JsonReader;
    import com.sencha.gxt.data.shared.loader.ListLoadConfig;
    import com.sencha.gxt.data.shared.loader.ListLoadResult;
    import com.sencha.gxt.data.shared.loader.ListLoader;
    import com.sencha.gxt.data.shared.loader.LoadResultListStoreBinding;
    import com.sencha.gxt.explorer.client.model.Example.Detail;
    import com.sencha.gxt.explorer.client.model.Example.Detail;
    import com.sencha.gxt.widget.core.client.FramedPanel;
    import com.sencha.gxt.widget.core.client.button.TextButton;
    import com.sencha.gxt.widget.core.client.container.BoxLayoutContainer.BoxLayoutPack;
    import com.sencha.gxt.widget.core.client.event.SelectEvent;
    import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
    import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
    import com.sencha.gxt.widget.core.client.grid.ColumnModel;
    import com.sencha.gxt.widget.core.client.grid.Grid;


    @Detail(name = "Json Grid", icon = "jsongrid", category = "Grid")
    public class JSONGrid implements IsWidget, EntryPoint {


    public interface dbEntityAutoBeanFactory extends AutoBeanFactory {


    AutoBean<RecordResult> items();


    AutoBean<ListLoadConfig> loadConfig();
    }


    public interface dbEntity {
    String getProjId();


    String getChipType();


    String getPlateSize();


    String getExperimentDescription();


    }


    /**
    * Defines the structure of the root JSON object being returned by the
    * server. This class is needed as we cannot return a list of objects.
    * Instead, we return a single object with a single property that contains
    * the data records.
    */
    public interface RecordResult {


    List<dbEntity> getdbEntity();
    }


    class DataRecordJsonReader extends
    JsonReader<ListLoadResult<dbEntity>, RecordResult> {
    public DataRecordJsonReader(AutoBeanFactory factory,
    Class<RecordResult> rootBeanType) {
    super(factory, rootBeanType);
    }


    @Override
    protected ListLoadResult<dbEntity> createReturnData(Object loadConfig,
    RecordResult incomingData) {
    return new ListLoadResultBean<dbEntity>(incomingData.getdbEntity());
    }
    }


    interface dbEntityProperties extends PropertyAccess<dbEntity> {
    @Path("ProjId")
    ModelKeyProvider<dbEntity> ProjId1();


    ValueProvider<dbEntity, String> ProjId();


    ValueProvider<dbEntity, String> ExperimentDescription();


    ValueProvider<dbEntity, String> PlateSize();


    ValueProvider<dbEntity, String> ChipType();


    // ValueProvider<dbEntity, String> zip();
    }


    @Override
    public void onModuleLoad() {
    RootPanel.get().add(this);
    }


    @Override
    public Widget asWidget() {
    dbEntityAutoBeanFactory factory = GWT
    .create(dbEntityAutoBeanFactory.class);


    DataRecordJsonReader reader = new DataRecordJsonReader(factory,
    RecordResult.class);


    String path = "JsonTest/dbEntity.json";
    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
    HttpProxy<ListLoadConfig> proxy = new HttpProxy<ListLoadConfig>(builder);


    final ListLoader<ListLoadConfig, ListLoadResult<dbEntity>> loader = new ListLoader<ListLoadConfig, ListLoadResult<dbEntity>>(
    proxy, reader);
    loader.useLoadConfig(factory.create(ListLoadConfig.class).as());


    dbEntityProperties props = GWT.create(dbEntityProperties.class);


    ListStore<dbEntity> store = new ListStore<dbEntity>(props.ProjId1());
    store.clear();
    loader.addLoadHandler(new LoadResultListStoreBinding<ListLoadConfig, dbEntity, ListLoadResult<dbEntity>>(
    store));


    ColumnConfig<dbEntity, String> cc1 = new ColumnConfig<dbEntity, String>(
    props.ProjId(), 100, "ProjID");
    ColumnConfig<dbEntity, String> cc2 = new ColumnConfig<dbEntity, String>(
    props.ExperimentDescription(), 165, "ExpDesc");
    ColumnConfig<dbEntity, String> cc3 = new ColumnConfig<dbEntity, String>(
    props.PlateSize(), 100, "PlateSize");
    ColumnConfig<dbEntity, String> cc4 = new ColumnConfig<dbEntity, String>(
    props.ChipType(), 50, "ChipType");
    // ColumnConfig<dbEntity, String> cc5 = new ColumnConfig<dbEntity,
    // String>(props.zip(), 65, "Zip Code");


    List<ColumnConfig<dbEntity, ?>> l = new ArrayList<ColumnConfig<dbEntity, ?>>();
    l.add(cc1);
    l.add(cc2);
    l.add(cc3);
    l.add(cc4);
    // l.add(cc5);
    ColumnModel<dbEntity> cm = new ColumnModel<dbEntity>(l);


    Grid<dbEntity> grid = new Grid<dbEntity>(store, cm);
    grid.getView().setForceFit(true);
    grid.setLoader(loader);
    grid.setLoadMask(true);
    grid.setBorders(true);
    grid.getView().setEmptyText("Please hit the load button.");


    FramedPanel cp = new FramedPanel();
    cp.setHeadingText("Json Grid Example");
    cp.setCollapsible(true);
    cp.setAnimCollapse(true);
    cp.setWidget(grid);
    cp.setPixelSize(575, 350);
    cp.addStyleName("margin-10");
    cp.setButtonAlign(BoxLayoutPack.CENTER);
    cp.addButton(new TextButton("Load Json", new SelectHandler() {


    @Override
    public void onSelect(SelectEvent event) {
    loader.load();
    }
    }));


    return cp;
    }


    }