Comparison

core/rostermanager.lua @ 7155:4a0825984e42

rostermanager: Use map stores when only one contact is changed
author Kim Alvefur <zash@zash.se>
date Tue, 09 Feb 2016 17:09:01 +0100
parent 7154:b3b92204802f
child 7167:7ae430fecf12
comparison
equal deleted inserted replaced
7154:b3b92204802f 7155:4a0825984e42
27 27
28 local function add_to_roster(session, jid, item) 28 local function add_to_roster(session, jid, item)
29 if session.roster then 29 if session.roster then
30 local old_item = session.roster[jid]; 30 local old_item = session.roster[jid];
31 session.roster[jid] = item; 31 session.roster[jid] = item;
32 if save_roster(session.username, session.host) then 32 if save_roster(session.username, session.host, nil, jid) then
33 return true; 33 return true;
34 else 34 else
35 session.roster[jid] = old_item; 35 session.roster[jid] = old_item;
36 return nil, "wait", "internal-server-error", "Unable to save roster"; 36 return nil, "wait", "internal-server-error", "Unable to save roster";
37 end 37 end
42 42
43 local function remove_from_roster(session, jid) 43 local function remove_from_roster(session, jid)
44 if session.roster then 44 if session.roster then
45 local old_item = session.roster[jid]; 45 local old_item = session.roster[jid];
46 session.roster[jid] = nil; 46 session.roster[jid] = nil;
47 if save_roster(session.username, session.host) then 47 if save_roster(session.username, session.host, nil, jid) then
48 return true; 48 return true;
49 else 49 else
50 session.roster[jid] = old_item; 50 session.roster[jid] = old_item;
51 return nil, "wait", "internal-server-error", "Unable to save roster"; 51 return nil, "wait", "internal-server-error", "Unable to save roster";
52 end 52 end
121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); 121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster });
122 end 122 end
123 return roster, err; 123 return roster, err;
124 end 124 end
125 125
126 function save_roster(username, host, roster) 126 function save_roster(username, host, roster, jid)
127 if not um_user_exists(username, host) then 127 if not um_user_exists(username, host) then
128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host); 128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host);
129 return nil; 129 return nil;
130 end 130 end
131 131
132 log("debug", "save_roster: saving roster for %s@%s", username, host); 132 log("debug", "save_roster: saving roster for %s@%s, (%s)", username, host, jid or "all contacts");
133 if not roster then 133 if not roster then
134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster; 134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster;
135 --if not roster then 135 --if not roster then
136 -- --roster = load_roster(username, host); 136 -- --roster = load_roster(username, host);
137 -- return true; -- roster unchanged, no reason to save 137 -- return true; -- roster unchanged, no reason to save
141 local metadata = roster_metadata(roster); 141 local metadata = roster_metadata(roster);
142 if metadata.version ~= true then 142 if metadata.version ~= true then
143 metadata.version = (metadata.version or 0) + 1; 143 metadata.version = (metadata.version or 0) + 1;
144 end 144 end
145 if metadata.broken then return nil, "Not saving broken roster" end 145 if metadata.broken then return nil, "Not saving broken roster" end
146 local roster_store = require "core.storagemanager".open(host, "roster", "keyval"); 146 if jid == nil then
147 return roster_store:set(username, roster); 147 local roster_store = require "core.storagemanager".open(host, "roster", "keyval");
148 return roster_store:set(username, roster);
149 else
150 local roster_store = require "core.storagemanager".open(host, "roster", "map");
151 return roster_store:set_keys(username, { [false] = metadata, [jid] = roster[jid] or roster_store.remove });
152 end
148 end 153 end
149 log("warn", "save_roster: user had no roster to save"); 154 log("warn", "save_roster: user had no roster to save");
150 return nil; 155 return nil;
151 end 156 end
152 157
158 item.subscription = "to"; 163 item.subscription = "to";
159 else -- subscription == from 164 else -- subscription == from
160 item.subscription = "both"; 165 item.subscription = "both";
161 end 166 end
162 item.ask = nil; 167 item.ask = nil;
163 return save_roster(username, host, roster); 168 return save_roster(username, host, roster, jid);
164 end 169 end
165 end 170 end
166 171
167 local is_contact_pending_out -- forward declaration 172 local is_contact_pending_out -- forward declaration
168 173
182 item.subscription = "from"; 187 item.subscription = "from";
183 changed = true; 188 changed = true;
184 end 189 end
185 end 190 end
186 if changed then 191 if changed then
187 return save_roster(username, host, roster); 192 return save_roster(username, host, roster, jid);
188 end 193 end
189 end 194 end
190 195
191 local is_contact_pending_in -- forward declaration 196 local is_contact_pending_in -- forward declaration
192 197
206 item.subscription = "to"; 211 item.subscription = "to";
207 changed = true; 212 changed = true;
208 end 213 end
209 end 214 end
210 if changed then 215 if changed then
211 return save_roster(username, host, roster); 216 return save_roster(username, host, roster, jid);
212 end 217 end
213 end 218 end
214 219
215 local function _get_online_roster_subscription(jidA, jidB) 220 local function _get_online_roster_subscription(jidA, jidB)
216 local user = bare_sessions[jidA]; 221 local user = bare_sessions[jidA];
239 local item = roster[jid]; 244 local item = roster[jid];
240 if item and (item.subscription == "from" or item.subscription == "both") then 245 if item and (item.subscription == "from" or item.subscription == "both") then
241 return; -- false 246 return; -- false
242 end 247 end
243 roster[false].pending[jid] = true; 248 roster[false].pending[jid] = true;
244 return save_roster(username, host, roster); 249 return save_roster(username, host, roster, jid);
245 end 250 end
246 function is_contact_pending_out(username, host, jid) 251 function is_contact_pending_out(username, host, jid)
247 local roster = load_roster(username, host); 252 local roster = load_roster(username, host);
248 local item = roster[jid]; 253 local item = roster[jid];
249 return item and item.ask; 254 return item and item.ask;
258 item = {subscription = "none", groups = {}}; 263 item = {subscription = "none", groups = {}};
259 roster[jid] = item; 264 roster[jid] = item;
260 end 265 end
261 item.ask = "subscribe"; 266 item.ask = "subscribe";
262 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid); 267 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid);
263 return save_roster(username, host, roster); 268 return save_roster(username, host, roster, jid);
264 end 269 end
265 local function unsubscribe(username, host, jid) 270 local function unsubscribe(username, host, jid)
266 local roster = load_roster(username, host); 271 local roster = load_roster(username, host);
267 local item = roster[jid]; 272 local item = roster[jid];
268 if not item then return false; end 273 if not item then return false; end
273 if item.subscription == "both" then 278 if item.subscription == "both" then
274 item.subscription = "from"; 279 item.subscription = "from";
275 elseif item.subscription == "to" then 280 elseif item.subscription == "to" then
276 item.subscription = "none"; 281 item.subscription = "none";
277 end 282 end
278 return save_roster(username, host, roster); 283 return save_roster(username, host, roster, jid);
279 end 284 end
280 local function subscribed(username, host, jid) 285 local function subscribed(username, host, jid)
281 if is_contact_pending_in(username, host, jid) then 286 if is_contact_pending_in(username, host, jid) then
282 local roster = load_roster(username, host); 287 local roster = load_roster(username, host);
283 local item = roster[jid]; 288 local item = roster[jid];
289 item.subscription = "from"; 294 item.subscription = "from";
290 else -- subscription == to 295 else -- subscription == to
291 item.subscription = "both"; 296 item.subscription = "both";
292 end 297 end
293 roster[false].pending[jid] = nil; 298 roster[false].pending[jid] = nil;
294 return save_roster(username, host, roster); 299 return save_roster(username, host, roster, jid);
295 end -- TODO else implement optional feature pre-approval (ask = subscribed) 300 end -- TODO else implement optional feature pre-approval (ask = subscribed)
296 end 301 end
297 local function unsubscribed(username, host, jid) 302 local function unsubscribed(username, host, jid)
298 local roster = load_roster(username, host); 303 local roster = load_roster(username, host);
299 local item = roster[jid]; 304 local item = roster[jid];
309 elseif item.subscription == "both" then 314 elseif item.subscription == "both" then
310 item.subscription = "to"; 315 item.subscription = "to";
311 is_subscribed = true; 316 is_subscribed = true;
312 end 317 end
313 end 318 end
314 local success = (pending or is_subscribed) and save_roster(username, host, roster); 319 local success = (pending or is_subscribed) and save_roster(username, host, roster, jid);
315 return success, pending, subscribed; 320 return success, pending, subscribed;
316 end 321 end
317 322
318 local function process_outbound_subscription_request(username, host, jid) 323 local function process_outbound_subscription_request(username, host, jid)
319 local roster = load_roster(username, host); 324 local roster = load_roster(username, host);
320 local item = roster[jid]; 325 local item = roster[jid];
321 if item and (item.subscription == "none" or item.subscription == "from") then 326 if item and (item.subscription == "none" or item.subscription == "from") then
322 item.ask = "subscribe"; 327 item.ask = "subscribe";
323 return save_roster(username, host, roster); 328 return save_roster(username, host, roster, jid);
324 end 329 end
325 end 330 end
326 331
327 --[[function process_outbound_subscription_approval(username, host, jid) 332 --[[function process_outbound_subscription_approval(username, host, jid)
328 local roster = load_roster(username, host); 333 local roster = load_roster(username, host);