--- deliantra/Deliantra-Client/DC/DB.pm 2008/01/19 04:49:37 1.32 +++ deliantra/Deliantra-Client/DC/DB.pm 2008/03/30 04:59:42 1.34 @@ -45,7 +45,7 @@ our $DB_STATE; our %DB_TABLE; -sub open_db { +sub try_open_db { mkdir $DB_HOME, 0777; $DB_ENV = db_env_create; @@ -86,20 +86,9 @@ ############################################################################# -unless (eval { open_db }) { - warn "$@";#d# - eval { File::Path::rmtree $DB_HOME }; - open_db; -} - -our $WATCHER = EV::io BDB::poll_fileno, EV::READ, \&BDB::poll_cb; - -our $SYNC = EV::timer_ns 0, 60, sub { - $_[0]->stop; - db_env_txn_checkpoint $DB_ENV, 0, 0, 0, sub { }; -}; - -our $tilemap; +our $WATCHER; +our $SYNC; +our $facemap; sub exists($$$) { my ($db, $key, $cb) = @_; @@ -121,6 +110,7 @@ sub put($$$$) { my ($db, $key, $data, $cb) = @_; + warn "put $key ",(length $data),"\n";#d# db_put table $db, undef, $key, $data, 0, sub { $cb->($!); @@ -152,7 +142,7 @@ my $id; db_get $table, undef, $name, $id, 0; - return $cb->($id) unless $!; + $! or return $cb->($id); for (1..100) { my $txn = $DB_ENV->txn_begin; @@ -165,9 +155,11 @@ db_put $table, $txn, id => $id, 0; db_txn_finish $txn; - $SYNC->again unless $SYNC->is_active; - - return $cb->($id) unless $!; + unless ($!) { + db_put $table, undef, $name => $id; + $SYNC->again unless $SYNC->is_active; + return $cb->($id); + } select undef, undef, undef, 0.01 * rand; } @@ -178,7 +170,7 @@ sub get_tile_id_sync($) { my ($name) = @_; - $tilemap->{$name} ||= do { + $facemap->{$name} ||= do { my $id; do_get_tile_id $name, sub { $id = $_[0]; @@ -223,19 +215,6 @@ ############################################################################# -# fetch the full face table first -unless ($tilemap) { - do_table facemap => sub { - $tilemap = $_[0]; - delete $tilemap->{id}; - my %maptile = reverse %$tilemap;#d# - if ((scalar keys %$tilemap) != (scalar keys %maptile)) {#d# - $tilemap = { };#d# - DC::error "FATAL: facemap is not a 1:1 mapping, please report this and delete your $DB_HOME directory!\n";#d# - }#d# - }; -} - package DC::DB::Server; use strict; @@ -424,6 +403,41 @@ close $FH; } +package DC::DB; + +sub open_db { + unless (eval { try_open_db }) { + warn "$@";#d# + eval { File::Path::rmtree $DB_HOME }; + try_open_db; + } + + # fetch the full face table first + unless ($facemap) { + do_table facemap => sub { + $facemap = $_[0]; + delete $facemap->{id}; + my %maptile = reverse %$facemap;#d# + if ((scalar keys %$facemap) != (scalar keys %maptile)) {#d# + $facemap = { };#d# + DC::error "FATAL: facemap is not a 1:1 mapping, please report this and delete your $DB_HOME directory!\n";#d# + }#d# + }; + } + + $WATCHER = EV::io BDB::poll_fileno, EV::READ, \&BDB::poll_cb; + $SYNC = EV::timer_ns 0, 60, sub { + warn "SYNC\n";#d# + $_[0]->stop; + db_env_txn_checkpoint $DB_ENV, 0, 0, 0, sub { }; + }; +} + +END { + %DB_TABLE = (); + undef $DB_ENV; +} + 1; =back