home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / browser / tools / javasearch / database.java next >
Text File  |  1995-08-11  |  10KB  |  319 lines

  1. /*
  2.  * @(#)Database.java    1.10 95/03/14 David A. Brown
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package browser.tools.JavaSearch;
  21. import java.io.*;
  22.  
  23. /**
  24.  * Database:  Class describing an JavaSearch database.
  25.  *
  26.  * See the detailed comment below for info on the filenames
  27.  * making up a database, and file formats.
  28.  *
  29.  */
  30. public class Database {
  31.  
  32.     /** Name of this database */
  33.     public String dbName;
  34.  
  35.     /** Pathname prefix for DOCUMENT files in this database.
  36.      *  An absolute document pathname is constructed by concatenating
  37.      *  docPathPrefix with the "filename" from a Doc object.
  38.      *
  39.      *  docPathPrefix may be an empty string but is never null.
  40.      */
  41.     public String docPathPrefix;
  42.  
  43.     /** URL prefix for documents in this database.
  44.      *  An absolute document URL is constructed by concatenating
  45.      *  docURLPrefix with the "url" from a Doc object.
  46.      *
  47.      *  If docURLPrefix is null, that means that Documents in
  48.      *  this database do not have meaningful URLs.
  49.      */
  50.     public String docURLPrefix;
  51.  
  52.     /**
  53.      * Human-readable string describing this database
  54.      */
  55.     public String description;
  56.     
  57.     // FUTURE:
  58.     //  - JavaSearch version info
  59.     //  - "Maintainer" of this DB
  60.     //  - Cost parameters
  61.     //  - List of most frequent words in the index
  62.     //  - Most common file type(s) in this index
  63.     //  - Date this db was (1) created, (2) last re-indexed
  64.  
  65.  
  66.     /** 
  67.      *  Filenames of the separate files making up this
  68.      *    JavaSearch database.  These files are the DB info file,
  69.      *    the index and docs files, and *their* indexes.
  70.      *    See the big comment at the end of this file.
  71.      *  These filenames are derived from dbName, and are filled
  72.      *  in by our constructor. */
  73.     public String dbinfoFilename;
  74.     public String indexFilename, qindexFilename;
  75.     public String docsFilename, docindexFilename;
  76.  
  77.     /**
  78.      *  Database constructor.  Specify the database name,
  79.      *  and we derive the index/docs filenames.
  80.      *
  81.      *  This constructor is private.  Use either
  82.      *  CreateNewDatabase() if you're creating an index,
  83.      *  or OpenDatabase() if you're about to search an already-existing
  84.      *  database.
  85.      */
  86.     private Database(String name) {
  87.         dbName = name;
  88.         dbinfoFilename = dbName + ".dbinfo";
  89.         indexFilename = dbName + ".index";
  90.         qindexFilename = dbName + ".qindex";
  91.         docsFilename = dbName + ".docs";
  92.         docindexFilename = dbName + ".docindex";
  93.     }
  94.  
  95.     //
  96.     // Static methods returning a new Database object.
  97.     // CreateNewDatabase() is used when indexing (to creating a new DB).
  98.     // OpenDatabase() if used to search an already-existing DB.
  99.     //
  100.  
  101.     /*
  102.      * Create a brand-new Database object
  103.      */
  104.     public static Database CreateNewDatabase(String name) {
  105.     System.out.println("Creating a new Database ["+name+"]...");
  106.     Database db = new Database(name);
  107.     System.out.println("  "+db);
  108.     return db;
  109.     }
  110.  
  111.     /*
  112.      * Construct an JavaSearch Database object by reading
  113.      * an already-existing Database from disk.
  114.      *
  115.      * Returns a Database object, with all the info from the
  116.      * ".dbinfo" file pre-loaded.
  117.      *
  118.      * Throws IOException if the database can't be opened.
  119.      */
  120.     public static Database OpenDatabase(String name) {
  121.     //System.out.println("Opening a Database from disk ["+name+"]...");
  122.     Database db = new Database(name);
  123.     db.readInfoFile();
  124.     //System.out.println("  "+db);
  125.     return db;
  126.     }
  127.  
  128.     // Couple of utility functions to get file sizes
  129.  
  130.     /** Return the size (in bytes) of this db's on-disk index. */
  131.     public int indexSize() {
  132.     int size = 0;
  133.  
  134.     RandomAccessFile f = new RandomAccessFile(indexFilename,"r");
  135.     size += f.length();
  136.     f.close();
  137.  
  138.     f = new RandomAccessFile(qindexFilename,"r");
  139.     size += f.length();
  140.     f.close();
  141.  
  142.     return size;
  143.     }
  144.  
  145.     /** Return the total size (in bytes) of this Database.
  146.      *  This includes the index/qindex files, *plus* the dbinfo
  147.      *  and docs files. */
  148.     public int totalDBSize() {
  149.  
  150.     int size = indexSize();
  151.  
  152.     RandomAccessFile f = new RandomAccessFile(dbinfoFilename,"r");
  153.         size += f.length();
  154.         f.close();
  155.  
  156.     f = new RandomAccessFile(docsFilename,"r");
  157.         size += f.length();
  158.         f.close();
  159.  
  160.         f = new RandomAccessFile(docindexFilename,"r");
  161.         size += f.length();
  162.         f.close();
  163.  
  164.         return size;
  165.     }
  166.  
  167.     /**
  168.      * Write this Database's .dbinfo file to disk.
  169.      */
  170.     public void saveInfoFile() {
  171.         System.out.println("Opening DB info file '" + dbinfoFilename + "'...");
  172.         FileOutputStream fileout = new FileOutputStream(dbinfoFilename);
  173.         DataOutputStream out = new DataOutputStream(fileout);
  174.  
  175.     out.writeBytes("JavaSearch Database info file\n");
  176.         out.writeBytes("dbName:" + dbName + "\n");
  177.         out.writeBytes("docPathPrefix:" + docPathPrefix + "\n");
  178.     if (docURLPrefix != null) {
  179.         out.writeBytes("docURLPrefix:" + docURLPrefix + "\n");
  180.     }
  181.     else {
  182.         out.writeBytes("docURLPrefix:\n");
  183.     }
  184.         out.writeBytes("description:" + description + "\n");
  185.  
  186.         fileout.close();
  187.     }
  188.  
  189.     /**
  190.      * Read this Database's .dbinfo file,
  191.      * and set docPathPrefix / docURLPrefix / description.
  192.      */
  193.     private void readInfoFile() {
  194.     String line;
  195.  
  196.         //System.out.println("Opening DB info file '" + dbinfoFilename + "'...");
  197.         FileInputStream filein = new FileInputStream(dbinfoFilename);
  198.         DataInputStream in = new DataInputStream(filein);
  199.  
  200.     // REMIND:  This is real quick & dirty.  Really
  201.     //    should be more flexible...
  202.  
  203.     line = in.readLine();        // Skip over header line
  204.     line = in.readLine();        // dbName
  205.     String tmpName = line.substring(line.indexOf(':')+1);
  206. /*
  207.     if (!tmpName.equals(dbName)) {
  208.         throw new Exception("Database.readInfoFile(): dbName from file ("+
  209.                 tmpName+") doesn't agree with dbname ("+
  210.                 dbName+")!");
  211.     }
  212. */
  213.  
  214.     line = in.readLine();
  215.     docPathPrefix = line.substring(line.indexOf(':')+1);
  216.  
  217.     line = in.readLine();
  218.     docURLPrefix = line.substring(line.indexOf(':')+1);
  219.     if (docURLPrefix.length() == 0) {
  220.         docURLPrefix = null;
  221.     }
  222.  
  223.     line = in.readLine();
  224.     description = line.substring(line.indexOf(':')+1);
  225.  
  226.         filein.close();
  227.     }
  228.  
  229.     /** Return a simple printed representation of this Database */
  230.     public String toString() {
  231.     return "Database '"+dbName+
  232.         "': docPathPrefix '"+docPathPrefix+
  233.         "'; docURLPrefix '"+docURLPrefix+
  234.         "'; description '"+description+"'.";
  235.     }
  236.  
  237. }
  238.  
  239.  
  240.  
  241.  
  242. /*
  243.  *      Files used by the JavaSearch toolkit
  244.  *
  245.  An JavaSearch DATABASE consists consists of 5 files on disk:
  246.  
  247.    (0) dbName.dbinfo    Human-readable discription of this database
  248.  
  249.    (1) dbName.index     Inverted word index
  250.    (2) dbName.qindex    List of 4-byte pointers into the .index file
  251.  
  252.    (3) dbName.docs      The source documents making up this database
  253.    (4) dbName.docindex  List of 4-byte pointers into the .docs file
  254.  
  255.  
  256.    The .dbinfo file is intended to be human-readable, and
  257.    contains info describing this database.  It's basically
  258.    the persistent form of a Database object.
  259.  
  260.  
  261.  
  262.    The .qindex and .docindex files are simply a list of integers,
  263.    which can be used as pointers into the .index and
  264.    .docs files respectively (to quickly find the Nth
  265.    word in the index, or the Nth document in the database).
  266.    These files must be used to do a quick lookup in the
  267.    index of docs file (since .index and .docs records are
  268.    variable-length!)
  269.      See Searcher.java for the binary search algorithm
  270.    which uses the .qindex and .index files.
  271.  
  272.    The .index file contains the following information:
  273.      - Header (see Index.indexFileHeader) followed by newline
  274.      - List of Word entries.
  275.  
  276.    Each Word entry corresponds to a Word object, and contains
  277.    the following:
  278.      - The word itself, as a string (of bytes) followed by newline
  279.      - A list of Doc IDs, written as chars, terminated by zero.
  280.  
  281.    The .docs file contains the following information:
  282.      - Header (see DocList.docsFileHeader) followed by newline
  283.      - List of Doc entries.
  284.  
  285.    Each Doc entry corresponds to a Doc object, and contains 
  286.    the following:
  287.      - The ID of this Doc, written as a single char.
  288.        (Note this is redundant, but here for sanity checking). 
  289.      - This Doc's filename, as a string (of bytes) followed by newline
  290.      - This Doc's headline, as a string (of bytes) followed by newline
  291.    See Doc.java for some FUTURE stuff which might eventually
  292.    be added to Doc entries.
  293.  
  294.    Random NOTES and future feature info:
  295.  
  296.    - There are several alternate ways to do a fast search
  297.      through the inverted index.  The current .index/.qindex
  298.      file arrangement is straightforward, and is as fast
  299.      as a binary search (with two seeks and reads at each
  300.      step of the search).   A couple of other possible methods
  301.      might involve
  302.        - Having an "index to the index" with pointers
  303.      at every Nth entry (with n=1000, maybe) in the index file.
  304.      Then, you do a 2-level binary search (which should perform
  305.      better since your reads are clustered better than the
  306.      simple binary search, which reads all over the file...)
  307.        - Having an "index to the index" with a bunch of
  308.          FIXED-LENGTH entries, like maybe the first 4 characters
  309.      of every word in the index (with duplicates removed).
  310.      So you binary-search this (relatively small) file
  311.      to get a pointer into the real file, and then you
  312.      search the real file *sequentially* till you find your word
  313.      or determine it's not in the index.
  314.      Also, see the file "DESIGN" in the WAIS docs for a (terse)
  315.      description of WAIS's indexing system.
  316.  
  317. */
  318.  
  319.