From: pow@ipsa@ipsaint.ipsa.reuter.COM (Remote Addressee:)
Newsgroups: comp.lang.apl
Subject: Keyed Files for J
Date: 20 Dec 92 17:46:58 GMT
Reply-To: pow@ipsa@ipsaint.ipsa.reuter.COM (Remote Addressee:)
Organization: Reuters Information Services (Canada)


-----------Message forwarded from IPSA Mailbox-------------


no. 6843765 filed 23.39.19  sat 19 dec 1992
from pow@ipsa
to   uclapl
subj Keyed Files for J

@transferred from ipsa  no. 5455051 filed 23.39.07  sat 19 dec 1992

Below is a script for some J verbs to store values in a file by key. I'd
be delighted to receive improvements and suggestions.
/Mike Powell
---------------------
NB. KEYED FILES.                  Mike Powell, Dec 1992.

NB. J version 6.
NB. Tested on NeXT.
NB. All values are stored in 5!:5 format. Values retrieved from the file
NB. are recreated with the Do verb, ". .
NB. There's no checking done. Ill-formed arguments, references to
NB. non-existent files or keys etc, all generate errors.

NB. Create <'filename'
NB.   Creates a file and initializes its directory. Initially,
NB.   0-511     contain a two row integer matrix describing where to find
NB.             the list of keys and table of locations. Columns are
NB.             offset, size and slot capacity.
NB.   512-1535  The list of keys.
NB.             This is a list of boxed nouns. Initially empty.
NB.   1536-2559 The table of locations.
NB.             A two row integer matrix describing where to find the
NB.    objects associated with the elements of the list of keys.
NB.   Later, should either the list of keys or table of locations exceed
NB.   the slot capacity, they will be moved to a different part of the
NB.   file and given a greater capacity.
NB.   Returns the size of the file.

NB. key Get <'filename'
NB.   Returns the value associated with key. Produces an error if the key
NB.   does not exist.

NB. (key;value)Put<'filename'
NB.   Returns three integers - the offset,size and reserved capacity used
NB.   for this value.

NB.   If the key is a new one, its value is padded and appended to the end.
NB.   Padding is about 25%, rounded up to a 512B boundary.
NB.   If the key already exists and the value fits in the existing slot,
NB.   the new value replaces the old.
NB.   If the key already exists and the size of the new value exceeds the
NB.   space reserved, the value is padded and appended to the end.
NB.   Makes no attempt to reuse wasted space within the file.

NB.   A key is a noun. For example, the following are all usable as distinct
NB.   keys:
NB.     'abcd
NB.  <'abcd'
NB.  1 4$'abcd'
NB.  i.4 10
NB.  6.7j8

NB. Dir<'filename'
NB.   Returns the list of keys.
NB.   For example, to test if a key is already present;
NB.   (<'abc')e. Dir<'filename'

NB. (<'sourcefile')Copy <'destination file'
NB.   Copies the contents of one file to another. Eliminates wasted space.
NB.   Returns the before and after file sizes.

rep =. 5!:5
wr =. 1!:2
ap =. 1!:3
sz =. 1!:4
iw =. 1!:12
ev=. ". 1!:11

m=.  < 'a=.rep<''a'' [ a=.i.0'
m=.m,< 'b=.rep<''b'' [ b=.0 3$0'
m=.m,< 'c=.rep<''c'' [ c=.2 3$512,($a),1024,1536,($b),1024'
m=.m,< 'c=.(512{.c),(1024{.a),1024{.b'
m=.m,< '$c [ c wr y.'
Create =. m : ''

m=.  < 'a=.ev y.,<0 512'
m=.m,< 'b=.ev y.,<0 1{0{a'
m=.m,< 'c=.ev y.,<0 1{1{a'
m=.m,< 'ev y.,<,0 1{(b i. <x.){c'
Get =. '' : m

m=.  < 'a=.0{y.'
m=.m,< 'y.=.>1{y.'
m=.m,< 'b=.(sz a),$y.'
m=.m,< 'y.=.(512*>.($y.)%400){.y.'
m=.m,< 'a=.y. ap a'
m=.m,< 'b,$y.'

n=.  < 'a=.(2{x.)>:$>1{y.'
n=.n,< '$.=.((-.a)#2),(4#a)#3 4 5 6'
n=.n,< 'write y.'
n=.n,< 'a=.0{y.'
n=.n,< 'y.=.>1{y.'
n=.n,< 'a=. y. iw a,<(0{x.),$y.'
n=.n,< '(0{x.),($y.),2{x.'
write =. m : n

m=.  < 'a=.0{x.'
m=.m,< 'x.=.rep<''x.'' [ x.=.>1{x.'
m=.m,< 'b=.ev y.,<0 512'
m=.m,< 'c=.ev y.,<0 1{0{b'
m=.m,< 'd=.ev y.,<0 1{1{b'
m=.m,< 'e=.c i. a'
m=.m,< '$.=.((e>:#c)#7 8 9 10 11),(e<#c)#12 13 14 15'

m=.m,< 'f=.write y.,<x.'
m=.m,< 'a=.(,0{b) write y.,<rep <''c'' [ c=.c,a'
m=.m,< 'b=.(,1{b) write y.,<rep <''d'' [ d=.d,f'
m=.m,< 'a=.512{.rep<''a'' [ a=.2 3$a,b'
m=.m,< 'f [ a iw y.,<0 512'

m=.m,< 'f=.(,e{d) write y.,<x.'
m=.m,< 'a=.(,1{b) write y.,<rep<''a'' [ a=.(e{.d),f,(e+1)}.d'
m=.m,< 'a=.512{.rep<''a'' [ a=.2 3$(0{b),a'
m=.m,< 'f [ a iw y.,<0 512'
Put=. '' : m

Dir =. 'ev y.,<0 1{0{ev y.,<0 512' : ''

m=.  < 'a=.Dir x.'
m=.m,< '$.=.(($a)$2),3 [ b=.0'
m=.m,< 'b=.b+1 [ ((b{a),<(>b{a)Get x.)Put y.'
m=.m,< '(sz x.),sz y.'
Copy =. '' : m

-----------------------------------------------------------
This posting is forwarded from an internal Reuters mailbox.
No statement or opinion contained herein should be taken as
being Reuters policy, or even as being approved by Reuters,
in any way.
Newsgroups: comp.lang.apl