Fresh segments obey the following conventions:
the truncate segment call (truncseg),
the sibling segment call (sibseg) {The new seg starts as zero},
the delete segment call (delseg),
Otherwise, c will be 0 and FS will be the only key to a new fresh segment {(fs)}. Space bank SB2 will be used to obtain space needed by the fresh segment after the time of its creation. SB2 need not be an official space bank, but if it does not behave as a space bank there are no promises as to what the fresh segment will do. The segment keeper will run under meter M. Initially all bytes in the segment are zero.
{nonref}See (p3,prompt2) about why two banks are needed.
{arcane}See (p3,fscl) and (p3,vcsklogic) for sketchy program logic for these segment keepers.
As documented above, every fresh segment has its own segment keeper domain. There are two alternative implementations, and several designs that can be built on each.
One alternative allows several fresh segments to share the same segment keeper. Each keeper has a single space bank. If the fresh segments are using the same bank, there is no reason not to share segment keepers, because the keeper is only as prompt as the bank.
Another alternative also allows several fresh segments to share the same segment keeper, but each segment can use a different space bank. {A key to the bank is kept in the segment node, so there is one fewer initial slot available.} Two fresh segments could not share a keeper if one used a slow bank and the other used a fast bank and needed to be fast. The decision of what banks to group together for sharing a keeper would be made by the client of the FSC, because there is no standard for degrees of promptness.
Both these alternatives are motivated by the desire to save the storage associated with the segment keeper. If a keeper needs three nodes and one page {a parameter page}, about half the space in small segments could be saved by sharing keepers.
On the other hand, it appears possible that a segment keeper could be implemented which did not need to have its own parameter page permanently assigned. It could get one from the bank when it needed one {which would be on almost every call}, and when done, would return it or, if the call resulted in needing a page for the segment, recycle it locally. It may be awkward or impossible to implement the "read length" call, which returns a byte string. Then too, there is hope that modifications to the kernel may allow passing byte strings in registers, which would make it more likely that a segment keeper could be implemented which did not need a private page. If a private page is not needed, the argument for sharing is weaker because little space is involved.
These alternatives would be mirrored by changes in the user-visible interface. There might be a call on the FSC that accepts a key to be used as the segment keeper, returned on some previous call. Or there might be a Fresh Segment Creator Creator that builds FSC's with segment keepers built in. There are also several choices for specifying the space bank.
The current design was chosen because:
we have no statistics on fresh segment usage, so we don't know whether the potential storage savings of sharing are significant,
and we expect it will be possible to extend the current design if a change becomes necessary later, or, at worst, implement a new design which users can take advantage of if they choose.
"weaken key" (weak-seg)
{ni}"store segments" (stseg)
"truncate segment" (truncseg)
"exhausted space bank trap" (fullseg)
"read-only trap" (p2,roseg)
"dead parent" (dead)
"non zero scan" (nonzscan)
See (p3,vcsk-lc) for introduction to VCSK segments.
{arcane}{nonref}(p3,vcsklogic) is about the implementation of this segment keeper.
Enhancement Needs
Supporting Inflation
A VCSK order to accept (and sever) a page for a specified address might serve for initial inflation.
Old idea
This idea won't work because there may be segment keys in the tree. These would defeat the zero-skip code.
Any algorithm that can do this efficiently can as well provide an even better function: "Search forward (or backward) from here for the first non-zero byte. This would make deflation of sparse segments efficient.
Perhaps a order on the page can test for zero without bringing the page in. alternatively a kernel object could test the page.
A useful subset of the above function is to merely provide a vcsk order to "disown ancestors." This would make all non zero pages come from the current bank and no sense keys would remain in the tree. This idea is less elegant but might be easy to do. A simple way to do this would be to implement an "entire segment transplant" order which is like the old store segment operation but merely replaces the keys in the top (red) node with those of another segment. The effect may then be had by copying into a new segment and then doing the transplant.
The Unix address spaces need a segment that splits into two writable segments. Using VCSK for this means that the parent storage is not recoverable. I fear that this too is too unlike the current VCSK.
Accomplished:(but unreleased)
There should be a first class way of deleting the factory resulting from order 17 on a VCSK. Perhaps KT+4 on a segment should destroy everything built on the original bank as well as the stuff built from the bank mentioned in the order 17.(Done)
We should rationalize the behavior of a segment with a dead ancestor so that we can document it. (Done, see (dead)).
The tree of a VCSK segment is (internally) defined as those nodes reachable via node keys from the root. All node keys in the tree are formatted black. Sense keys may be found in the tree as well. These lead to trees outside the Vtree.
See (formative,vcseg) for early ideas on this.
The nodes and pages used to build the segment are returned to the space bank from which they came. Any data in the segment is lost. All keys to the segment become DK(0).
If the segment keeper produces virtual copies, those copies may also be deleted, depending on the logic of the keeper.
Make Read-only Segment Key {oc=0}
Make No-call Segment Key {oc=2}
Make Read-Only No-call Segment Key {oc=3}
The (_length) of a segment is the lowest address such that all bytes at that address or higher addresses yield the same result when read. The result may be an error or it may be a value {such as zero}. {The length of a segment may be as high as 2**48.}
This order should be like S(1,(8,2**48-1)==>c((8,length));). See below.
S(1,((8,start_scan))==>c,((8,zstrt));) scans the segment backwards starting from start_scan and reports the first non zero byte. zstrt is one plus the offset of that non zero byte. Thus zstrt = start_scan+1 if the byte at start_scan is not 0. zstrt=0 if all scanned bytes are zero. c=1 if undefined pages were found indicating dead ancestors. zstrt is one plus the address of this invalid offset. This supports efficient flattening of very sparse segments. One can leap tera bytes at a single bound (but only backwards).
c=2 and SB was not a valid prompt bank or
c=0 {the good case} and SB was a valid prompt bank.
F is a discreet {no-hole} factory requestor's key that produces, using the convention (p3,two-bank-fact-call), new writable segments that obey the same protocol as S and whose initial values are those of S.
Design Dilemma: How does one delete this factory? The builder's key is too much to give away. The requestor's key is too weak. Proposal: Consider the factory to be part of the segment. KT+4 to the segment does in the factory that stemmed therefrom.
Order kt+4 on segment S deletes both S and the factory that may have been produced.
If such a factory or segment is destroyed then factories and segments descended from the destroyed factory or segment may malfunction. {(dead)}
Let SEGA and SEGB be distinct segments kept by VCSK. SEGA must not be frozen and SEGB must have write rights. SEGA(32,(6,x);SEGB ==> c;) has the effect of deleting SEGB {and factories produced thereby} and storing the data of SEGB into SEGA at address x. x must be a multiple of 4K. The bank of SEGB will receive unneeded nodes that came from SEGB. The bank of SEGA will be used for new storage {and remain the bank of SEGA}. Deleting SEGA will not reclaim material originally from SEGB unless that material is acceptable to SEGA's bank.
A deadlock may occur if two segments are "fed to each other". Neither segment will obey orders thereafter.
Error codes
If key SEGB does not have write rights then c=2.
If the x is 0 then c=3. This restriction might be removed.
c=kt+9 if a ancestor of SEGA has been deleted.
the amalgamation operation is not yet implemented;
the amalgamation may undo the economy that this segment operation was designed for.
When the data from SEGB is stored into SEGA I think that SEGB's bank will derived from SEGA's bank and thus material from SEGB will be returnable to SEGA's bank.
This code will appear as the trap code of a domain when that domain refers to a segment so as to call the segment keeper. Typically the PSW will not refer to a call jump in this case.
A return code of kt+9 from a segment indicates that a parent segment has been deleted. {(bad-vcsk)}
The 4K page order codes don't conform but are a convenient hack and would not get in the way of a more general segment protocol.
CALLSEG's design should be considered as well. Its orders 2 & 3 do reads and writes to 6 byte addresses. These orders do not conflict with page orders.