UNIT DB;

(* unit for a simple key-value db *)

(* Copyright (C) 1999,2000 Jim Hall <jhall1@isd.net>
   Translated to Pascal: Aitor Santamar¡a <aitor.sm@terra.es> *)

(*
  This unit is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This unit is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this unit; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)

INTERFACE

(* Symbolic constants *)

CONST
     HASHSIZE=101;

(* Types *)

TYPE
    Pdb_t = ^db_t;
    db_list = RECORD
                    next : Pdb_t;
                    key  : string;
                    value: string;
              END;
    db_t = db_list;

(* Functions *)

FUNCTION db_Insert (key: string; value: string): Pdb_t;
FUNCTION db_fetch   (s: string): Pdb_t;



IMPLEMENTATION

(* Global variables *)

VAR
    hashtab : ARRAY [1..HASHSIZE] OF Pdb_t;


(* Functions *)

(* hash - My hash function.  This is a little simple, but it will
   suffice. *)

FUNCTION hash (s: string): WORD;
VAR
    hashval : WORD;
    I       : BYTE;
BEGIN
     hashval := 0;
     FOR I:=1 TO Length(S) DO
           hashval := ord(s[i]) + 31 * hashval;
     hash := hashval MOD hashsize;
END;



(* db_fetch() - Query the hash and return a struct that contains the
   key and the pointer.  The calling function should not look beyond
   that. *)
FUNCTION db_fetch   (s: string): Pdb_t;
VAR
   db_ptr : Pdb_t;
BEGIN
     db_ptr := hashtab[hash(s)];
     WHILE Assigned (db_ptr) AND (s <> db_ptr^.key) DO
        db_ptr := db_ptr^.Next;
     db_fetch := db_ptr;
END;


(* db_insert() - Inserts a key,value pair into the hash.  If the key
   already exists in the hash, the new value is NOT inserted. *)


FUNCTION db_Insert (key: string; value: string): Pdb_t;
VAR
   db_ptr  : Pdb_t;
   hashval : word;
BEGIN
 db_ptr := NIL;
 IF (key<>'') AND (value<>'') AND (MaxAvail >= SizeOf(db_list)) THEN
   BEGIN
     db_ptr := db_fetch (key);
     IF NOT Assigned (db_ptr) THEN
       BEGIN
           (*  not found  *)
           New (db_ptr);
           db_ptr^.key := key;
           (* insert the key,value into the hash. *)
           hashval := hash(key);
           db_ptr^.next := hashtab[hashval];
           hashtab[hashval] := db_ptr;
       END;
     (* If already there, old value will be overwritten *)
     db_ptr^.value := value;
   END;
   db_insert := db_ptr;
END;


BEGIN
END.
