--- deliantra/server/ext/map-tags.ext 2007/12/05 11:08:34 1.13 +++ deliantra/server/ext/map-tags.ext 2010/05/04 21:45:42 1.26 @@ -4,8 +4,8 @@ use JSON::XS; -my $db_mapinfo = cf::sync_job { cf::db_table "tag-mapinfo" }; # info/cache for maps -my $db_target = cf::sync_job { cf::db_table "tag-target" }; # tag => maps +our $db_mapinfo = cf::db_table "tag-mapinfo"; # info/cache for maps +our $db_target = cf::db_table "tag-target"; # tag => maps sub remove_tag_target { my ($txn, $tag, $target) = @_; @@ -42,8 +42,6 @@ my $hash = join ",", 1, (stat _)[7,9], $file; - my $old_tags; - my $txn = $cf::DB_ENV->txn_begin; utf8::encode $key; @@ -52,10 +50,11 @@ unless ($!) { $data = decode_json $data; return if $data->{hash} eq $hash; - $old_tags = $data->{tags}; - } - $old_tags ||= []; + # remove all old tags unconditionally + remove_tag_target $txn, $_, $key + for @{ $data->{tags} }; + } my $f = new_from_file cf::object::thawer $file or return; @@ -65,48 +64,29 @@ BDB::db_put $db_mapinfo, $txn, $key, $data; - # 1. remove tags no longer existing - for my $tag (@$old_tags) { - next if grep $_ eq $tag, @tags; - remove_tag_target $txn, $tag, $key; - } - - # 2. add tags that are new - for my $tag (@tags) { - next if grep $_ eq $tag, @$old_tags; - add_tag_target $txn, $tag, $key; - } + # add all tags + add_tag_target $txn, $_, $key + for @tags; # we don't actually care if it succeeds or not, as we # will just retry an hour later BDB::db_txn_finish $txn; - warn "tag-updated $file (= $key) <@tags>\n" + cf::debug "tag-updated $file (= $key) <@tags>\n" if @tags; } sub scan_static { - my ($dir, $map) = @_; - - my ($dirs, $files) = Coro::AIO::aio_scandir $dir, 2 - or return; - - for my $file (@$files) { - my $name = $file; - next unless $name =~ s/\.map$//; - utf8::decode $name; + my $maps = cf::map::static_maps; - scan_map "s$map$name", "$dir/$file"; - } - - &scan_static ("$dir/$_", "$map$_/") - for @$dirs; + scan_map "s$_", "$cf::MAPDIR$_.map" + for @$maps; } sub reload { my $guard = cf::lock_acquire "map-tags::reload"; - my $start = EV::time; + my $start = AE::time; # 1. check for maps no longer existing { @@ -171,7 +151,7 @@ # } # } - warn sprintf "map-tag scan (%fs)", EV::time - $start; + cf::info sprintf "map-tag scan finished (%fs)\n", AE::time - $start; } our $RELOAD_SCHEDULER = cf::periodic $SCHEDULE_INTERVAL, Coro::unblock_sub { @@ -180,7 +160,9 @@ reload; }; -cf::async { reload }; # force at startup +cf::post_init { + $RELOAD_SCHEDULER->invoke (0); # force at startup +}; # find all objects with the given tag, or at least try to sub find($) { @@ -196,3 +178,11 @@ grep s/^s//, split /\x00/, $data } + +sub unload { + my $guard = cf::lock_acquire "map-tags::reload"; + + BDB::db_close $db_target; + BDB::db_close $db_mapinfo; +} +