--- deliantra/server/ext/map-tags.ext 2007/09/11 13:27:53 1.2 +++ deliantra/server/ext/map-tags.ext 2007/11/14 08:09:46 1.10 @@ -1,6 +1,6 @@ #! perl # mandatory -our $SCHEDULE_INTERVAL = $cf::CFG{extractor_schedule_interval} || 3600; +our $SCHEDULE_INTERVAL = $cf::CFG{extractor_schedule_interval} || 3600; use JSON::XS; @@ -79,9 +79,10 @@ # we don't actually care if it succeeds or not, as we # will just retry an hour later - BDB::db_txn_commit $txn; + BDB::db_txn_finish $txn; -# warn "tag-updated $file (= $key) $hash\n";#d# + warn "tag-updated $file (= $key) <@tags>\n" + if @tags; } sub scan_static { @@ -102,23 +103,47 @@ for @$dirs; } -cf::async_ext { - $Coro::current->prio (Coro::PRIO_MIN); +sub reload { + my $guard = cf::lock_acquire "map-tags::reload"; - while () { - my $start = Event::time; + my $start = EV::time; - # 1. check for maps no longer existing + # 1. check for maps no longer existing + { + my @delkeys; + + my $cursor = $db_mapinfo->cursor; + for (;;) { + BDB::db_c_get $cursor, my $key, my $data, BDB::NEXT; + last if $!; + + my $data = JSON::XS::from_json $data; + my ($ver, undef, undef, $path) = split /,/, $data->{hash}, 4; + push @delkeys, [$key, $data->{tags}] + if $ver != 1 || Coro::AIO::aio_stat $path; + } + BDB::db_c_close $cursor; + + for (@delkeys) { + my ($key, $tags) = @$_; + my $txn = $cf::DB_ENV->txn_begin; + BDB::db_del $db_mapinfo, $txn, $key; + for my $tag (@{ $tags || [] }) { + remove_tag_target $txn, $tag, $key; + } + BDB::db_txn_finish $txn; + } + } - # 2. scan all static maps - scan_static $cf::MAPDIR, "/"; + # 2. scan all static maps + scan_static $cf::MAPDIR, "/"; - # 3. scan all dynamic maps - for my $path (@{ cf::map::tmp_maps or [] }, @{ cf::map::random_maps or [] }) { + # 3. scan all dynamic maps + for my $path (@{ cf::map::tmp_maps or [] }, @{ cf::map::random_maps or [] }) { # my $map = cf::map::find $path; # extract_map_tags "t/$map", $path; - } - + } + # now hunt for all per-player maps # scan_dir $cf::PLAYERDIR # for my $login (@{ cf::player::list_logins or [] }) { @@ -146,30 +171,28 @@ # } # } - warn sprintf "map-tag scan (%fs)", Event::time - $start; - Coro::Timer::sleep $SCHEDULE_INTERVAL; - } + warn sprintf "map-tag scan (%fs)", EV::time - $start; +} + +our $RELOAD_SCHEDULER = cf::periodic $SCHEDULE_INTERVAL, sub { + cfd::async { + $Coro::current->prio (Coro::PRIO_MIN); + $Coro::current->desc ("map-tag scanner"); + reload; + }; }; +# find all objects with the given tag, or at least try to sub find($) { my ($tag) = @_; - my @res; - - utf8::encode $tag; - BDB::db_get $db_target, undef, $tag, my $data; + utf8::encode (my $key = $tag); + BDB::db_get $db_target, undef, $key, my $data; utf8::decode $data; - for my $map ( + map { $_->load; $_->find_tagged_objects ($tag) } grep $_, map { cf::map::find $_ } grep s/^s//, split /\x00/, $data - ) { - $map->load; - - warn "tag<$tag>map<$map>\n";#d# - } - - @res }