Random.e
Random Access Library
Version 2.0
March 31 1999
Derek Brown (tidefball@aol.com)


  This library enables you to use random access in Euphoria.  There are two formats, ASCII and binary.  Each one is better than the other at storing different types of data (will be explained further down), but the syntax is the same.  Also, it is possible to create a datafile that has records stored in each format.
  DISCLAIMER:  I'm not responsible for any damage, period.  Anything else you'd expect to see in a disclaimer goes here too.


Thanks
======

Rob Craig for Euphoria
Gabriel Boehme for his binary bprint() and bget() routines

Features
========

1.  Records of varying length.
2.  Multiple level sequence support.
3.  Optimized for speed.
4.  Extremely stable and reliable.  Tested thoroughly.
5.  Quantity() function that returns the number of records in database.
6.  Very easy to use.
7.  Safe overwriting of records.  No data corruption.
8.  ASCII and binary storage.


What is random access?
======================

  Random access is a kind of misnomer because actually it lets you access the precise piece of data you're looking for.  Data is stored in a datafile as records.  The records are numbered.  You can retrieve data by it's record number.  This library lets you create records of varying length.  This library can also handle sequences of multiple levels.


How it works
============

  This works by the program creaing "track marks" to signify the beginning of a new record.  The symbol for the track mark is '!'.  When loading records, the program must first make a map of the tracks.  This is done extremely fast.
  There are three ways to enter data.  Output() writes data directly, either to the beginning (if you open the file in update mode) or end (if you append).  Replace() overwrites a record with a new record.  This new record must be the same length.  Over_write() overwrites a record with a new record of different length.
  To retrieve data, input() is used.
  The two above paragraphs dealt with ASCII mode.  For binary mode, the only difference is the "b_" at the beginning...  the binary version of output() is b_output().


Commands
========

1. output() 
      output data
      syntax:  output(atom fn, object record)

2. input()
      load data into a variable
      syntax: sequence record = input(atom fn, atom rec_num)

3. replace()
      overwrite a record of same length
      syntax:  replace(atom fn, atom rec#, object record)
      You must be in "update mode".
      Slightly faster than over_write(), more so in large databases.

4. over_write()
      overwrite a record of different length
      syntax:  over_write(atom fn, atom rec#, object record)
      You must be in "update mode".
      
5. quantity()
      determines the number of records
      syntax: atom quan = quantity(atom fn)


The first 4 commands above have binary versions:
 output()     - b_output()
 input()      - b_input()
 replace()    - b_replace()
 over_write() - b_over_write()

Examples
========

include random.e

integer fn, how_many
sequence test1, test2, load

test1 = {1,2,3,4,5,{6,7,8}}
test2 = {"Euphoria"}

--Outputting data:
fn = open("file","w")
  output(fn,test1) --Make test1 the first record
  output(fn,test2) --And test2 the second (binary)
close(fn)

--Retrieving data:
fn = open("file","r")
  load = input(fn,1)   --load is now {1,2,3,4,5{6,7,8}}
  load = input(fn,2)   --load is now {"Euphoria"}
close(fn)

--Overwriting data:
fn = open("file","u")
  over_write(fn,1,test2) --Now both entries are {"Euphoria"}
close(fn)

--Appending data / adding new records:
fn = open("file","a")
  output(fn,test2)      --Just a reminder to use append mode, otherwise it will ruin your
close(fn)               --datafile

--Determining quantity:
fn = open("file","u")
  how_many = quantity(fn)
close(fn)


ASCII or Binary?
================

  ASCII is more efficient at storing atoms and sequences with floating point numbers.  Binary handles integers better.  There is a comparison in the demo program.  The sequence {5.5,6.5,7.5} would be much shorter in ASCII mode (about half the size).  On the other hand, {5,6,7} would be much smaller in the binary format.


Over_write() or Replace()?
==========================

  Over_write() is preferred because it is safer.  If the database is less than 100K in size, then both commands will be very close in speed.  However, if you're running a huge database with identical records, go with replace() because in datafiles upward of 100K in size, replace() is at least twice as fast.


Information
===========

  There is a minor bug when over_write()ing records.  If the new record is smaller than the original record, it will leave garbage at the end.  This happens b/c when you write to a record, if there are records after that it saves them, then writes your record, then rewrites the saved records.  So if your record is shorter than the old one, it will cause the records after that to be shifted to the left of their original position.  However, this garbage is not counted as a record, so it does not affect your data in any way.  Even after you append records to the end, it is still skipped.  All it does is sit in between two records and take up a few bytes of disk space.  This is an inconvinience I am going to try to fix, however, if it means losing speed, I will not deal with it.
  This routine should be very reliable and should never crash.  However, if it does crash, please tell me ASAP.  That way I can fix the problem.  If you have some spare time, fool around and try to make it crash.


Derek Brown
tidefball@aol.com