Commit 7795ffa0 authored by Richard Knoll's avatar Richard Knoll Committed by Commit Bot

[Downloads Home] Support items with the same creation time.

The DateOrderedListMutator kept OfflineItems in a Map keyed by their
creation time. Two entries with the same one (or within the same
millisecond) would therefore override each other. This replaces the map
with a sorted set and a custom comparator to keep the descending sort
order.

Bug: 962889
Change-Id: I1bef6b32a42dc34b49946512e31f440999cf7287
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1609901
Commit-Queue: Richard Knoll <knollr@chromium.org>
Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#659446}
parent 0e114271
......@@ -21,7 +21,9 @@ import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* A class responsible for turning a {@link Collection} of {@link OfflineItem}s into a list meant
......@@ -186,13 +188,13 @@ class DateOrderedListMutator implements OfflineItemFilterObserver {
if (!mHideSectionHeaders) {
sectionHeaderItem.showTitle = !mHideTitleFromSectionHeaders;
sectionHeaderItem.showMenu = filter == OfflineItemFilter.IMAGE;
sectionHeaderItem.items = new ArrayList<>(section.items.values());
sectionHeaderItem.items = new ArrayList<>(section.items);
}
listItems.add(sectionHeaderItem);
}
// Add the items in the section.
for (OfflineItem offlineItem : section.items.values()) {
for (OfflineItem offlineItem : section.items) {
OfflineItemListItem item = new OfflineItemListItem(offlineItem);
if (mConfig.supportFullWidthImages && section.items.size() == 1
&& offlineItem.filter == OfflineItemFilter.IMAGE) {
......@@ -258,7 +260,7 @@ class DateOrderedListMutator implements OfflineItemFilterObserver {
public boolean contains(ContentId id) {
for (Section section : sections.values()) {
for (OfflineItem item : section.items.values()) {
for (OfflineItem item : section.items) {
if (item.id.equals(id)) return true;
}
}
......@@ -268,15 +270,25 @@ class DateOrderedListMutator implements OfflineItemFilterObserver {
/** Represents a group of items having the same filter type. */
private static class Section {
public Map<Date, OfflineItem> items =
new TreeMap<>((lhs, rhs) -> { return rhs.compareTo(lhs); });
/**
* The list of items in a section for a day. Ordered by descending creation time then
* namespace and finally by id.
*/
public Set<OfflineItem> items = new TreeSet<>((lhs, rhs) -> {
int comparison = Long.compare(rhs.creationTimeMs, lhs.creationTimeMs);
if (comparison != 0) return comparison;
comparison = lhs.id.namespace.compareTo(rhs.id.namespace);
if (comparison != 0) return comparison;
return lhs.id.id.compareTo(rhs.id.id);
});
public void addOrUpdateItem(OfflineItem item) {
items.put(new Date(item.creationTimeMs), item);
items.remove(item);
items.add(item);
}
public void removeItem(OfflineItem item) {
items.remove(new Date(item.creationTimeMs));
items.remove(item);
}
}
}
......@@ -735,6 +735,56 @@ public class DateOrderedListMutatorTest {
assertOfflineItem(mModel.get(5), buildCalendar(2018, 1, 1, 4), item2);
}
/**
* Action List
* 1. Set() [ ]
*
* 2. Add(item3 @ 4:00 1/1/2018) [ DATE @ 0:00 1/1/2018,
* SECTION @ Video,
* item3 @ 4:00 1/1/2018 ]
*
* 3. Add(item1 @ 4:00 1/1/2018) [ DATE @ 0:00 1/1/2018,
* SECTION @ Video,
* item1 @ 4:00 1/1/2018,
* item3 @ 4:00 1/1/2018 ]
*
* 4. Add(item2 @ 4:00 1/1/2018) [ DATE @ 0:00 1/1/2018,
* SECTION @ Video,
* item1 @ 4:00 1/1/2018,
* item2 @ 4:00 1/1/2018,
* item3 @ 4:00 1/1/2018 ]
*/
@Test
public void testAddMultipleItemsSameTimestamp() {
when(mSource.getItems()).thenReturn(Collections.emptySet());
DateOrderedListMutator list = createMutatorWithoutJustNowProvider();
mModel.addObserver(mObserver);
OfflineItem item3 = buildItem("3", buildCalendar(2018, 1, 1, 4), OfflineItemFilter.VIDEO);
when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item3));
list.onItemsAdded(CollectionUtil.newArrayList(item3));
Assert.assertEquals(2, mModel.size());
assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), item3);
OfflineItem item1 = buildItem("1", buildCalendar(2018, 1, 1, 4), OfflineItemFilter.VIDEO);
when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item3, item1));
list.onItemsAdded(CollectionUtil.newArrayList(item1));
Assert.assertEquals(3, mModel.size());
assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), item1);
assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 4), item3);
OfflineItem item2 = buildItem("2", buildCalendar(2018, 1, 1, 4), OfflineItemFilter.VIDEO);
when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item3, item1, item2));
list.onItemsAdded(CollectionUtil.newArrayList(item2));
Assert.assertEquals(4, mModel.size());
assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), item1);
assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 4), item2);
assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 4), item3);
}
/**
* Action List
* 1. Set(item1 @ 6:00 IN_PROGRESS 1/1/2018) [ DATE @ 0:00 1/1/2018,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment