Vision Release Notes 6.1.1

Description

Release 6.1.1 adds new capabilities, bug fixes, and specialized performance improvements to Vision. Internally, it also implements many important architectural changes that lay the groundwork for future capabilities. These notes describe the functionality, bug fixes, and other externally visible changes associated with this release.

Please note that this release introduces the need for a Vision license key in order to update your database. The license is tied to specific hosts or IP addresses. Based on this information, Insyte will supply you with a Vision script that must be installed in order to update your database with release 6.1.1 (and future releases). See Update Licenses for more information.

Several Vision scripts have been included with this release, providing optional new and modified messages for your installation:

    EXTcore.6.1.1 New protocol for core classes
    CHadmin.6.1.1 New and modified protocol for the AdminTools ToolKit
    CHfeeds.6.1.1 New and modified protocol for DataFeed support

Some of these messages can be installed independent of the Vision version being run; however, many of the messages included in this release define new primitives which will only work with this and future releases. These messages are identified in the New Messages.


Update Licenses

A license issued by Innovative Systems Techniques, Inc. is required to update a Vision database using this and subsequent Vision releases. Without that license, Vision can be used to read an existing database but not maintain or build one. If, at the start of an update, Vision cannot find a suitable license, it generates the following output:

     Utility updateNetwork
    V> ?g
    >>> License Does Not Permit Network Update From This Session <<<
            5
    
Vision update licenses are tied to specific hosts or IP addresses. Once you have supplied Insyte with this information, you will receive via e-mail a Vision script containing licensing information defined for your environment. The EXTcore.6.1.1 script implements the basic changes to the Utility class required to save and use the license. With the modifications defined in those scripts installed, the Vision license script you received simply needs to be run and saved once in order to permanently enable updates to that database from the systems for which you have licenses.

Selector Not Found Reporting

As of this release, the information content of Selector Not Found messages can be controlled via a session attribute. The EXTcore.6.1.1 script defines messages that enable and disable this attribute. When enabled, a display of the Vision virtual machine's execution stack accompanies each Selector Not Found message. By default, this attribute is disabled, resulting in the generation of conventional Selector Not Found messages. The following example illustrates the result of enabling this attribute:

    ####  Define a method that causes a selector not found, ...
    V> Integer defineMethod: [ | foo | ^self bar ];
    V> ?g
    
    ####  Generate the conventional selector not found, ...
    V> 3 foo
    V> ?g
    
    >>> Selector 'bar' Not Found <<<
          NA 
    
    ####  Enable verbose selector not found messages, ...
    V> Utility SessionAttribute enableVerboseSelectorNotFound ;
    V> ?g
    
    ####  And get the verbose message, ...
    V> 3 foo
    V> ?g
    
    >>> Selector 'bar' Not Found <<<
    
        Selector Recipient: #RTYPE_C_ValueStore[2:994]
    
    
    ----   1:
    
    |foo|^self bar
               ^
    
    ----   2:
    
    3 foo
      ^
          NA 
    
The verboseSelectorNotFound session attribute makes an experimental capability added to release 5.9.5 controllable using a Vision expression.

String Tokenization Primitives

Several new variants of the breakOn: primitive have been added to Vision. These are defined in the EXTcore.6.1.1 script and will only work with release 6.1.1 and future releases. These primitives extend the breakOn: concept to support substring and pattern matching and provide a convenient way to return both the matched and unmatched portions of their input. The following operations are available:

        Message             Index   Converse
        =======             =====   ========
        breakOn:            369     breakString:
        breakOnString:      389     stringBreak:		
        breakOnPattern:     390     patternBreak:
    
        tokenizeOn:         369/1   breakTokenize:
        tokenizeOnString:   389/1   stringTokenize:
        tokenizeOnPattern:  390/1   patternTokenize:
    
        cbreakOn:           370     cbreakString:
        ctokenizeOn:        370/1   cbreakTokenize:
    
In this list, all but breakOn: and cbreakOn: and their converses are new.

The breakOn:, breakOnString: and breakOnPattern: primitives divide a string into one or more substrings based on a set of characters, a string to be matched, or a regular expression, respectively. For example, if s is defined as:

    !s <- "The quick brown fox jumped over the lazy dog.";
    
then, s breakOn: "the". do: ["<" print; print; ">" printNL]; displays:
    <T>
    <>
    < quick brown fox jump>
    <d ov>
    <r >
    <>
    <>
    < lazy dog.>
    
In this example, each occurrence of a "t", "h", or "e" marks the end of a substring. To match the string "the" exactly, breakOnString: is used. For example, using breakOnString: instead of breakOn: in the previous example produces the following output:
    <The quick brown fox jumped over >
    < lazy dog.>
    
Because breakOnString: performs an exact match, the initial "The" wasn't used to delimit a substring. To match on more complex patterns, breakOnPattern: is used. For example:
    s breakOnPattern: "[Tt]he".
    do: ["<" print; print; ">" printNL];
    
displays:
    <>
    < quick brown fox jumped over >
    < lazy dog.>
    
The breakOn...: operations return the text between matches as a list of the form "substring-1", "substring-2", ..., "substring-n". The matched characters, strings, or patterns are not returned as part of that list of substrings. To deal with cases where the delimiting text is of interest, the tokenize... primitives are provided. These primitives return their results as lists of the form "substring-1", "match-1", "substring-2", "match-2", ..., "match-n-1", "substring-n". For example, replacing breakOn: with tokenizeOn: in the first of the preceding examples yields the output:
    <T>
    <h>
    <>
    <e>
    < quick brown fox jump>
    <e>
    <d ov>
    <e>
    <r >
    <t>
    <>
    <h>
    <>
    <e>
    < lazy dog.>
    
Note that the elements in the output list returned by tokenizeOn... always alternate between the substrings between matches and matched text. If matches occur at adjacent positions in the source string, they are separated by an empty substring in the result. The empty substrings separating the matched "t"'s, "h"'s, and "e"'s are examples of this behavior. As is the case with breakOn..., the first string in the list is always the text up to the first match, and the last string in the list is always the text after the last match.

To complete the illustration of the tokenizeOn...: variants, if tokenizeOnString: is used in place of tokenizeOn: in the previous example, the following output is generated:

    <The quick brown fox jumped over >
    <the>
    < lazy dog.>
    
and, if ... tokenizeOnPattern: "[Tt]he" is used in place of ... tokenizeOnString: "the", the following result is produced:
    <The>
    < quick brown fox jumped over >
    <the>
    < lazy dog.>
    
Before leaving the topic of tokenization, there is another noteworthy example. ctokenizeOn:, given an empty argument, can be used to quickly convert a string into a list of its characters. For example:
    "abc" ctokenizeOn: "".
    do: ["<" print; print; ">" printNL];
    
generates the output:
    <>
    <a>
    <>
    <b>
    <>
    <c>
    <>
    
This behavior is used to produce the high performance version of the toList String method, supplied in the FIXcore.6.1.1 script.

While empty character sets always produce well defined answers when passed as an argument to breakOn:, tokenizeOn:, cbreakOn: and ctokenizeOn:, they can cause problems for the string and pattern matching variants of these primitives. That is because empty strings and patterns always match the beginning of any input and never consume any characters from that input. The result is a sure-fire recipe for an infinite loop. To prevent that, special provision is made in these primitives to detect empty search strings and patterns. If an empty string or pattern is detected, only the first, empty match will be returned. Thus, either:

    "abc" breakOnString: "". do: ["<" print; print; ">" printNL];
    
or:
    "abc" breakOnPattern: "()". do: ["<" print; print; ">" printNL];
    
displays:
    <>
    <abc>
    
while either:
    "abc" tokenizeOnString: "". do: ["<" print; print; ">" printNL];
    
or:
    "abc" tokenizeOnPattern: "()". do: ["<" print; print; ">" printNL];
    
displays:
    <>
    <>
    <abc>
    
While on the topic of regular expressions and string pattern matching, there is one final point to be made. The regular expression processing algorithms used by all string pattern matching primitives in Vision always match the longest possible substring. For simple patterns, this isn't usually an issue, but, for patterns with wildcards, some care needs to be taken. For example, in the examples of this section, if:
    s tokenizeOnPattern: "[Tt]he". do: ["<" print; print; ">" printNL];
    
had been written as:
    s tokenizeOnPattern: "[Tt].*e".do: ["<" print; print; ">" printNL];
    
the resulting output would have been:
    <>
    <The quick brown fox jumped over the>
    < lazy dog.>
    
instead of:
    <The>
    < quick brown fox jumped over >
    <the>
    < lazy dog.>
    

String Case Conversion

Five new unary primitives have been defined in the EXTcore.6.1.1 script to change the case of a string. Four of these primitives are direct replacements for non-primitive methods currently in use -- toUpper, toLower, capitalize, and lowercase. The fifth, toggleCase, flips the case of all upper and lower case characters it finds in its input string. All of these primitives return a suitably modified copy of their input.

String Clustering

Prior to this release, there was no direct mechanism for placing a string in a specific cluster. Only the Vision bulk loader (a.k.a., the incorporator) had that ability. The implementation and performance consequences were significant and often hard to recognize. Release 6.1.1 introduces a collection of primitives that facilitate string clustering.

Beginning with this release, strings can be clustered using a mechanism known as associative clusters. Associative clusters apply only to strings. Associative string clusters are similar to dictionaries in that they examine the text of a string and store at most one copy of a string based on its text. Additionally, like dictionaries, the instances in an associative cluster are ordered by their text. The script EXTcore.6.1.1 contains the new primitives defined to support string clustering. These primitives will not work with earlier releases.

Not all string clusters are associative string clusters. Associative string clusters are created using the newAssociativeCluster operation:

    !stringSpace <- String newAssociativeCluster;
    
The string returned by newAssociativeCluster is the shadow instance of a new associative cluster containing no instances. The message isAnAssociativeCluster returns a boolean indicating whether the recipient String is part of an associative string cluster.

Strings are added to the associative cluster using the message insertIntoCluster::

    !a0 <- "a" insertIntoCluster: stringSpace;
    
or its converse, clusterInsert::
    !a1 <- stringSpace clusterInsert: "a";
    
As noted, only one copy of "a" is inserted into the cluster -- both a0 and a1 reference the same copy of the string "a".

Associative clusters can be queried to determine if they contain a particular string. The locateInCluster: message or its converse, clusterLocate: perform that function. Both messages return the instance of the string in the associative cluster if the string is present and NA if it isn't. In the context of this example, both:

    "a", "b" do: [
        ^self print: 3;
         ^self locateInCluster: ^my stringSpace. printNL
    ];
    
and:
    "a", "b" do: [
        ^self print: 3;
         ^my stringSpace clusterLocate: ^self. printNL
    ];
    
display:
    a  a
    b        NA 
    
Strings can be deleted from an associative cluster using the deleteFromCluster: message or its clusterDelete: converse:
    Input:
    "a" deleteFromCluster: stringSpace
    
    Output:
    TRUE
    
    Input:
    stringSpace instanceList
    
    Output:
    List of 0
    
Both deletion messages return TRUE if the string was found and deleted and FALSE if the string was not present in the first place. If the same string is deleted in the context of a list operation:
    "a", "a" do: [
        ^self print: 2;
        ^self deleteFromCluster: ^my stringSpace. printNL
    ];
    
only one instance of the delete operation returns TRUE:
    a FALSE
    a TRUE
    
As is the case with any deletion, all references to the deleted string are automatically converted to references to the shadow instance of the associative cluster.

Strings stored in associative clusters are protected from deletion using the standard instance deletion messages -- delete and rdelete. If one of these messages is sent to an associative cluster resident string, the deletion will fail and the message will return FALSE:

    Input:
    !a0 <- "a" insertIntoCluster: stringSpace
    Output:
    a
    
    Input:
    a0 rdelete
    Output:
    FALSE
    
    Input:
    a0
    Output:
    a
    
While strings in associative clusters are protected from accidental deletion, they are not protected from damage by the incorporator. If an associative string cluster is used as an incorporator string store, it will be severely damaged and will need to be re-created.

Cluster Object Space Assignment

As of this release, it is possible to explicitly assign newly created transient clusters to specific persistent object spaces. Previously, that assignment was made based on the first persistent reference to the new cluster encountered during the initial save of the new cluster. The script EXTcore.6.1.1 includes new primitives used to locate new clusters. These primitives will not work with earlier releases.

Cluster object space assignments are made with the message establishResidenceInSpaceOf: :

    Object createSubclass: "MyClass";
    MyClass establishResidenceInSpaceOf: AnotherClass
    
or its converse provideResidenceFor::
    Object createSubclass: "MyClass";
    AnotherClass provideResidenceFor: MyClass
    
AnotherClass is assumed to have a persistent identity (i.e., it was saved previously or given a persistent identity using the cluster object space assignment messages described here). If AnotherClass has a valid persistent identity (i.e., an object space), MyClass will be assigned to the same object space as AnotherClass.

Both the establishResidenceInSpaceOf: message and its converse return TRUE if the object space assignment was performed successfully and FALSE if it failed. The object space assignment can fail if the new cluster already has a persistent identity or if the old reference cluster doesn't. If the assignment fails, no identity changes occur.


IEEE NaN->NA Conversion

As of this release, the numeric primitives (add, subtract, multiply, divide, power, subtracted from, divided into, and power of) convert IEEE NaN (Not a Number) values into Vision NAs. Previously, only division by zero generated Vision NAs; other conditions like overflow, underflow, and loss of precision returned the IEEE NaN generated by the hardware. While these NaN values propagated correctly through subsequent computations, Vision programs could not test for them or control their display.


Type Defragmentation/Coalescing

When sending a message to a collection of objects, Vision's virtual machine partitions that collection by the type of its elements. For each type found, the virtual machine locates the implementation of the message and applies that implementation to the set of elements in the associated partition. The objects returned become the recipients of the next message sent by the expression being evaluated. In general, the objects returned can be of different types, and more importantly, objects of the same type can be returned in several of the partitions. The effect of this recursive partitioning is fragmentation (in fact, the structure used to hold these partitioned intermediate results is called a fragmentation). Common examples of this occur when a message returning a boolean is sent to a polymorphic collection of objects or different execution paths generated by ifTrue: and its variants all return objects of the same type.

There is a performance and clustering tradeoff between performing a computation on a recursively fragmented collection versus coalescing the fragmentation. Coalescing similar types can result in larger and more efficiently organized partitions; however, there is a cost associated with searching for coalesceable fragments and with performing the defragmentation. Historically, Vision deferred defragmentation because, in the majority of cases, that resulted in better average performance. In some cases, particularly those involving the creation of new persistent objects, this decision had an adverse affect on clustering, update performance, or both. A new, high performance, defragmentation algorithm implemented in this release changes the tradeoff. As of this release, Vision's default behavior is to attempt aggressive defragmentation prior to sending a message to a fragmented collection.

Vision's type defragmentation behavior can be controlled by the visionAttemptDefragment session attribute (defined in the accompanying extension scripts) or the VisionAttemptDefragment environment variable. Aggressive defragmentation can be disabled by setting the session attribute to FALSE:

    Utility SessionAttribute visionAttemptDefragment <- FALSE;
    
or by setting the environment variable to 0:
    setenv VisionAttemptDefragment 0    # c-shell syntax
    
prior to starting a Vision session.

Optimized Garbage Collection and Session Garbage Collection

The internal queuing mechanism used by the network maintenance garbage collector (Utility collectGarbage) has been reimplemented to yield a performance improvement of up to an order of magnitude (10x) in some cases with the effect most noticeable on large databases with many containers.

Vision has always utilized a reference counting mechanism to enable the collection of transient objects that are no longer needed. This mechanism works well in most situations, but fails in the case of circular references. If a circular reference is introduced, the reference count of any object in the path of the circular reference will never drop to zero, nor will that of any objects referenced by objects in the circular path. This release includes a mark-and-sweep garbage collector for transient objects similar to the mark-and-sweep global garbage collector. The EXTcore.6.1.1 script includes the new primitive collectSessionGarbage which can be explicitly invoked to perform transient garbage collection. It is automatically invoked whenever:

    1. an allocation error is encountered.
    2. when a Vision session has been idle for more than 30 seconds.

Error handling in batchvision

A serious Vision error (reported in the NDF.ERROR file, and in the session log with the preface >>> Error Trapped by Read-Eval-Print <<<) traditionally leaves the session active, but unable to commit changes to the object network. This policy provides an opportunity for determining the cause of the error by exploring the state of the session. This remains Vision's default policy; however, with this release, there are two other possible responses to a serious error.

One of the new possibilities is to choose to exit the session. The second is to restart the session. In both cases, all access to the environment developed in the session prior to the error is lost. In the restart case, a batchvision with the same standard input and output channels replaces the original session. If both exit and restart are chosen, exit takes precedence.

This feature has been provided because, after a serious error, the batchvision session may be unable to relinquish some system resources. On some platforms, this inability is more serious than others, and can result in other batchvision sessions being stalled until the session with the error exits or restarts.

There are two ways to enable restart or exit on error. One is via environment variables:

    setenv VisionExitOnError 1
    setenv VisionRestartOnError 1
    
The second is via session attributes:
    Utility SessionAttribute visionExitOnError <- 1;
    Utility SessionAttribute visionRestartOnError <- 1;
    

Tuneable Update Write Size

Some operating and file system configurations do not work correctly when presented with large disk write requests. These failures are caught by Vision's update checksum mechanism; however, they require that the failed update be re-run. This release implements a tuning parameter that controls the maximum amount of data that Vision will attempt to transfer to disk during a single update write. Either the session attribute visionMaxWriteChunk or the environment variable VisionMaxWriteChunk can be set to the maximum number of bytes that Vision will attempt to transfer. By default, this parameter is set internally by Vision to not exceed the documented limits of the operating system on which Vision is running. You should not change the value of this parameter unless you are encountering or suspect that you are encountering a problem caused by an operating system bug.


Minor Enhancements and Bug Fixes

  1. batchvision
    1. The asObject message when sent to a POP representing a Block now returns a decompiled string. Previously it had returned an NA. This is in support of the new Selector Not Found handling.
    2. Fix to OpenVision process streams to prevent generation of Unix "zombies".
    3. Lowered Severity of echoToFile: usage errors to a "warning". This means that the error is not written to the NDF.ERRORS log, and that the session will be able to update the network. The usage errors are still reported to the session. In addition, the primitive now catches an integer argument as a usage error. In the past, an integer argument would specify an undefined file name, or potentially cause a segmentation fault.
    4. Fixed degenerate case in the FilterOutputOf: primitive. When run from a stream open via communication with an OpenVision service channel, the FilterOutputOf: primitive would sometimes not work. The degenerate case would result when the original input and output streams, opened by default when batchvision starts up, were closed.
    5. Enable the setting of the following tuning parameters as Session Attributes. Previously, they could only be modified via environment variables (see EXTcore.6.1.1)
    6. Enhanced error reporting for segment mismatches. The expected and actual transaction ids and resource ids for the segment are now included in the error message which is recorded in the NDF.ERRORS log.
    7. Modified FilterOutput2 (NT implementation of FilterOutputOf: to return 512 if process creation fails.
    8. Modified permission constants for Object Space Creation. In prior releases, if a user was in the global update rights list, then space creation was permitted. Starting with this release, VisionAdm privilege must also be set.
    9. If Utility collectGarbage is run in a session, User Space updates are no longer permitted.
    10. Any Update Annotations which were previously set to be entered into the NDF, are now also written to NDF.JOURNAL (if it exists.)
    11. New primitives to access NDF and process information including the version number of the database your session has accessed and the session's process id (see EXTcore.6.1.1).
    12. When run with the -I option, batchvision now checks the checksum of the external segments it is being asked to commit. This is subject to disabling via the environment variable VisionCheckCheckSM.
    13. Transaction IDs generated by the Windows/NT version of batchvision are now based on the volume serial number of the c: drive of the machine running batchvision and have the same structure as transaction ids generated on UNIX systems. Previously, Windows/NT transaction IDs were generated from an OLE UUID.

  2. compustat2
    1. Adjusted implementation of Floating point conversion so that NA comparisons would work on all platforms (NT in particular)
    2. Generalized Header/Trailer filtering by introducing the -N option. This allows command line specification of a character string which compustat2 will use to identify "Null" records. If the input string matches the beginning of a record, that record is discarded. By default, compustat2 behaves as though it were called in the following way:
        compustat2 -N "000000000000"
        
      In other words, it will discard all records which begin with 12 zeros.

  3. dbconvert
    1. When the transfer of a segment between platforms with the same binary data representation (i.e., no data conversion required) is interrupted, a subsequent run of dbconvert would interpret the partial segment as complete. To correct for this, the 6.1.1 version receives segments into temporary files. Only when the transfer has completed does dbconvert move the segment into place. (The temporary file is the segment number with an x character appended.
    2. When running in server mode, dbconvert would send unformatted textual error messages to the client which could not interpret them. Version 6.1.1 of the dbconvert server writes those errors instead to a file specified via the -s option. If the -s option is not specified, dbconvert will use /dev/null as the default repository for these messages.
    3. Corrected an error message informing users that a container would extend beyond the end of a segment. In earlier versions, it printed an incorrect container size.
    4. Added an error message to inform users when dbconvert cannot recognize a message format.

  4. preproc2
    1. When converting a numeric field, preproc2 now checks to ensure that the entire field is legitimately numeric. In earlier versions, preproc2 would convert whatever string was present. If the string was not numeric, the conversion result would be zero. This version converts such strings to NA values.
        For Example			New		Old
        '         '			NA		0
        '    3    '			3		3
        '    .   3'			NA		0
        '   42Kzcd'			NA		42
        

  5. ndftool
    1. removed inaccurate error report induced by a session which performed multiple saves of which one (not the last) was a base version.

  6. onprof/onck
    1. removed inaccurate error report induced by a space which has no root (container at table slot 1)
    2. augmented error messages that report mismatched versions to include the expected and actual version numbers.
    3. utility is now tolerant of missing spaces in a network.

New Messages

********************
   EXTcore.6.1.1
********************
    This script contains messages that have been added to the core classes as part of release 6.1.1. Note that many of these messages are primitives which will only run in release 6.1.1 or higher. The methods used to install these primitives relies on messages defined in the EXTprimitives.6.0 script from release 6.0.

Class     Utility
Message   UpdateLicense
          setUpdateLicenseTo: 
Class     Utility SessionAttribute
Message   licenseItemAt:
    These message have been defined to install and access the license information defined for your site. You will not be able to perform updates to your database if these messages are not installed in conjunction with a site-specific license file generated for you by Insyte.

    Note that this message will not work with releases prior to 6.1.1


Class     Utility
Message   updateNetwork
    This message has been modified to query the stored license information. If this information is not stored and/or it does not match the host or IP address defined for your installation, the update will abort and you will see the error message:
      >>> License Does Not Permit Network Update From This Session <<<

Class     Utility SessionAttribute
Message   visionMaxWriteChunk
          visionMappingLimit
          visionAddressThreshold
          visionNSyncRetries
          visionSSyncRetries
          visionSOpenRetries
          visionSORetryDelay
          visionNetOpenTrace
          visionLargeTaskSize
          visionStackDump
          visionGRMEnabled
          visionGRMTrace
          visionAttemptDefragment
          visionRestartOnError
          visionExitOnError
          verboseSelectorNotFound
          largeContainerSizeOfSpace: space
    These messages provide control over various session-temporary attributes. Note that these messages will not work with releases prior to 6.1.1

Class     Utility SessionAttribute
Message   enableVerboseSelectorNotFound
          disableVerboseSelectorNotFound
    These messages are used to toggle the amount of information displayed when a Vision query encounters a selector not found. By default, the verbose mode is disabled.

    Note that these messages will not work with releases prior to 6.1.1


Class     Utility 
Message   hostname
          hostId
          username
          processId
    The message hostname displays the logical name of the machine on which your batchvision is running. The message hostId displays the vendor-specific integer uniquely identifying this machine. The username message is the name of the current effective user code running the batchvision. The processId returns the process identifier assigned to the batchvision by the operating system.

    Note that these messages will not work with releases prior to 6.1.1


Class     Utility 
Message   accessedNetworkVersion
    This message displays the version number of the NDF accessed at session startup.

    Note that this message will not work with releases prior to 6.1.1


Class     Utility 
Message   currentNetworkVersion
    This message displays the version number of the last commit performed by this session. This will be the same as the accessed version when no commits have been performed.

    Note that this message will not work with releases prior to 6.1.1


Class     Utility 
Message   collectSessionGarbage
    This message runs the transient garbage collection.

    Note that this message will not work with releases prior to 6.1.1


Class     Utility 
Message   fullCompact
          fullCompactOf:
          fullCompactExcept:
    These methods have been modified to turn off tracing after execution so that the release 6.1.1 transient garbage collect does not cause sporadic printing to occur within a session left running after a compaction.

Class     String 
Message   breakOnString: string
          breakOnPattern: stringPattern
    These messages expand on the functionality of the breakOn: message. While the original breakOn: message divides the recipient string into one or more substrings based on a set of one or more characters, these messages are used to divide the recipient string into one or more substrings based on a string to match exactly or a regular expression. The messages stringBreak: and patternBreak: are converse messages that must be defined in the database but are not generally called directly.

    Note that these messages will not work with releases prior to 6.1.1


Class     String 
Message   tokenizeOn: string
          ctokenizeOn: string
          tokenizeOnString: string
          tokenizeOnPattern: stringPattern
    The breakOn: message variations return the text between matches as a list of the form "substring-1", "substring-2", ... "substring-n". The matched characters, strings, or patterns are not returned as part of the list of substrings. The tokenize versions of these methods return their results in the form "substring-1", "match-1", "substring-2", "match-2", ... "match-n-1", "substring-n". The elements in the returned list always alternate between the substrings between matches and the matched text. If matches occur at adjacent positions in the recipient string, they are separated by an empty substring in the result. Then message ctokenizeOn: is similar to tokenizeOn: except a match occurs for any character in the recipient not included in the parameter. The messages breakTokenize: and cbreakTokenize:, stringTokenize:, and patternTokenize: are converse messages that must be defined in the database but are not generally called directly.

    Note that these messages will not work with releases prior to 6.1.1


Class     String 
Message   toList
          translateString: string to: replacement
    These modified messages used the new ctokenizeOn: and breakOnString: primitives to produce much faster implementations.

    Note that these modifications will not work with releases prior to 6.1.1


Class     String 
Message   translatePattern: pattern to: replacement
    This message replaces all occurrences of the supplied pattern with the replacement.

    Note that this message will not work with releases prior to 6.1.1


Class     String 
Message   toUpper
          toLower
          capitalize
          lowercase
          toggleCase
    These messages are used to change the case of the characters in the recipient string. The first four of these messages replace non-primitive methods currently in use. The toggleCase method flips the case of all upper and lower case characters it finds in the recipient.

    Note that these messages will not work with releases prior to 6.1.1


Class     String 
Message   newAssociativeCluster
    This message creates a new associative string cluster and is normally sent to ^global String.

    Note that this message will not work with releases prior to 6.1.1


Class     String 
Message   isAnAssociativeCluster
    This message returns a boolean value indicating if the recipient is an associative string cluster.

    Note that this message will not work with releases prior to 6.1.1


Class     String 
Message   insertIntoCluster: cluster
          clusterInsert: stringValue
    These messages add the stringValue into an associative cluster if it is not already present in it and return the value stored in the cluster. Because associative clusters maintain only one copy of any string, the value returned will have the same contents as the one in inserted but may not be the same string object.

    Note that these messages will not work with releases prior to 6.1.1


Class     String 
Message   locateInCluster: cluster
          clusterLocate: stringValue
    These messages return the instance of the string in the associative cluster if the string is present and NA if it is not.

    Note that these messages will not work with releases prior to 6.1.1


Class     String 
Message   deleteFromCluster: cluster
          clusterDelete: stringValue
    These messages delete a string from an associative cluster. They return TRUE if the string was found and deleted and FALSE otherwise. If the same string is deleted more than once in a list operation, only one instance of the delete operation will return TRUE.

    Note that these messages will not work with releases prior to 6.1.1


Class     Object 
Message   establishResidenceInSpaceOf: object
          provideResidenceFor: aCluster
    These messages can be used to explicitly assign newly created transient clusters to specific persistent object spaces. Cluster object space assignments are made with the message establishResidenceInSpaceOf: :
      Object createSubclass: "MyClass";
      MyClass establishResidenceInSpaceOf: AnotherClass
      
    or its converse provideResidenceFor::
      Object createSubclass: "MyClass";
      AnotherClass provideResidenceFor: MyClass
      
    AnotherClass is assumed to have a persistent identity (i.e., it was saved previously or given a persistent identity using the cluster object space assignment messages described here). If AnotherClass has a valid persistent identity (i.e., an object space), MyClass will be assigned to the same object space as AnotherClass.

    Both the establishResidenceInSpaceOf: message and its converse return TRUE if the object space assignment was performed successfully and FALSE if it failed. The object space assignment can fail if the new cluster already has a persistent identity or if the old reference cluster doesn't. If the assignment fails, no identity changes occur.

    Note that these messages will not work with releases prior to 6.1.1


********************
   CHadmin.6.1.1
********************
    This script contains modifications and additions related to the AdminTools ToolKit. These messages work with pre-6.1.1 versions of the database as well. These messages are frequently used by Insyte support personnel to help analyze object structure complexity.
********************
   CHfeeds.6.1.1
********************
    This script contains modifications and additions related to the DataFeed class. The reconcile method is modified to keep track of the last timestamp and count each time a feed is run. This is a transitional change - more audit information will be recorded in a separate descriptor class in a future release.