Skip to content

Commit e6cb1d8

Browse files
committed
Fixed a performance issue with long lists of items - should see constant time perf during child changes instead of linear time.
Removed interfaces internally where exact types would be faster.
1 parent 6babf71 commit e6cb1d8

File tree

2 files changed

+27
-44
lines changed

2 files changed

+27
-44
lines changed

database/src/main/java/com/firebase/ui/database/FirebaseArray.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import com.google.firebase.database.ValueEventListener;
2222

2323
import java.util.ArrayList;
24-
import java.util.List;
24+
import java.util.HashMap;
2525

2626
/**
2727
* This class implements an array-like collection on top of a Firebase location.
@@ -38,11 +38,12 @@ enum EventType {ADDED, CHANGED, REMOVED, MOVED}
3838

3939
}
4040

41-
private Query mQuery;
41+
private final Query mQuery;
42+
private final ArrayList<DataSnapshot> mSnapshots = new ArrayList<>();
43+
private final HashMap<String, Integer> mSnapshotMap = new HashMap<>();
4244
private OnChangedListener mListener;
43-
private List<DataSnapshot> mSnapshots = new ArrayList<>();
4445

45-
public FirebaseArray(Query ref) {
46+
FirebaseArray(Query ref) {
4647
mQuery = ref;
4748
mQuery.addChildEventListener(this);
4849
mQuery.addValueEventListener(this);
@@ -61,16 +62,13 @@ public DataSnapshot getItem(int index) {
6162
return mSnapshots.get(index);
6263
}
6364

64-
private int getIndexForKey(String key) {
65-
int index = 0;
66-
for (DataSnapshot snapshot : mSnapshots) {
67-
if (snapshot.getKey().equals(key)) {
68-
return index;
69-
} else {
70-
index++;
71-
}
65+
public int getIndexForKey(String key) {
66+
final Integer index = mSnapshotMap.get(key);
67+
if (index != null) {
68+
return index;
69+
} else {
70+
throw new IllegalArgumentException("Key not found");
7271
}
73-
throw new IllegalArgumentException("Key not found");
7472
}
7573

7674
@Override
@@ -80,6 +78,7 @@ public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
8078
index = getIndexForKey(previousChildKey) + 1;
8179
}
8280
mSnapshots.add(index, snapshot);
81+
mSnapshotMap.put(snapshot.getKey(), index);
8382
notifyChangedListeners(OnChangedListener.EventType.ADDED, index);
8483
}
8584

@@ -94,6 +93,7 @@ public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {
9493
public void onChildRemoved(DataSnapshot snapshot) {
9594
int index = getIndexForKey(snapshot.getKey());
9695
mSnapshots.remove(index);
96+
mSnapshotMap.remove(snapshot.getKey());
9797
notifyChangedListeners(OnChangedListener.EventType.REMOVED, index);
9898
}
9999

@@ -103,6 +103,7 @@ public void onChildMoved(DataSnapshot snapshot, String previousChildKey) {
103103
mSnapshots.remove(oldIndex);
104104
int newIndex = previousChildKey == null ? 0 : (getIndexForKey(previousChildKey) + 1);
105105
mSnapshots.add(newIndex, snapshot);
106+
mSnapshotMap.put(snapshot.getKey(), newIndex);
106107
notifyChangedListeners(OnChangedListener.EventType.MOVED, newIndex, oldIndex);
107108
}
108109

@@ -120,17 +121,17 @@ public void setOnChangedListener(OnChangedListener listener) {
120121
mListener = listener;
121122
}
122123

123-
protected void notifyChangedListeners(OnChangedListener.EventType type, int index) {
124+
void notifyChangedListeners(OnChangedListener.EventType type, int index) {
124125
notifyChangedListeners(type, index, -1);
125126
}
126127

127-
protected void notifyChangedListeners(OnChangedListener.EventType type, int index, int oldIndex) {
128+
void notifyChangedListeners(OnChangedListener.EventType type, int index, int oldIndex) {
128129
if (mListener != null) {
129130
mListener.onChildChanged(type, index, oldIndex);
130131
}
131132
}
132133

133-
protected void notifyCancelledListeners(DatabaseError databaseError) {
134+
void notifyCancelledListeners(DatabaseError databaseError) {
134135
if (mListener != null) {
135136
mListener.onCancelled(databaseError);
136137
}

database/src/main/java/com/firebase/ui/database/FirebaseIndexArray.java

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,15 @@
2323

2424
import java.util.ArrayList;
2525
import java.util.HashMap;
26-
import java.util.HashSet;
27-
import java.util.List;
2826
import java.util.Map;
29-
import java.util.Set;
3027

3128
class FirebaseIndexArray extends FirebaseArray {
3229
private static final String TAG = FirebaseIndexArray.class.getSimpleName();
3330

34-
private Query mQuery;
31+
private final Query mQuery;
32+
private final HashMap<Query, ValueEventListener> mRefs = new HashMap<>();
33+
private final ArrayList<DataSnapshot> mDataSnapshots = new ArrayList<>();
3534
private OnChangedListener mListener;
36-
private Map<Query, ValueEventListener> mRefs = new HashMap<>();
37-
private List<DataSnapshot> mDataSnapshots = new ArrayList<>();
3835

3936
public FirebaseIndexArray(Query keyRef, Query dataRef) {
4037
super(keyRef);
@@ -44,9 +41,8 @@ public FirebaseIndexArray(Query keyRef, Query dataRef) {
4441
@Override
4542
public void cleanup() {
4643
super.cleanup();
47-
Set<Query> refs = new HashSet<>(mRefs.keySet());
48-
for (Query ref : refs) {
49-
ref.removeEventListener(mRefs.remove(ref));
44+
for (Map.Entry<Query, ValueEventListener> entry : mRefs.entrySet()) {
45+
entry.getKey().removeEventListener(entry.getValue());
5046
}
5147
}
5248

@@ -60,21 +56,7 @@ public DataSnapshot getItem(int index) {
6056
return mDataSnapshots.get(index);
6157
}
6258

63-
private int getIndexForKey(String key) {
64-
int dataCount = getCount();
65-
int index = 0;
66-
for (int keyIndex = 0; index < dataCount; keyIndex++) {
67-
String superKey = super.getItem(keyIndex).getKey();
68-
if (key.equals(superKey)) {
69-
break;
70-
} else if (mDataSnapshots.get(index).getKey().equals(superKey)) {
71-
index++;
72-
}
73-
}
74-
return index;
75-
}
76-
77-
private boolean isMatch(int index, String key) {
59+
private boolean isKeyAtIndex(int index, String key) {
7860
return index >= 0 && index < getCount() && mDataSnapshots.get(index).getKey().equals(key);
7961
}
8062

@@ -105,7 +87,7 @@ public void onChildRemoved(DataSnapshot keySnapshot) {
10587
super.onChildRemoved(keySnapshot);
10688
super.setOnChangedListener(mListener);
10789

108-
if (isMatch(index, key)) {
90+
if (isKeyAtIndex(index, key)) {
10991
mDataSnapshots.remove(index);
11092
notifyChangedListeners(OnChangedListener.EventType.REMOVED, index);
11193
}
@@ -120,7 +102,7 @@ public void onChildMoved(DataSnapshot keySnapshot, String previousChildKey) {
120102
super.onChildMoved(keySnapshot, previousChildKey);
121103
super.setOnChangedListener(mListener);
122104

123-
if (isMatch(oldIndex, key)) {
105+
if (isKeyAtIndex(oldIndex, key)) {
124106
DataSnapshot snapshot = mDataSnapshots.remove(oldIndex);
125107
int newIndex = getIndexForKey(key);
126108
mDataSnapshots.add(newIndex, snapshot);
@@ -147,15 +129,15 @@ public void onDataChange(DataSnapshot snapshot) {
147129
int index = getIndexForKey(key);
148130

149131
if (snapshot.getValue() != null) {
150-
if (!isMatch(index, key)) {
132+
if (!isKeyAtIndex(index, key)) {
151133
mDataSnapshots.add(index, snapshot);
152134
notifyChangedListeners(OnChangedListener.EventType.ADDED, index);
153135
} else {
154136
mDataSnapshots.set(index, snapshot);
155137
notifyChangedListeners(OnChangedListener.EventType.CHANGED, index);
156138
}
157139
} else {
158-
if (isMatch(index, key)) {
140+
if (isKeyAtIndex(index, key)) {
159141
mDataSnapshots.remove(index);
160142
notifyChangedListeners(OnChangedListener.EventType.REMOVED, index);
161143
} else {

0 commit comments

Comments
 (0)