mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-07-14 00:01:30 -04:00
115 lines
2.9 KiB
Plaintext
115 lines
2.9 KiB
Plaintext
create or replace package body objectidmanager
|
|
as
|
|
|
|
procedure get_ids(how_many in out number, block_start_id out number, block_end_id out number)
|
|
as
|
|
result_cursor cursortype;
|
|
begin
|
|
delete free_object_ids
|
|
where end_id is not null
|
|
and rownum=1
|
|
returning start_id, end_id
|
|
into block_start_id, block_end_id;
|
|
|
|
if (sql%rowcount = 0) then
|
|
update free_object_ids
|
|
set start_id = start_id + how_many
|
|
where end_id is null
|
|
returning start_id - how_many, start_id - 1
|
|
into block_start_id, block_end_id;
|
|
end if;
|
|
|
|
how_many := block_end_id - block_start_id + 1;
|
|
end;
|
|
|
|
-- same as get_ids, except guarantees the ids are all contiguous
|
|
-- (therefore it can return just the starting id)
|
|
function get_contiguous_ids(min_count number) return number
|
|
as
|
|
result_cursor cursortype;
|
|
block_start_id number;
|
|
block_end_id number;
|
|
begin
|
|
update free_object_ids
|
|
set start_id = start_id + min_count
|
|
where (end_id - start_id + 1 >= min_count
|
|
or end_id is null)
|
|
and rownum < 2
|
|
returning start_id - min_count, start_id - 1
|
|
into block_start_id, block_end_id;
|
|
|
|
if (block_start_id > block_end_id) then -- entire block was consumed
|
|
delete free_object_ids where start_id = block_start_id;
|
|
end if;
|
|
|
|
return block_start_id;
|
|
end;
|
|
|
|
-- get only one id
|
|
function get_single_id return number
|
|
as
|
|
block_start_id number;
|
|
block_end_id number;
|
|
begin
|
|
update
|
|
free_object_ids
|
|
set
|
|
start_id = start_id + 1
|
|
where
|
|
rownum=1
|
|
returning
|
|
start_id,
|
|
end_id
|
|
into
|
|
block_start_id,
|
|
block_end_id;
|
|
|
|
if (block_start_id > block_end_id) then -- entire block was consumed
|
|
delete free_object_ids where start_id = block_start_id;
|
|
end if;
|
|
|
|
return block_start_id - 1;
|
|
end;
|
|
|
|
procedure rebuild_freelist
|
|
as
|
|
message_count number;
|
|
message_id_block number;
|
|
begin
|
|
delete free_object_ids;
|
|
|
|
-- following is not legal in PL/SQL, so it must be "execute immediated"
|
|
execute immediate 'insert into free_object_ids (end_id, start_id) '||
|
|
'select o1.object_id-1 end_id, (select max(o2.object_id) from objects o2 where o1.object_id > o2.object_id)+1 start_id ' ||
|
|
'from objects o1 ' ||
|
|
'where o1.object_id > (select max(o2.object_id)+1 from objects o2 where o1.object_id > o2.object_id)';
|
|
|
|
insert into free_object_ids (start_id, end_id)
|
|
select * from
|
|
(select 1,min(object_id)-1
|
|
from objects)
|
|
where not exists (select * from objects where object_id = 1);
|
|
|
|
insert into free_object_ids (start_id, end_id)
|
|
select * from
|
|
(select max(object_id)+1,NULL
|
|
from objects)
|
|
where exists (select * from objects);
|
|
|
|
--easier to ignore messages while finding free object ids and then fix them up at the end:
|
|
|
|
select count(*)
|
|
into message_count
|
|
from messages
|
|
where rownum = 1;
|
|
|
|
if (message_count <> 0) then
|
|
message_id_block := get_contiguous_ids(message_count);
|
|
|
|
update messages
|
|
set message_id = rownum + message_id_block - 1;
|
|
end if;
|
|
end;
|
|
end;
|
|
/
|