1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-23 06:42:05 +01:00

[SMACK-235] Switched to a much faster, but also thread safe, concurrenthashmap for entries list.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@9687 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Daniel Henninger 2007-12-27 15:54:56 +00:00 committed by dhenninger
parent 0a455fe195
commit 048e5b679c

View file

@ -57,7 +57,7 @@ public class Roster {
private XMPPConnection connection; private XMPPConnection connection;
private final Map<String, RosterGroup> groups; private final Map<String, RosterGroup> groups;
private final List<RosterEntry> entries; private final Map<String,RosterEntry> entries;
private final List<RosterEntry> unfiledEntries; private final List<RosterEntry> unfiledEntries;
private final List<RosterListener> rosterListeners; private final List<RosterListener> rosterListeners;
private Map<String, Map<String, Presence>> presenceMap; private Map<String, Map<String, Presence>> presenceMap;
@ -101,7 +101,7 @@ public class Roster {
this.connection = connection; this.connection = connection;
groups = new ConcurrentHashMap<String, RosterGroup>(); groups = new ConcurrentHashMap<String, RosterGroup>();
unfiledEntries = new CopyOnWriteArrayList<RosterEntry>(); unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
entries = new CopyOnWriteArrayList<RosterEntry>(); entries = new ConcurrentHashMap<String,RosterEntry>();
rosterListeners = new CopyOnWriteArrayList<RosterListener>(); rosterListeners = new CopyOnWriteArrayList<RosterListener>();
presenceMap = new ConcurrentHashMap<String, Map<String, Presence>>(); presenceMap = new ConcurrentHashMap<String, Map<String, Presence>>();
// Listen for any roster packets. // Listen for any roster packets.
@ -271,7 +271,7 @@ public class Roster {
public void removeEntry(RosterEntry entry) throws XMPPException { public void removeEntry(RosterEntry entry) throws XMPPException {
// Only remove the entry if it's in the entry list. // Only remove the entry if it's in the entry list.
// The actual removal logic takes place in RosterPacketListenerprocess>>Packet(Packet) // The actual removal logic takes place in RosterPacketListenerprocess>>Packet(Packet)
if (!entries.contains(entry)) { if (!entries.containsKey(entry.getUser())) {
return; return;
} }
RosterPacket packet = new RosterPacket(); RosterPacket packet = new RosterPacket();
@ -353,13 +353,7 @@ public class Roster {
if (user == null) { if (user == null) {
return null; return null;
} }
String userLowerCase = user.toLowerCase(); return entries.get(user.toLowerCase());
for (RosterEntry entry : entries) {
if (entry.getUser().equals(userLowerCase)) {
return entry;
}
}
return null;
} }
/** /**
@ -671,12 +665,10 @@ public class Roster {
// Add the new presence, using the resources as a key. // Add the new presence, using the resources as a key.
userPresences.put(StringUtils.parseResource(from), presence); userPresences.put(StringUtils.parseResource(from), presence);
// If the user is in the roster, fire an event. // If the user is in the roster, fire an event.
for (RosterEntry entry : entries) { RosterEntry entry = entries.get(key);
if (entry.getUser().equals(key)) { if (entry != null)
fireRosterPresenceEvent(presence); fireRosterPresenceEvent(presence);
} }
}
}
// If an "unavailable" packet. // If an "unavailable" packet.
else if (presence.getType() == Presence.Type.unavailable) { else if (presence.getType() == Presence.Type.unavailable) {
// If no resource, this is likely an offline presence as part of // If no resource, this is likely an offline presence as part of
@ -701,12 +693,10 @@ public class Roster {
userPresences.put(StringUtils.parseResource(from), presence); userPresences.put(StringUtils.parseResource(from), presence);
} }
// If the user is in the roster, fire an event. // If the user is in the roster, fire an event.
for (RosterEntry entry : entries) { RosterEntry entry = entries.get(key);
if (entry.getUser().equals(key)) { if (entry != null)
fireRosterPresenceEvent(presence); fireRosterPresenceEvent(presence);
} }
}
}
else if (presence.getType() == Presence.Type.subscribe) { else if (presence.getType() == Presence.Type.subscribe) {
if (subscriptionMode == SubscriptionMode.accept_all) { if (subscriptionMode == SubscriptionMode.accept_all) {
// Accept all subscription requests. // Accept all subscription requests.
@ -756,8 +746,8 @@ public class Roster {
// If the packet is of the type REMOVE then remove the entry // If the packet is of the type REMOVE then remove the entry
if (RosterPacket.ItemType.remove.equals(item.getItemType())) { if (RosterPacket.ItemType.remove.equals(item.getItemType())) {
// Remove the entry from the entry list. // Remove the entry from the entry list.
if (entries.contains(entry)) { if (entries.containsKey(item.getUser())) {
entries.remove(entry); entries.remove(item.getUser());
} }
// Remove the entry from the unfiled entry list. // Remove the entry from the unfiled entry list.
if (unfiledEntries.contains(entry)) { if (unfiledEntries.contains(entry)) {
@ -773,16 +763,15 @@ public class Roster {
} }
else { else {
// Make sure the entry is in the entry list. // Make sure the entry is in the entry list.
if (!entries.contains(entry)) { if (!entries.containsKey(item.getUser())) {
entries.add(entry); entries.put(item.getUser(), entry);
// Keep note that an entry has been added // Keep note that an entry has been added
addedEntries.add(item.getUser()); addedEntries.add(item.getUser());
} }
else { else {
// If the entry was in then list then update its state with the new values // If the entry was in then list then update its state with the new values
RosterEntry existingEntry = entries.get(entries.indexOf(entry)); entries.put(item.getUser(), entry);
existingEntry
.updateState(entry.getName(), entry.getType(), entry.getStatus());
// Keep note that an entry has been updated // Keep note that an entry has been updated
updatedEntries.add(item.getUser()); updatedEntries.add(item.getUser());
} }