Commit graph

622 commits

Author SHA1 Message Date
4e23c45e61 Make xundump check each partial table supplies the same rows
Also streamline the error message for missing rows at end of table.
2011-06-25 16:51:44 +02:00
4c731905cf Make xundump reject out-of-order rows
This also catches duplicate rows.  Will make blanking out gaps easier.
2011-06-25 16:51:44 +02:00
cff42775ac Permit truncating table product
Truncating is actually fine for table product.  It's forbidden because
selector sname has flag NSC_CONST set.  I don't remember why sname was
made const in commit 445dfec9 along with item selector mnem, sect-chr
selector mnem and infrastructure selector name.  Unlike the other
tables, no code depends on product's builtin values.  Clear the flag.
2011-06-25 16:51:35 +02:00
3a3b9409b2 Clean up xundump's test whether table may be truncated
A table may be truncated when its size is variable and it doesn't have
const fields.  The old code tested table IDs instead.
2011-06-25 16:50:41 +02:00
63f972d31c Overhaul how xundump keeps track of current object
Factor tracking of cur_type, cur_obj, cur_id and cur_is_blank into a
set of functions.  They replace getobj().  While there, improve some
error messages.
2011-06-25 16:50:41 +02:00
465c0c8587 Move src/lib/subs/empobj.c back to src/lib/common/
Commit 77e95bd7 (v4.3.12) moved it from its natural home because
obj_nameof() required stuff from subs/.  Now that obj_nameof() is
gone, move it back.
2011-06-25 16:50:20 +02:00
79f289c365 Refuse to grow or truncate files with fixed size
Make ef_write() treat it like any other invalid write beyond the file
size: oops.  Be less harsh in ef_extend() and ef_truncate(): log an
error.
2011-06-25 16:50:20 +02:00
7d2269b5ae Make ef_open() extend files with fixed size automatically
Turns the fixed size into an invariant.  Before, the files utility
created them empty, then extended them.
2011-06-25 16:50:06 +02:00
31b9ff08f3 Move pln_oninit(), lnd_oninit(), nuk_oninit() to filetable.c
They set up invariants, and thus should be always active, not just in
the server.  Since ef_blank() isn't used for these files outside the
server right now, this isn't a bug fix, just cleanup.
2011-06-25 16:50:06 +02:00
3fe3cd376f Move file initialization from files.c to empfile oninit()
files.c writes initial contents to game state files with fixed size.
Necessary for setting up invariants, such as struct sctstr members
sct_x, sct_y matching sct_uid.

Do that from the oninit() callback, so ef_blank() sets up invariants
correctly.  Since ef_blank() isn't used for these files right now,
this isn't a bug fix, just cleanup.
2011-06-25 16:50:06 +02:00
576a3c60ed Initialize empfile user callbacks explicitly
Instead of stuffing NULL initializers into the cache initializer
macros UNMAPPED_CACHE(), ARRAY_CACHE(), PTR_CACHE(), ARRAY_TABLE().
In preparation of having some non-NULL initializers.
2011-06-25 16:50:06 +02:00
58ed1d1b9e Fix empdump not to grow game state files with fixed size
empdump -i now complains about extra rows instead of silently growing
the file to a size the server will reject.  Affects tables sector,
nation, realms, game.

Bonus fix: better error message on I/O error or insufficient memory.
2011-06-25 16:50:06 +02:00
73bd5d6aa3 Fix empdump not to truncate game state files with fixed size
empdump -i now complains about missing rows instead of silently
truncating the file to a size the server will reject.  Affects tables
sector, nation, realms, game.
2011-06-25 16:50:06 +02:00
0fcd935999 Clean up how game state file sizes are checked
New struct empfile member nent replaces ef_open() parameter nelt.
Cleaner, because the expected size is a property of the file, not of
how it's used.  Also fixes empdump to check file sizes.

Complication: with EFF_CREATE, ef_open() creates an empty file, to be
extended to the correct size.  Callers passed nelt argument -1 along
with EFF_CREATE, to make ef_open() accept the empty file.  Can't do
the same for empfile member nent.  Instead, make ef_open() not check
the (zero) size then.

Replaces commit 5750107b, v4.3.15.
2011-06-25 16:50:06 +02:00
44f97c3297 Clean up how a view's base table is defined
New struct empfile member base replaces ef_open_view() parameter base.
Cleaner, because the base table is a property of the view, not of how
it's used.

Use it to clean up verify_fail()'s base table access, and for extra
sanity checks in ef_open() and ef_open_view().
2011-06-25 16:50:06 +02:00
2b0b53992f Simplify how ef_write() handles write beyond end of file 2011-06-25 16:50:06 +02:00
f50fc19aab Make ef_close() set fids later, so it's cleaned up on error
Just for cleanliness.
2011-06-25 16:50:06 +02:00
5d54e424df Clean up ef_close() to zap csize along with cache 2011-06-25 16:50:06 +02:00
a485084777 Change struct empfile callback onresize() to return void
ef_open() handles onresize() failing incorrectly.  Instead of fixing
that, drop the failure mode.  It's not really used: unit_onresize()
fails only when used incorrectly.  It isn't.  If it ever is, ignoring
the failure is safe.
2011-06-25 16:50:05 +02:00
45c7337e70 Fix clearing mutable flags on ef_close()
Make ef_close() clear them always, even for views.  Harmless, as
ef_open_view() always sets the same flags.

Drop redundant assignment to ep->flags in ef_open().  ef_close()
clears mutable flags, no need to clear them some more right before
calling it.  Missed in commit 3eb3607f, v4.3.0.
2011-06-25 16:50:05 +02:00
5703bdd61c Fix ef_open()'s error message for file larger than static cache
The message claims the file is larger than it actually is.  Broken
since commit 71908018 (v4.3.0) implemented static cache in ef_open().
Harmless, because no file-backed table has a statically allocated
cache.
2011-06-25 16:50:05 +02:00
bd453cd821 Fix how empdump rejects attempt to split table sect
Split tables require the record index in the leftmost column.
defellipsis() correctly rejects "..." when the table doesn't have one.
It fails to reject it when it has one that is NSC_EXTRA, and thus not
permitted in a dump.  This is the case for table sect.  defellipsis()
happily succeeds, then chkflds() demands column "uid" if it's missing,
and rejects it if its present.
2011-06-25 16:50:05 +02:00
b40741dc5f empdump failed to catch some invalid column names
It missed those with more flags than just NSC_EXTRA set: table sect
name uid, table nat names passwd, xorg, yorg, contacts, rejects.
Since xundump() doesn't provide space for these, the bug could lead to
buffer overruns.  Fixes flawed commit 726a8e3d, v4.3.12.
2011-06-25 16:50:05 +02:00
7e95b52bce Fix empdump to check for truncation failure
xubody() neglected to check ef_truncate()'s return value.  Two failure
modes: invalid arguments, and ftruncate() failure.  The former
shouldn't happen, and the latter can happen only for file-backed
tables, hence only in empdump -i.
2011-06-25 16:49:58 +02:00
5cedc533f8 Make xundump report invalid record IDs
It failed silently before.
2011-06-25 16:49:57 +02:00
50070a8f9a Make xundump reject numbers that don't fit into integral field
Numbers are read into a double, then cast to the field type.  The cast
may change the value.  Flag that as error, except for floating-point
fields.
2011-06-25 16:49:57 +02:00
029d929b1b Restrict xundump to tables with a file name
Tables with a file name are: any game state, and any table that's
initialized from a .config file.

Tables that are no longer customizable: "updates" (customization had
no effect, because update_get_schedule() overwrote it), "table",
"meta" and the symbol tables (customization couldn't change them
anyway), and news-chr (customizing r_newsstory[] was kind of neat, but
unsafe because they are format strings for sprintf()).
2011-06-25 16:47:57 +02:00
573d3fe870 Fix xdump updates not to dump bogus extra updates
"xdump updates" believes there are always 15 (UPDATE_TIME_LEN - 1)
scheduled updates.  When fewer than 15 updates are scheduled, it shows
whatever crap update time happens to be in the unused part of
update_time[]: the initial zero or a previously scheduled update.

Root cause is that table EF_UPDATES has always UPDATE_TIME_LEN - 1
entries, which is incorrect when fewer updates are scheduled.  Only
xdump is affected, as the other users ignore the length and stop at
the sentinel.

Fix update_get_schedule() to resize table EF_UPDATES.
2011-06-25 16:45:31 +02:00
5b9d31a4b3 Check record uid comes first in split config tables
setnum() requires the record uid to come first, so we better ensure it
does.
2011-06-25 16:45:31 +02:00
cb3e35cb3a Don't stop checking xdump field headers when join field is missing
Also improve the error message a bit.
2011-06-25 16:45:31 +02:00
6e4772b175 A few comment fixes for nsc.[ch] file.[ch] 2011-06-25 16:45:31 +02:00
221268e0e1 Provide proper ca_table for carrier unit# selectors
Makes ef_verify() check carrier UIDs are sane.  Partially protects
unit_cargo_init(), which oopses on bad carriers.

This has become possible only since commit 64a53c90 (v4.3.17) set
their values to -1 in newly created units.  Before, they were zero in
units that had never been used, and a proper ca_table would have made
ef_verify() fail when unit#0 didn't exist.

The only unit# selectors left without a proper ca_table are ship's
follow, lost's id and trade's unitid.  Document why.
2011-06-25 16:44:04 +02:00
b461cd3ae7 Provide proper ca_table for meta selector table
No idea why it was missing.
2011-06-25 16:44:04 +02:00
97f475b6c1 Oops in verify_row() when non-integral selector references a table 2011-06-06 19:24:13 +02:00
e1caa11733 Don't ignore non-virtual NSC_EXTRA columns in ef_verify.c
These are commonly timestamps (no verification implemented), or
aliases for a non-extra column (which gets verified).  Commit 49780e2c
(v4.3.12) added the exception: EF_SECTOR's uid.  Proof by example that
ignoring these columns is wrong.  Fix: ignore only virtual columns.
2011-06-06 19:24:13 +02:00
05fc6523d5 Clean up write-only variable in path_find_to() 2011-04-14 21:20:09 +02:00
98cd2a3a70 Update known contributors comments 2011-04-14 20:21:23 +02:00
47b68a1c1f Document sequence numbers and generation numbers better 2011-04-14 20:21:23 +02:00
af5e25aa16 Move xdmeta() back to commands/xdump.c, internal linkage
Partially revert commit 4c746b5e.
2011-04-14 20:21:21 +02:00
40b6032a5d Move xysize_range(), xydist_range() to xy.c and xy.h
Moved from snxtsct.c and prototypes.h next to the other struct range
functions.
2011-04-14 20:21:21 +02:00
157ae8ec21 Clean up superfluous include of nsc.h in prototypes.h 2011-04-14 19:46:05 +02:00
a2386edc01 Clean up superfluous include of news.h in empobj.h
Missed in commit 0ba61f17, v4.3.24.
2011-04-14 19:46:05 +02:00
e450c31ddb Inline BestShipPath(), BestAirPath() glue
Following commits will simplify the resulting code.
2011-04-12 21:51:32 +02:00
92e64d7638 Inline BestLandPath(), BestDistPath() glue
Following commits will simplify the resulting code.
2011-04-12 21:51:32 +02:00
04363a92db Use the new path finder for sea & air, drop bestownedpath()
bestownedpath() is a rather simple-minded breadth-first search.  It's
slower than the new path finder, and maintaining it in addition to the
new path finder makes no sense.
2011-04-12 21:51:31 +02:00
2fc9dfc526 New path_find_visualize(), to aid debugging 2011-04-12 21:51:31 +02:00
18dd516076 Add performance statistics to path finder
New function path_find_print_stats() prints a few numbers of interest
when compiled with PATH_FIND_STATS defined.
2011-04-12 21:51:31 +02:00
d7dccef3b1 Optimize Dijkstra's inner loop for hex maps
Because the cost to enter a sector is independent of the direction of
entry, we visit sectors at most once.  Exploit that.

Beware: this is not the case for A*.  Pitfall for any future
generalization to A*.

Speeds up distribution path assembly by 35-40% in my tests.
2011-04-12 21:51:31 +02:00
ffbbfcb25f Use the new path finder for land paths, drop old A*
This gets rid of the memory leak mentioned in the previous commit.

To get rid of the buffer overruns for long paths mentioned in the
previous commit, make BestLandPath() fail when path length exceeds
1023 characters.

assemble_dist_paths() and move_ground() pass buffers with a different
size.  Eliminate assemble_dist_paths()'s buffer.  Update now works
regardless of distribution distance (the distribute command still
limits to 1023, to be fixed in a later commit).  Enlarge
move_ground()'s buffers.  Doubles the length of paths accepted by
explore, move, and transport.

I use two test cases to benchmark the path finders: "continental" (Hvy
Metal 2 updates) and "island" (Hvy Plastic 2 updates).

The new path finder runs my tests around 3-4 times faster than the old
A* without its caches.  That's enough to meet its cached performance
for "island", but it's only half as fast for "continental".  Not for
long; big speedups are coming.
2011-04-12 21:48:58 +02:00
90de24d038 New path finder
We've been using Phil Lapsley's A* library to find land paths since
Chainsaw 3.  It's reasonably general, and uses relatively complex data
structures to conserve memory.  Unfortunately, it occasionally leaks a
bit of memory (see commit 86a187c0), and is unsafe for long paths (see
commit e30dc417).

To speed it up, v4.2.2 added two caches: the neighbor cache and the
path cache.

The neighbor cache attempts to speed up lookup of adjacent sectors.
It allocates 6 pointers per sector for that.  In my tests, this is
more, sometimes much more memory than the A* library uses.  See commit
7edcd3ea on branch old-astar for its (modest) performance impact.

The path cache attempts to speed up the update's computation of
distribution path costs.  There, A* runs many times.  Each run finds
many shortest paths, of which only the one asked for is returned.  The
path cache saves all of them, so that when one of them is needed
later, we can get it from the path cache instead of running A* again.
The cache is quite effective, but a bit of a memory hog (see commit
a02d3e9f on branch old-astar).

I'm pretty sure I could speed up the path cache even more by reducing
its excessive memory consumption --- why store paths when we're only
interested in cost?  But that's a bad idea, because the path cache
itself is a bad idea.

Finding many shortest paths from the same source has a well-known
efficient and simple solution: Dijkstra's algorithm[*].

A* is an extension of Dijkstra's algorithm.  It computes a *single*
path faster than Dijkstra's.  But it can't compute *many* shortest
paths from the same source as efficiently as Dijkstra's.

I could try to modify Phil's code to make it compute many shortest
paths from the same source efficiently: turn A* into its special case
Dijkstra's algorithm (at least for distribution path assembly), then
generalize it to the many paths problem.  Of course, I'd also have to
track down its memory allocation bugs, and make it safe for long
paths.

Instead, I'm replacing it.  This commit is the first step: a rather
unsophisticated implementation of Dijkstra's algorithm specialized to
hex maps.  It works with simple data structures: an array for the hex
map (16 bytes per sector), and a binary heap for the priority queue
(16 bytes per sector, most of it never touched).  This is more memory
than Phil's A* uses, but much less than Phil's A* with v4.2.2's
caches.

[*] To fully exploit Dijkstra's "many paths" capability, we need to
compute distribution paths in distribution center order.
2011-04-12 21:44:22 +02:00