Swapping rooms to disk

From: George (greerga@CIRCLEMUD.ORG)
Date: 07/03/98


Here's an ugly 10 minute hack to keep room descriptions on disk instead of
in memory.  This is unique from previous attempts in that it doesn't load
the descriptions from disk if not used, they are _always_ on disk.

It saves 512 KB on a stock CircleMUD world but creates a 3 MB world binary
file on disk.  I've already thought of a better way to do this so don't
tell me it's inefficent, I know and would never use this version
personally. :)

Mostly posted as a proof of concept type thing.  I originally had it
keeping the world file open, but decided that the OS might mmap() the file
and thus use memory even after we don't want it.  Think of this as a
paranoid memory saving thing.

NOTE: A change was not made to act.wizard.c for do_stat_room which would be
required if using this.

Anyway...let's see what ideas other people have...

diff -uprN stk/Makefile wldswp/Makefile
--- stk/Makefile        Fri Jul  3 20:50:22 1998
+++ wldswp/Makefile     Fri Jul  3 21:34:33 1998
@@ -29,14 +29,14 @@ OBJFILES = comm.o act.comm.o act.informa
        castle.o class.o config.o constants.o db.o fight.o graph.o handler.o \
        house.o interpreter.o limits.o magic.o mail.o mobact.o modify.o \
        objsave.o olc.o random.o shop.o spec_assign.o spec_procs.o \
-       spell_parser.o spells.o utils.o weather.o
+       spell_parser.o spells.o utils.o weather.o world.o

 CXREF_FILES = act.comm.c act.informative.c act.item.c act.movement.c \
        act.offensive.c act.other.c act.social.c act.wizard.c ban.c boards.c \
        castle.c class.c comm.c config.c constants.c db.c fight.c graph.c \
        handler.c house.c interpreter.c limits.c magic.c mail.c mobact.c \
        modify.c objsave.c olc.c random.c shop.c spec_assign.c spec_procs.c \
-       spell_parser.c spells.c utils.c weather.c
+       spell_parser.c spells.c utils.c weather.c world.c

 default: all

diff -uprN stk/act.informative.c wldswp/act.informative.c
--- stk/act.informative.c       Thu Jun 25 01:16:56 1998
+++ wldswp/act.informative.c    Fri Jul  3 21:38:03 1998
@@ -424,7 +424,7 @@ void look_at_room(struct char_data * ch,

   if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
       ROOM_FLAGGED(ch->in_room, ROOM_DEATH))
-    send_to_char(world[ch->in_room].description, ch);
+    send_to_char(get_room_desc(ch->in_room), ch);

   /* autoexits */
   if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
diff -uprN stk/db.c wldswp/db.c
--- stk/db.c    Thu Jun 25 00:44:38 1998
+++ wldswp/db.c Fri Jul  3 21:33:08 1998
@@ -125,6 +125,7 @@ void weather_and_time(int mode);
 void mag_assign_spells(void);
 void boot_social_messages(void);
 void update_obj_file(void);    /* In objsave.c */
+void write_world(void);
 void sort_commands(void);
 void sort_spells(void);
 void load_banned(void);
@@ -271,6 +272,8 @@ void boot_db(void)


   boot_world();
+
+  write_world();

   log("Loading help entries.");
   index_boot(DB_BOOT_HLP);
diff -uprN stk/db.h wldswp/db.h
--- stk/db.h    Sat Jun 13 13:51:20 1998
+++ wldswp/db.h Fri Jul  3 21:37:16 1998
@@ -112,6 +112,7 @@ void        clear_char(struct char_data *ch);
 void   reset_char(struct char_data *ch);
 void   free_char(struct char_data *ch);

+const char *get_room_desc(room_rnum rnum);
 struct obj_data *create_obj(void);
 void   clear_object(struct obj_data *obj);
 void   free_obj(struct obj_data *obj);
diff -uprN stk/world.c wldswp/world.c
--- stk/world.c Wed Dec 31 19:00:00 1969
+++ wldswp/world.c      Fri Jul  3 21:51:47 1998
@@ -0,0 +1,67 @@
+#include "conf.h"
+#include "sysdep.h"
+#include "structs.h"
+#include "utils.h"
+#include "db.h"
+
+extern int top_of_world;
+extern struct room_data *world;
+
+#define MAX_ROOM_DESC  1536
+
+struct world_file {
+  char description[MAX_ROOM_DESC];
+};
+
+struct world_file wfg;
+
+FILE *world_f = NULL;
+
+void get_room(room_rnum rnum, struct world_file *wf)
+{
+  if (rnum < 0 || rnum > top_of_world)
+    return;
+
+  if ((world_f = fopen("world.bin", "r")) == NULL) {
+    log("SYSERR: Unable to open world binary file.");
+    exit(1);
+  }
+  fseek(world_f, sizeof(struct world_file) * rnum, SEEK_SET);
+  fread(&wfg, sizeof(struct world_file), 1, world_f);
+  fclose(world_f);
+}
+
+const char *get_room_desc(room_rnum rnum)
+{
+  get_room(rnum, &wfg);
+  return wfg.description;
+}
+
+void write_world(void)
+{
+  FILE *f;
+  int i, maxsize = 0, tmpsize;
+  struct world_file wfw;
+
+  if ((f = fopen("world.bin", "w")) == NULL) {
+    log("SYSERR: Error writing 'world.bin'.");
+    abort();
+  }
+
+  for (i = 0; i <= top_of_world; i++) {
+    if ((tmpsize = strlen(world[i].description)) >= MAX_ROOM_DESC) {
+      log("SYSERR: Room #%d description longer than %d characters.", i, MAX_ROOM_DESC);
+      abort();
+    }
+    strcpy(wfw.description, world[i].description);
+    free(world[i].description);
+    world[i].description = NULL;
+
+    if (tmpsize > maxsize)
+      maxsize = tmpsize;
+    fwrite(&wfw, sizeof(struct world_file), 1, f);
+  }
+
+  fclose(f);
+  log("Longest room description: %d", maxsize);
+}

--
George Greer, greerga@circlemud.org | Genius may have its limitations, but
http://patches.van.ml.org/          | stupidity is not thus handicapped.
http://www.van.ml.org/CircleMUD/    |                  -- Elbert Hubbard


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST