--- deliantra/Deliantra-Client/DC/DB.pm 2008/03/30 04:59:42 1.34 +++ deliantra/Deliantra-Client/DC/DB.pm 2008/03/30 06:05:52 1.35 @@ -17,6 +17,7 @@ use strict; use utf8; +use File::Path (); use Carp (); use Storable (); use Config; @@ -28,14 +29,17 @@ our $DBDIR = "client-" . BDB::VERSION . "-$Config{archname}"; our $DB_HOME = "$Deliantra::VARDIR/$DBDIR"; -if (!-e $DB_HOME and -e "$Deliantra::VARDIR/$ODBDIR") { - rename "$Deliantra::VARDIR/$ODBDIR", $DB_HOME; - print STDERR "INFO: moved old database from $Deliantra::VARDIR/$ODBDIR to $DB_HOME\n"; -} - -if (!-e $DB_HOME and -e "$Deliantra::OLDDIR/$ODBDIR") { - rename "$Deliantra::OLDDIR/$DBDIR", $DB_HOME; - print STDERR "INFO: moved old database from $Deliantra::OLDDIR/$ODBDIR to $DB_HOME\n"; +unless (-d $DB_HOME) { + if (-d "$Deliantra::VARDIR/$ODBDIR") { + rename "$Deliantra::VARDIR/$ODBDIR", $DB_HOME; + print STDERR "INFO: moved old database from $Deliantra::VARDIR/$ODBDIR to $DB_HOME\n"; + } elsif (-d "$Deliantra::OLDDIR/$ODBDIR") { + rename "$Deliantra::OLDDIR/$DBDIR", $DB_HOME; + print STDERR "INFO: moved old database from $Deliantra::OLDDIR/$ODBDIR to $DB_HOME\n"; + } else { + File::Path::mkpath [$DB_HOME] + or die "unable to create database directory $DB_HOME: $!"; + } } BDB::max_poll_time 0.03; @@ -44,9 +48,10 @@ our $DB_ENV; our $DB_STATE; our %DB_TABLE; +our $TILE_SEQ; sub try_open_db { - mkdir $DB_HOME, 0777; + File::Path::mkpath [$DB_HOME]; $DB_ENV = db_env_create; @@ -110,7 +115,6 @@ sub put($$$$) { my ($db, $key, $data, $cb) = @_; - warn "put $key ",(length $data),"\n";#d# db_put table $db, undef, $key, $data, 0, sub { $cb->($!); @@ -141,30 +145,24 @@ my $table = table "facemap"; my $id; - db_get $table, undef, $name, $id, 0; + db_get $table, undef, $name => $id, 0; $! or return $cb->($id); - for (1..100) { - my $txn = $DB_ENV->txn_begin; - db_get $table, $txn, id => $id, 0; - - $id = 64 if $id < 64; - - ++$id; - - db_put $table, $txn, id => $id, 0; - db_txn_finish $txn; + unless ($TILE_SEQ) { + $TILE_SEQ = $table->sequence; + $TILE_SEQ->initial_value (64); + $TILE_SEQ->set_cachesize (0); + db_sequence_open $TILE_SEQ, undef, "id", BDB::CREATE; + } - unless ($!) { - db_put $table, undef, $name => $id; - $SYNC->again unless $SYNC->is_active; - return $cb->($id); - } + db_sequence_get $TILE_SEQ, undef, 1, my $id; - select undef, undef, undef, 0.01 * rand; - } + die "unable to allocate tile id: $!" + if $!; + + db_put $table, undef, $name => $id, 0; + $cb->($id); - die "maximum number of transaction retries reached - database problems?"; } sub get_tile_id_sync($) { @@ -405,10 +403,15 @@ package DC::DB; +sub nuke_db { + File::Path::mkpath [$DB_HOME]; + eval { File::Path::rmtree $DB_HOME }; +} + sub open_db { unless (eval { try_open_db }) { warn "$@";#d# - eval { File::Path::rmtree $DB_HOME }; + eval { nuke_db }; try_open_db; } @@ -427,13 +430,13 @@ $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 { + undef $TILE_SEQ; %DB_TABLE = (); undef $DB_ENV; }