Let B be a space bank. Some space banks are prompt.
Operations for Nodes
If successful, c will be 0 and N will be the only key to a node which contains all zero data keys, and there will be no process in the node.
Return codes c:
Some banks require an account for the number of gratis nodes. If the account is insufficient or the node limit is reached, c will be 3.
Some banks require an account which is charged some amount for the node. Others place a limit on the number of nodes that can be created. If the account AC is insufficient for this purpose or the limit of some superior bank is reached, c will be 4.
If want_gratis is supplied and is nonzero, the node will be gratis; otherwise, it will be non-gratis. Lower_limit and upper_limit can be used to restrict the range from which the node may be allocated; for details, see the formal description of space banks in Algol68. If it is not desired to restrict the range, lower_limit should be absent or zero and upper_limit should be absent or the maximum {unsigned} integer.
The node is acceptable to the bank provided the same limits are used.
{arcane}The full form of this operation is:
{arcane}The full form of this operation is:
If N is already gratis, c will be 2.
If N cannot be made gratis, because either account AC is insufficient or a limit was reached, c will be 3.
Otherwise, c is 0 and the node is made gratis.
Design Note: While we have not yet made use of the gratis attribute, this order plays the important function of non destructive verification of the "accptability of a node to a bank".
{arcane}The full form of this operation is:
{arcane}The full form of this operation is:
N is the number of nodes that could be created in the specified range.
C will be zero if the operation is successful. N1 and N2 are node keys with zero databytes to two different nodes, and there are no other keys to those nodes. The nodes will contain all zero data keys and will not have processes. They will be non-gratis.
C will be 1 if two nodes are not available. No node keys are returned.
{arcane}C will be 3 if want_gratis is nonzero and for that reason account AC is insufficient or a limit is reached. No node keys are returned.
C will be 4 if account AC is insufficient or a limit is reached. No node keys are returned.
{arcane}The full form of this operation is:
The nodes will be from the range specified by lower_limit and upper_limit, if specified. If want_gratis is supplied and is nonzero, the nodes will be gratis; otherwise, they will be non-gratis. The nodes will be acceptable to the bank provided the same or wider limits are used.
Time is 4.6 ms. {(p3,ob1)}.
Otherwise: c[i] will be 0; all keys that designate the node N[i], including keys that designate a domain whose root is N[i], are changed to zero data keys; if there was a process in the node it is destroyed; and if the node was gratis g[i] will be 1 otherwise 0. If the bank uses an account, AC will receive any refund for the node.
1 means N[1] was not acceptable but N[2] was.
2 means N[1] was acceptable but N[2] wasn't.
3 means neither N[1] nor N[2] was acceptable.
Time is 2.6 ms. {(p3,ob1)}.
Otherwise change_limit is regarded as a signed number and added to B's current node limit unless that would cause it to become negative or exceed 2**32-1. Instead of going negative the unmodified limit is returned and c=1. Instead of exceeding 2**32-1 the unmodified limit is returned and c=2.
A newly created page contains all zeros and you get a read/write key to it. A page key must be read/write to be acceptable to a bank.
q is 0 or 2 and WB has query rights if (B does and q = 0).
m is 0 or 4 and WB has limit change rights if (B does and m = 0).
d, q and m may not all be zero.
As each node is destroyed, all resume keys in the node are invoked with order code kt+1. The idea is to notify a caller when an object is destroyed by this method.
B(kt+4; ==> c;) {"destroy"}
This operation may be deimplemented and order code kt+4 made to provide the operation now referred to by code 64 {(o64)}. See, however, (keep64).
There should be at least a few pages and a few nodes. In other words, not all pages or all nodes. The bank needs both to build the bit map that keeps track of which pages and nodes are available.
Then mount the disk and ready it.
Then get a domain key to the primordial space bank domain. {There is one in SYSNODE.PRIMORDSTUFF.0 {sysnode.2}.} Make an entry key to it with databyte X'20'. Call it with order code 69. It will find the new space and begin using it.
A space bank will not pass a factory discression test since it (through its counters) may be used to pass information. Factory products may use the Prompt Space Bank from the factory for "offical space bank" tests since it has already passed the Factory's "offical" test.
Space limits and counters are not large enough for 6 byte CDAs or 100 MIP machines
Space banks do not permit non-mounted holes in their range keys.
Many domains require the space bank transformer solely for the purposes of testing for "offical" banks and creating sub-banks.
Create and Destroy calls do not use an Account key.
Destroy calls do not return a string.
"Gratis" is not implemented.
B(5{=Query nodes available}==>c,(4,count)) will return X'FFFFFFFF' whenever more than 2**32-1 nodes are available
B(6{=Query nodes statistics}==>c,(4,buys),(4,sells)) will return X'FFFFFFFF' when buys are more than 2**32-1. The sells value will be adjusted (if possible) so the difference (buys-sells) is the number of nodes currently allocated.
B(BANK__SET_NODE_RANGE_LIMIT{=12},(8,node_lower_limit),(8,node _upper_limit) ==> c)
Otherwise if node_lower_limit is greater than node_upper_limit c=2 and no change is made to the node limits.
Otherwise the space bank is changed to only allocate nodes with CDAs between node_lower_limit and node_upper_limit (inclusive). Note that this bank is also subject to the node range limits imposed upon superior banks.
Otherwise change_limit is regarded as a signed number and added to B's current node limit unless that would cause it to become negative or exceed 2**48-1. Instead of going negative the unmodified limit is returned and c=1. Instead of exceeding 2**48-1 the unmodified limit is returned and c=2.
B(BANK__QUERY_STATISTICS{=65} ==> c, (8,nc), (8,nd), (8,pc), (8,pd)).
Programming note: A more restrictive sub-bank may be created by using CHANGE_NODE_LIMIT, CHANGE_PAGE_LIMIT, CHANGE_NODE_RANGE_LIMIT, and CHANGE_PAGE_RANGE_LIMIT as desired and then using order code 36 to restrict change limits rights.
Each space bank is represented by a red segment node, a data structure in a common segment, and a guard segment. The keeper of the red segment is the "quick" space bank domain. It has a friend called the "slow" (although still prompt) space bank domain.
Red Segment Node Format
Slot 9 - Slot to receive caller's 3rd key parameter.
Slot 10 - Forward sibling node key (or self)
Slot 11 - Backward sibling node key (or self)
Slot 12 - Descendent node key (one of possibly many) or DK0
Slot 13 - Ancestor node key
Slot 14 - Keeper start key
Slot 15 - Red segment node format data key
(4,upper node range limit as set)
(4,lower page range limit as set)
(4,upper page range limit as set)
(8,page allocation limit)
(8,node allocation limit)
(8,nodes allocated)
(8,node sells)
(8,pages allocated)
(8,page sells)
(4,ancestor data structure segment id)
(4,ancestor data structure index within segment)
(4,data structure index within segment)
(1,node presence presence bits) Iff 0 then node data is format 0
(1,page presence presence bits) Iff 0 then page data is format 0
(4,node allocation cursor)
(4,page allocation cursor)
Format = 0 (small bitmap)
(2000, node guard bitmap) allocated node CDAs are bit offset in guard bitmap + first node.
(4,first page) - First guarded cda, must be a multiple of 32 (on a word boundry in the bitmap)
(2000, page guard bitmap) used similary to the node guard bitmap
Get a node with a lss=8 node key. Install the lss3 node key in its slot 0. Store the lss=8 node key in slot 0 of the space bank front end node. Set the format to 1.
The guard segment structure is now valid for a format 1 segment. Use grow_segment to allocate a page at first_node or first_page (whichever guard needs to be converted). Copy the first part (or all) of the bitmap to the page at the offset. If only part copied use grow_segment to allocate a second page and copy the rest.
It performs the initial processing when a space bank is zapped. This processing consists of severing the space bank node for the bank and each of its sub-banks, placing the bank nodes on a work queue for the "slow" domain.
It also implements an internal key to allow the slow space bank domain to make pages and nodes available for allocation (update the allocation map), de-queue and return space bank nodes and data structures, and request more work from the "quick" domain.
The space bank keeps two bit maps to control node and page allocation. The format and stratigy for using these bitmaps is similar to the that for format 1 guard maps described in (newbank_guard)
The space bank keeps two global (for all space banks using a keeper domain) allocation cursors, one for nodes and one for pages. When a space bank bank needs to create a new guard page, the space bank starts its search at the cda of the appropreate global allocation cursor and then sets the cursor to the first available cda + 8000. Note that to be considered available the cda must be not allocated and in a mounted range.
Each new space bank is created with initial values in the first_node and first_page fields of its format 0 guard page. These values are calculated by finding the first available cdas above the global cursors and updating the global cursors by that cda + 8000.