UNIFILE
by David Lawrence
from Your Computer, April 1983, pages 66-67

If your aim is world domination or merely a more organised social life,
David Lawrence's versatile program will put your ideas in order.


ONE OF THE dreams that accompanies most micros into the home is the vision
of massive information storage. Within weeks, every recipe will be stored,
every cheque and bill recorded, phone numbers available at the mere touch
of a button. Even if the dream does not turn into a nightmare, it usually
fades for two reasons: first, for a great many purposes, the amount of
benefit to be gained from putting information on to a micro simply does not
justify the amount of work needed to program it in or to retrieve it; and
secondly, large masses of information have a nasty habit of resisting all
attempts to process them or present them in an orderly fashion - it is all
very well storing the whole of the telephone directory on your micro but
how do you actually persuade the thing to tell you what you want to know?
        The program accompanying this article is directed at 16K ZX-81
owners who have decided that thev do want to use their machines for
information storage and retrieval but have run up against problems in
practice. The system is called Unifile and it is, basically, an empty
filing cabinet waiting to be filled with information which it will arrange
according to instructions laid down by the user and, equally important,
retrieve and display information or amend it.
        The Unifile program stores its data in a single string which can be
as long as the memory of your expanded ZX-81 will allow. This is not the
simplest method of storage by any means. Imagine, for instance, a file
consisting only of 100 names. By far the simplest way to store them on a
ZX-81 would be to use a string array - each name would be in a clearly
definable place and to gain access to any name you would have only to
specify its number in the array, a fast and uncomplicated technique.
        The real problem is one of space. It is unlikely that you will have
many names with 20 characters in them, but if your filing system is not to
break down the first time you come across such a name, your array must
allow for at least 20 charactes - a 100 by 20 array. The result is that
every time you enter "Smith,JH" you have wasted an enormous amount of
space in your memory because even with the punctuation you only needed 10
characters of the 20 you have set aside in the array.
        If all you have to worry about is one hundred, or even two or three
hundred names, then do put them into an array. But what if you wish to add
details to the names, so that for each name entered into the file there may
be five or six other items of information, all of which will require a
space allocation in the array. Space enough in the memory for three hundred
names now becomes space enough for only 50 names with their attendant
details, assuming that you allow a possible 20 characters for each item of
information.
        It is for this reason that most computer filing systems use a
storage method which allocates to each item of information only as much
space as it actually needs and on the ZX-81 the only way to achieve this
end is to pack each item into a string. The technique raises its own
problems, as the following example will illustrate.

	Name: Smith
	C/name: John
	Address: 12 North St
	Town: Anytown
	Phone: 0998-11111
	Age: 35
	Interests: Ferret washing
This is a typical entry from an imaginary file and is fairly self-explanatory.
Packed into a string, however, it becomes slightly less clear:
	SMITHJOHN12 NORTH STANYTOWN0998-1111135FERRET WASHING
It may still be decipherable to the human eye, but how is a program
searching a string made up of many such entries, packed together, to know
where one item begins and another ends. It would be much clearer if we
marked each item, at the cost of very little extra space:
	+SMITH*JOHN*12 NORTH ST*ANYTOWN*0998-11111*35*FERRET WASHING+
We can now instruct our program, when it searches for a particular item, to
recognise a plus sign as the beginning of an entry and an asterisk as
marking individual items within that entry. Unfortunately such separator
symbols can only be recognised if the string of information is examined
character by character, which is fine when you are dealing with only a few
entries but a little on the slow side if your file has grown to around
10,000 characters.
        Some method is needed which allows the program to identify the
beginning and end of an entry without examining every character in the
file. The Unifile program achieves this by attaching to each entry a
special indicator called a "string length indicator", or SLI.
        In the case of a small system such as Unifile, the SLI does not
need to be able to cope with huge entries and it is, in fact, one character
whose Code value is the length of the whole entry. This limits the length
of each entry to 255 characters, or approximately five times as much
information as was stored in our specimen entry, which has been found in
practice to be adequate.
        While the Unifile program cannot jump to the middle of its stored
data and unerringly identify the beginning of an entry, using the SLIs it
can quickly scan along its files, jumping from one entry to the next at an
acceptable speed. A typical Unifile entry would be structured as follows:

a) an SLI recording the length of the whole entry
b) an SLI recording the length of item 1
c) item 1
d) an SLI recording the length of item 2
e) item 2 fl an SLI for the next entry
   etc.

The Unifile program provides five facilities necessary to operating a
useful storage and retrieval system: file structuring, information entry,
amendment, search and display. First of all, file structuring. In the
specimen entry given above, seven items of information were recorded about
John Smith. The Unifile system allows any number of named items to be
specified and any information retrieved later will be reproduced under the
specified headings. The only limitation here is that the whole entry must
not exceed 255 characters.
        As to entry of information, once the types of information to be
recorded in each entry have been specified, the program requests entries on
the basis of the structure the user has laid down. Entries will be stored
in alphabetical order of the first item.
        Using the amendment function, individual items can be changed or
whole entries deleted.
        Two types of search function are provided. For the purposes of a
normal search the user specifies an item to be searched for and the program
compares this with each item contained in its files. However, only whole
items are compared - a normal search would only come up with John Smith if
the address being searched for were "12 North Street", it would pass over
the entry if the specificd address were simply North Street.
        Special search, on the other hand, will identify every occurrence
of a specified combination of characters such as North Street, or even
"Nor". Special search is particularly useful for files which do not follow
an orderly structure, such as recipes, where it may not be possible to
predict precisely how many items of information will be needed and two or
more end up being lumped together under the same heading. The disadvantage
of special search is that it is considerably slower than normal search. For
either form of search, when the specified item is discovered, the whole of
the entry containing it is displayed.
        The display function displays entries one at a time on command. All
the program's functions are called simply from a menu section which is
displayed on entry to the program and at relevant points during its use.
        The beauty of the Unifile idea is that, once entered on to your
ZX-81 and recorded on to a cassette, its uses are endless. A single user
can, at one and the same time, be using one version to store his personal
address book, with only two or three items per entry, while another version
stores vastly more complex club records or business data.
        The one major drawback of the program as listed is that it still
does not use the memory space available as effciently as possible - in fact
it uses only half the space the ZX-81 would allow. The reason for this is
that we have referred to our data storage string on both sides of a string
equation, as in line 730. Upon encountering this instruction the ZX81
promptly sets up a copy of B$ in order that it may maintain a distinction
between the new BS that it is being asked to create and the old BS it is
being asked to use as material. This problem can only be avoided by fixing
the length of BS in the memory of the ZX-81 and working within that fixed
length.
        The method of doing this, outlined in the supplementary program
notes, requires more program lines and is slightly slower in execution.
This is because, instead of the economy of line 730, we have now to move B$
in blocks whenever we wish to insert or remove data from the file. This
version of the program should only be used, therefore, if you are likely to
exceed 4K characters in your intended file. In order to use the second
version, B$ must be dimensioned when the file is about to be set up. The
maximum length is between 9000 and 9500 characters and to set up a new file
simply enter DIM B$(9000) in direct mode, followed by GOTO 1. Other than
that there is no difference in operation.

396   Size is the variable used to store the number of characters so far
      recorded in B$.
632   These extra lines check to see whether B$, which is now of fixed length,
      will be overfilled by the current entry.
730   These two GOSUBs replace the sections which added data or subtracted it
      from B$.
1170  We cannot now use the length of B$ as an indicator that the end of
      the data has been passed in a search, since no matter how little data is
      recorded, the length of B$ is static.
1256  This line and 1320 use the spurious entry, inserted into the file
      when it was first set up, in order to detect the end of the file.
1880  This section (down to 1930) uses an intermediate string (S$) to
      move blocks of B$ up the string, in order to make room for more data.
      Since B$ does not appear on both sides of a string equation any longer,
      it is not duplicated in the memory. Slightly more memory can be made
      available for storage by reducing the value of SHIFT in line 1880 and
      1950, though this slows down the program.
1940  This section telescopes the file when an entry is removed and is
      simply the opposite of the previous section.

