util/datamanager.lua
changeset 13141 b417a49cc31b
parent 13138 638f627e707f
child 13184 48622b89f570
equal deleted inserted replaced
13140:396db0e7084f 13141:b417a49cc31b
   258 	return true, pos;
   258 	return true, pos;
   259 end
   259 end
   260 
   260 
   261 local index_fmt, index_item_size, index_magic;
   261 local index_fmt, index_item_size, index_magic;
   262 if string.packsize then
   262 if string.packsize then
   263 	index_fmt = "TT"; -- struct { size_t start, size_t length }
   263 	index_fmt = "T"; -- offset to the end of the item, length can be derived from two index items
   264 	index_item_size = string.packsize(index_fmt);
   264 	index_item_size = string.packsize(index_fmt);
   265 	index_magic = string.pack(index_fmt, 7767639, 1); -- Magic string: T9 for "prosody", version number
   265 	index_magic = string.pack(index_fmt, 7767639 + 1); -- Magic string: T9 for "prosody", version number
   266 end
   266 end
   267 
   267 
   268 local function list_append(username, host, datastore, data)
   268 local function list_append(username, host, datastore, data)
   269 	if not data then return; end
   269 	if not data then return; end
   270 	if callback(username, host, datastore) == false then return true; end
   270 	if callback(username, host, datastore) == false then return true; end
   277 			datastore, msg, where, username or "nil", host or "nil");
   277 			datastore, msg, where, username or "nil", host or "nil");
   278 		return ok, msg;
   278 		return ok, msg;
   279 	end
   279 	end
   280 	if string.packsize then
   280 	if string.packsize then
   281 		local offset = type(msg) == "number" and msg or 0;
   281 		local offset = type(msg) == "number" and msg or 0;
   282 		local index_entry = string.pack(index_fmt, offset, #data);
   282 		local index_entry = string.pack(index_fmt, offset + #data);
   283 		if offset == 0 then
   283 		if offset == 0 then
   284 			index_entry = index_magic .. index_entry;
   284 			index_entry = index_magic .. index_entry;
   285 		end
   285 		end
   286 		local ok, off = append(username, host, datastore, "lidx", index_entry);
   286 		local ok, off = append(username, host, datastore, "lidx", index_entry);
   287 		off = off or 0;
   287 		off = off or 0;
   356 end
   356 end
   357 
   357 
   358 local function store_list_index(username, host, datastore, index)
   358 local function store_list_index(username, host, datastore, index)
   359 	local data = { index_magic };
   359 	local data = { index_magic };
   360 	for i, v in ipairs(index) do
   360 	for i, v in ipairs(index) do
   361 		data[i + 1] = string.pack(index_fmt, v.start, v.length);
   361 		data[i + 1] = string.pack(index_fmt, v.start + v.length);
   362 	end
   362 	end
   363 	local filename = getpath(username, host, datastore, "lidx");
   363 	local filename = getpath(username, host, datastore, "lidx");
   364 	return atomic_store(filename, t_concat(data));
   364 	return atomic_store(filename, t_concat(data));
   365 end
   365 end
   366 
   366 
   367 local index_mt = {
   367 local index_mt = {
   368 	__index = function(t, i)
   368 	__index = function(t, i)
   369 		if type(i) ~= "number" or i % 1 ~= 0 or i < 1 then
   369 		if type(i) ~= "number" or i % 1 ~= 0 or i < 0 then
   370 			return
   370 			return
   371 		end
   371 		end
   372 		if i < 0 then
   372 		if i <= 0 then
   373 			return
   373 			return 0
   374 		end
   374 		end
   375 		local fh = t.file;
   375 		local fh = t.file;
   376 		local pos = i * index_item_size;
   376 		local pos = (i - 1) * index_item_size;
   377 		if fh:seek("set", pos) ~= pos then
   377 		if fh:seek("set", pos) ~= pos then
   378 			return nil
   378 			return nil
   379 		end
   379 		end
   380 		local data = fh:read(index_item_size);
   380 		local data = fh:read(index_item_size * 2);
   381 		if not data then
   381 		if not data or #data ~= index_item_size * 2 then
   382 			return nil
   382 			return nil
   383 		end
   383 		end
   384 		local start, length = string.unpack(index_fmt, data);
   384 		local start, next_pos = string.unpack(index_fmt .. index_fmt, data);
       
   385 		if pos == 0 then
       
   386 			start = 0
       
   387 		end
       
   388 		local length = next_pos - start;
   385 		local v = { start = start; length = length };
   389 		local v = { start = start; length = length };
   386 		t[i] = v;
   390 		t[i] = v;
   387 		return v;
   391 		return v;
   388 	end;
   392 	end;
   389 	__len = function(t)
   393 	__len = function(t)