Mapped Boxed Arrays

>> << Ndx Usr Pri Phr Dic Rel Voc !: wd Help Release

Mapped Boxed Arrays | initial writing: 2000-03-31 last updated: 2004-10-21

Introduction
Amend in Place
Multiple References
Shared Use
Diagnostics
Function Summary

Introduction

You are assumed to have studied the “Mapped Files” Lab as a pre-requisite. (The lab is found under the J menu item Studio|Labs...|Mapped Files.) Now then, a quick example illustrates mapped boxed arrays:

       corequire 'jmf'
       createjmf_jmf_ 'q.jmf';3e5
       map_jmf_ 'q';'q.jmf';'sh';0

The first line defines the requisite mapped file utilities into the`jmf` locale.
The second line creates a mapped file named`q.jmf` of size 300,000 bytes.
The third line maps the file, associating the name`q` (more precisely`q_base_`,`` `q` in the`base` locale) to the mapped file`q.jmf`,`` using the share name`sh`,`` in read-write mode. Initially,`q` is the empty vector.
The verb`showmap_jmf_` provides information on currently mapped arrays. The result is a table with a row of column headings and one row of information per mapped array: name, file name, share name, file handle, mapping handle, address, header address, size, and number of references. For example:

       showmap_jmf_ ''
    +-------+-----+--+---+---+--------+--------+------+----+
    |name   |fn   |sn|fh |mh |address |header  |msize |refs|
    +-------+-----+--+---+---+--------+--------+------+----+
    |q_base_|q.jmf|sh|380|408|39714816|39714816|300000|2   |
    +-------+-----+--+---+---+--------+--------+------+----+

To create a mapped boxed array, simply assign a boxed array to a mapped name. Thus:

       q=: 'abc';(i.2 3);'penultimate';_1
       q
    +---+-----+-----------+--+
    |abc|0 1 2|penultimate|_1|
    |   |3 4 5|           |  |
    +---+-----+-----------+--+

Any operation supported on a boxed array, is supported on a mapped boxed array. In particular, amend in place is supported.
A mapped boxed array is self-contained in the mapped file. That is,`q` itself and the subarrays`'abc'`,`` `i.2 3`,`` `'penultimate'`,`` and`_1` are all contained in the mapped file.
To unmap an array, use the verb`unmap_jmf_`. The argument is the name of the mapped array. Thus:

       unmap_jmf_ 'q'

Amend in Place

Amend in place is supported for mapped boxed array. In the phrase`a=: b ind}a` the indexed elements of`a` are amended, and in so doing no copy of`a` is created. Hence amend in place.

       q
    +---+-----+-----------+--+
    |abc|0 1 2|penultimate|_1|
    |   |3 4 5|           |  |
    +---+-----+-----------+--+
       q=: (<'alpha') 0}q
       q
    +-----+-----+-----------+--+
    |alpha|0 1 2|penultimate|_1|
    |     |3 4 5|           |  |
    +-----+-----+-----------+--+

In amending element 0 from`'abc'` to`'alpha'`,`` no copy of`q` is made. (Trust me.)
Amend in place for mapped boxed array is atomic, in that either all the specified elements are amended or none of them are amended. In the following example, neither element 0 nor 1 is amended. Element 0 would have succeeded, but the new data for element 1 is`i.1e6`,`` which takes over 4 Mbytes, but the mapped file for`q` is limited to 300 Kbytes.

       q=: ('abc';i.1e6) 0 1}q
    |allocation error
    |   q=:('abc';i.1000000)    0 1}q
       q
    +-----+-----+-----------+--+
    |alpha|0 1 2|penultimate|_1|
    |     |3 4 5|           |  |
    +-----+-----+-----------+--+

Multiple References

Assigning a name to a mapped array creates a reference to that array. All names so assigned refer to the same array, and a change to the array is reflected in all the names. This property applies in particular to multiple references created as a result of using a mapped array as an argument to an explicitly defined verb, adverb, or conjunction. For example:

       q
    +---+-----+-----------+--+
    |abc|0 1 2|penultimate|_1|
    |   |3 4 5|           |  |
    +---+-----+-----------+--+
       t=: q
       t
    +---+-----+-----------+--+
    |abc|0 1 2|penultimate|_1|
    |   |3 4 5|           |  |
    +---+-----+-----------+--+
       t=: (<'boustrophedonic') _1}t
       t
    +---+-----+-----------+---------------+
    |abc|0 1 2|penultimate|boustrophedonic|
    |   |3 4 5|           |               |
    +---+-----+-----------+---------------+
       q
    +---+-----+-----------+---------------+
    |abc|0 1 2|penultimate|boustrophedonic|
    |   |3 4 5|           |               |
    +---+-----+-----------+---------------+

       am=: 4 : 0
    y.=. x. 0}y.
    0
    )
       (<'alpha') am t
    0
       t
    +-----+-----+-----------+---------------+
    |alpha|0 1 2|penultimate|boustrophedonic|
    |     |3 4 5|           |               |
    +-----+-----+-----------+---------------+
        q -: t
    1

Shared Use

The verb`share_jmf_` provides access to an array previously mapped in the current or another process. The argument is`n;s` where`n` is the new name and`s` is the share name supplied in the original call to`map_jmf_`. For example:

       share_jmf_ 'xy';'sh'
       xy
    +-----+-----+-----------+---------------+
    |alpha|0 1 2|penultimate|boustrophedonic|
    |     |3 4 5|           |               |
    +-----+-----+-----------+---------------+

The result is a new reference to the mapped array, with consequences as described in Multiple References.

Diagnostics

The verb`15!:12` returns a 3-column sorted integer matrix of memory usage information on a mapped boxed array. The columns are: address, block size, and usage code (0 overall; 1 used; 2 free). For example:

       q=: 'abc';(i.2 3);'penultimate';_1
       q
    +---+-----+-----------+--+
    |abc|0 1 2|penultimate|_1|
    |   |3 4 5|           |  |
    +---+-----+-----------+--+

       15!:12 q
    32309552 299576 0
    32309552     64 1
    32309616     64 1
    32309680    128 1
    32309808     64 1
    32309872     64 2
    32309936    128 2
    32310064   4096 2
    32314160  32768 2
    32346928 262144 2

       15!:12 'not a mapped boxed array'
    |domain error
    |       15!:12 'not a mapped boxed array'

The verb`mbxcheck_jmf_` performs internal consistency checks on a mapped boxed array, based on the information produced by`15!:12`.`` The result is a boolean vector whose elements correspond to the following conditions:
0 usage codes are 0, 1, or 2
1 block sizes are powers of 2
2 blocks are contiguous
3 first block begins at the base address
4 last block is within bounds
5 the total block size is a multiple of 64
6 the total block size matches the overall size rounded down to 64
7 addresses are double-word aligned
For example:
`
mbxcheck_jmf_ q
1 1 1 1 1 1 1 1
` The verb`15!:13` reconstructs the free list of a mapped boxed array (not yet implemented).

Function Summary

`createjmf_jmf_ f;m`
  Create map file`f` with size`m` bytes.
`map_jmf_ n;f;s;ro`
  Map name`n` to file`f` with share name`s`,`` read-only or not`` (`ro=1` or`0`).
`unmap_jmf_ n`
  Erase name`n` from the current process and, if it is not still mapped (by the current or some other process), unmap the associated file.
`share_jmf_ n;s`
  Obtain access to a mapped array under name`n` and share name`s` .
`showmap_jmf_ ''`
  A boxed table of column headings and one row of information for each mapped array: name, file name, share name, file handle, mapping handle, address, header address, size, and number of references.
`mbxcheck_jmf_ y`
  Apply internal consistency checks on the mapped boxed array`y` (based on`15!:12`).
`15!:12 y`
  A 3-column matrix of addresses, block sizes, and usage codes for mapped boxed array`y`.
`15!:13 y`
  Reconstruct the free-list for mapped boxed array`y` (not yet implemented).

>> << Ndx Usr Pri Phr Dic Rel Voc !: wd Help Release