abora-cvs Mailing List for Abora
Status: Alpha
Brought to you by:
dgjones
You can subscribe to this list here.
| 2003 |
Jan
(191) |
Feb
(106) |
Mar
(149) |
Apr
(65) |
May
(40) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
|---|
|
From: <dg...@us...> - 2003-12-08 04:09:05
|
Update of /cvsroot/abora/website/htdocs
In directory sc8-pr-cvs1:/tmp/cvs-serv21787/htdocs
Modified Files:
style.css
Log Message:
DGJ:
-Include Dean Tribble comments on porting
Index: style.css
===================================================================
RCS file: /cvsroot/abora/website/htdocs/style.css,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** style.css 2 May 2003 13:45:21 -0000 1.8
--- style.css 8 Dec 2003 04:08:58 -0000 1.9
***************
*** 33,34 ****
--- 33,37 ----
a.screenshot:link, a.screenshot:visited { color: #ffffff; none; }
a.screenshot:hover { color: #FAEBD7; none; }
+
+ .feedback1 {border-left: 0.5em solid #CFC; padding-left: 0.5em; font-size: smaller; }
+ .feedback-meta { font-style: italic; }
\ No newline at end of file
|
|
From: <dg...@us...> - 2003-12-08 04:08:34
|
Update of /cvsroot/abora/abora-white/docs
In directory sc8-pr-cvs1:/tmp/cvs-serv21680/docs
Modified Files:
porting.html
Log Message:
DGJ:
-Include Dean Tribble comments on porting
Index: porting.html
===================================================================
RCS file: /cvsroot/abora/abora-white/docs/porting.html,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** porting.html 23 Apr 2003 01:16:52 -0000 1.12
--- porting.html 8 Dec 2003 04:08:31 -0000 1.13
***************
*** 28,34 ****
the final outcome I have chosen for Abora-White.</p>
<h3>BooleanVar</h3>
! <p>This was simply replace with the Java <tt>boolean</tt>
primitive data type.</p>
--- 28,38 ----
the final outcome I have chosen for Abora-White.</p>
+ <p class="feedback1 feedback-meta">Dean Tribble kindly emailed in
+ a few comments on the contents of this page. I have included
+ them below in the marked lines. Thanks Dean.</p>
+
<h3>BooleanVar</h3>
! <p>This was simply replaced with the Java <tt>boolean</tt>
primitive data type.</p>
***************
*** 36,40 ****
<p>The Smalltalk native support for Integers is very powerful. For
! small numbers (< 29(ish) bits) a compact unboxed in-representation form
is used to minimise performance overhead. If an integer larger
than the initial range is needed then the system automatically
--- 40,44 ----
<p>The Smalltalk native support for Integers is very powerful. For
! small numbers (< 29(ish) bits) a compact unboxed in-representation form
is used to minimise performance overhead. If an integer larger
than the initial range is needed then the system automatically
***************
*** 45,48 ****
--- 49,59 ----
other than computations start from the left.</p>
+ <p class="feedback1">These are intended as 32-bit integers. In the
+ server we were not anticipating using infinite precision
+ Integers.<br>
+
+ Note that the translator to X++ did manage
+ the transition to C++ precedence correctly.</p>
+
<p>The X++ version of Udanax-Gold seems to support just 32-bit
integers, which is a surprise. I guess this is either a
***************
*** 51,54 ****
--- 62,70 ----
IntegerVar class representations.</p>
+ <p class="feedback1">The 'Var' suffix meant allocated on the stack as opposed to the heap.
+ IntegerVar was defined so that we could control alignment, operators,
+ additional type checking, etc., but can be thought of as a 32 bit int.
+ </p>
+
<p>The Java native support for integers is split between primitive
data types of various bit sizes, and the BigInteger class which
***************
*** 58,61 ****
--- 74,80 ----
for BigIntegers.</p>
+ <p class="feedback1">I recommend mapping to int in Java.
+ </p>
+
<p>Assuming Udanax-Gold IntegerVars are required to support
unlimited procession, I have temporarily gone for a wrapped
***************
*** 74,77 ****
--- 93,101 ----
significant for the UInt32 type which is often used.</p>
+ <p class="feedback1">Mostly UInt32 was used for indices, for which negative numbers never
+ made sense. They were also used for hashes. These could almost all
+ be translated as int and it would be fine.
+ </p>
+
<p>The second case has to do with Strings; Java string characters
are unsigned 16-bit Unicode, default X++ string characters are unsigned 8-bit.</p>
***************
*** 85,88 ****
--- 109,116 ----
exceptions were added to the C++ specification.</p>
+ <p class="feedback1">I'm pretty sure they map easily to instances of type-based exceptions,
+ so the mapping to Java should be straightforward.
+ </p>
+
<p>Java supports a reasonable class based exception mechanism. A
facility beyond the Udanax-Gold exceptions is the support for
***************
*** 156,159 ****
--- 184,191 ----
}</pre>
+ <p class="feedback1">As I recall we tried to make sure that it could be translated as a
+ for-loop. That would be a little more readable.
+ </p>
+
<p>...and the original Smalltalk source:<br>
<pre> (s _ myArray stepper) forEach: [ :e {Heaper} |
***************
*** 168,171 ****
--- 200,208 ----
change the return type of the super definition.</p>
+ <p class="feedback1">Yes. Exposing the allocation behavior of a class when you want an
+ instance of it prevents opportunities for caching, refactoring, etc.
+ so we tried to use factory methods consistently.<br>
+ Yup, they definitely will need some renaming for Java.</p>
+
<p>I have used the Java constructors in place of the create
methods. This generally works out, except that Constructors have
***************
*** 175,178 ****
--- 212,219 ----
general factor pattern, the constructors are made protected.</p>
+ <p class="feedback1">Exactly the right thing. Part of the reason for the generic naming of
+ create methods is that they were supposed to map to constructors.
+ </p>
+
<p>Some open issues in this area are with the area of the
<tt>new.Become</tt>, and possibly similar methods. Java has not
***************
*** 185,188 ****
--- 226,235 ----
for all objects referencing object B to now reference object A.</p>
+ <p class="feedback1">We did not use two-way become except to emulate behavior we could
+ accomplish in C++ some other way. We did use one-way become for
+ converting stubs into objects during unmarshalling. In Java, you
+ would need to use Proxies and maintain the layer of forwarding, I
+ think (or not use lazy unmarshalling).</p>
+
<h3>Object Death</h3>
***************
*** 192,203 ****
--- 239,264 ----
the Udanax-Gold Smalltalk included these as well.</p>
+ <p class="feedback1">We used the post-mortem finalization support from ObjectWorks. That's
+ where it was invented, after all :-) For various reasons, WeakArrays
+ are much better than individual weak references, but you can still do
+ everything with individual weak references.</p>
+
<p>C++ doesn't support Garbage Collection in the default
implementation, and it is assumed that X++ included some kind of
Garbage Collection system.</p>
+ <p class="feedback1">Yes. That code should be available somewhere. It was a pretty
+ impressive GC system.</p>
+
<p>To be researched; is destruct/destroyed only relevant to X++ or
does it make sense for Smalltalk and Java implementation,
distributed and file based garbage collection support.</p>
+ <p class="feedback1">My recollection is that it was only for X++. We might have used the
+ distinction elsewhere, but we tried not to. One of the last things we
+ did was move the X++ GC to use post-mortem finalization (and not
+ destructors).
+ </p>
+
<h3>Equality and Hashing</h3>
***************
*** 257,260 ****
--- 318,325 ----
creation of the Category class.</p>
+ <p class="feedback1">Category was part of Smalltalk. We stuffed information there that
+ would normally be inline in a Java or C++ file (like instance variable
+ types). In java, there should be no need for them.</p>
+
<p>For the moment the Java Class objects are being used in place
of Categories. In the future the Category class my need to be
***************
*** 301,305 ****
elements to produce different contentHashes.</li>
! <li>IntegerRegion:below was actually a duplicate of the above method.</li>
</ul>
--- 366,374 ----
elements to produce different contentHashes.</li>
! <li>IntegerRegion:below was actually a duplicate of the above
! method.
! <br><span class="feedback1">The scary thing is that I remember this bug, so your code may be a
! slightly-earlier-than-final snapshot.
! </span></li>
</ul>
|
|
From: <dg...@us...> - 2003-12-03 04:50:19
|
Update of /cvsroot/abora/website In directory sc8-pr-cvs1:/tmp/cvs-serv12992 Modified Files: build.xml Log Message: DGJ: add updatewebsite target Index: build.xml =================================================================== RCS file: /cvsroot/abora/website/build.xml,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** build.xml 1 May 2003 13:51:35 -0000 1.28 --- build.xml 3 Dec 2003 04:50:15 -0000 1.29 *************** *** 311,314 **** --- 311,315 ---- </target> + <!--**************************************************************--> <!--** Compile Tools *********************************************--> *************** *** 321,324 **** --- 322,332 ---- /> </target> + + + <!--**************************************************************--> + <!--** Update website with latest pages **************************--> + <!--**************************************************************--> + + <target name="updatewebsite" depends="init,compile,replacetemplate,uploadNoReplace"/> <!--**************************************************************--> |
|
From: <dg...@us...> - 2003-12-03 04:49:48
|
Update of /cvsroot/abora/website/htdocs In directory sc8-pr-cvs1:/tmp/cvs-serv12879/htdocs Modified Files: index.html Log Message: DGJ: tidy up a little optimism here... Index: index.html =================================================================== RCS file: /cvsroot/abora/website/htdocs/index.html,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** index.html 4 May 2003 15:38:01 -0000 1.19 --- index.html 3 Dec 2003 04:49:45 -0000 1.20 *************** *** 39,45 **** <p>A number of sub-projects exploring these aims are documented on this website. A limited demo was written in Summer 2002 that ! gives a flavour for some of the core features. An expanded ! implementation suitable for wider exploration should be ! available Summer 2003.</p> <p>David Jones<br> <a --- 39,43 ---- <p>A number of sub-projects exploring these aims are documented on this website. A limited demo was written in Summer 2002 that ! gives a flavour for some of the core features.</p> <p>David Jones<br> <a |
|
From: <dg...@us...> - 2003-05-09 13:58:50
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests In directory sc8-pr-cvs1:/tmp/cvs-serv2145/src/org/abora/ash/ent/tests Modified Files: AllTests.java CollectionLeafTest.java Added Files: SplitNodeTest.java Log Message: -Start split node testing --- NEW FILE: SplitNodeTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import java.util.List; import org.abora.ash.engine.AboraConverter; import org.abora.ash.ent.CollectionLeaf; import org.abora.ash.ent.SequenceNumber; import org.abora.ash.ent.SplitNode; /** */ public class SplitNodeTest extends EntTestCase { public SplitNodeTest(String arg0) { super(arg0); } // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // AboraBeTests subclass: #SplitNodeTest // instanceVariableNames: '' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // SplitNodeTest guid: (GUID fromString: '{CC025AE1-680C-498F-BF70-ABE7C6E62C9F}')! // SplitNodeTest comment: ''! // !SplitNodeTest categoriesForClass!SUnit! ! // !SplitNodeTest methodsFor! // // testAssertIsChild // | splitNode leaf1 leaf2 leaf3 | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'abcdef' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 7 // elements: 'ghijk' asAboraContent. // leaf3 := CollectionLeaf // branch: 1 // startPosition: 7 // elements: 'ghijk' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 7 // left: leaf1 // right: leaf2. // splitNode assertIsChild: leaf1. // splitNode assertIsChild: leaf2. // self should: [splitNode assertIsChild: leaf3] raise: EntError! // public void testChildren() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 0, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 6, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 6, leaf1, leaf2); List children = split.children(); assertEquals(2, children.size()); assertTrue(children.contains(leaf1)); assertTrue(children.contains(leaf2)); } // testChildren // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 7 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 7 // left: dataLeaf1 // right: dataLeaf2. // self should: [splitNode children = (Array with: dataLeaf1 with: dataLeaf2)]! // // testContents // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'h' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 20 // left: dataLeaf1 // leftDsp: 16 // right: dataLeaf2 // rightDsp: -80. // // "test" // self should: [splitNode contents = 'hthere' asAboraContent]! // // testContentsAt // | splitNode leaf1 leaf2 | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'abcdef' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'ghijk' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 20 // left: leaf1 // leftDsp: 11 // right: leaf2 // rightDsp: -80. // self should: [(splitNode contentsAt: 14) = $a codePoint]. // self should: [(splitNode contentsAt: 15) = $b codePoint]. // self should: [(splitNode contentsAt: 19) = $f codePoint]. // self should: [(splitNode contentsAt: 20) = $g codePoint]. // self should: [(splitNode contentsAt: 24) = $k codePoint]! // // testContentsAtBadPosition // | splitNode leaf1 leaf2 | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'abcdef' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'ghijk' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 20 // left: leaf1 // leftDsp: 11 // right: leaf2 // rightDsp: -80. // self should: [splitNode contentsAt: 13] raise: BoundsError. // self should: [splitNode contentsAt: 25] raise: BoundsError! // // testContentsFromExtentDo // | splitNode out do | // splitNode := SplitNode // branch: 1 // split: 7 // left: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '123456' asAboraContent) // right: (CollectionLeaf // branch: 1 // startPosition: 7 // elements: '78901' asAboraContent). // out := ''. // do := [:int | out := out , (Character codePoint: int) asString]. // splitNode // contentsFrom: 1 // extent: 11 // do: do. // self should: [out = '12345678901']. // out := ''. // splitNode // contentsFrom: 1 // extent: 6 // do: do. // self should: [out = '123456']. // out := ''. // splitNode // contentsFrom: 7 // extent: 5 // do: do. // self should: [out = '78901']. // out := ''. // splitNode // contentsFrom: 2 // extent: 3 // do: do. // self should: [out = '234']. // out := ''. // splitNode // contentsFrom: 8 // extent: 2 // do: do. // self should: [out = '89']. // out := ''. // splitNode // contentsFrom: 3 // extent: 7 // do: do. // self should: [out = '3456789']. // out := ''. // splitNode // contentsFrom: -4 // extent: 10 // do: do. // self should: [out = '12345']. // out := ''. // splitNode // contentsFrom: 8 // extent: 10 // do: do. // self should: [out = '8901']. // out := ''. // splitNode // contentsFrom: -4 // extent: 20 // do: do. // self should: [out = '12345678901']. // out := ''. // splitNode // contentsFrom: -4 // extent: 6 // do: do. // self should: [out = '1']. // out := ''. // splitNode // contentsFrom: -4 // extent: 5 // do: do. // self should: [out = '']. // out := ''. // splitNode // contentsFrom: 11 // extent: 2 // do: do. // self should: [out = '1']. // out := ''. // splitNode // contentsFrom: 12 // extent: 2 // do: do. // self should: [out = '']! // public void testCount() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 99, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 19, leaf1, 12, leaf2, 80); assertEquals(11, split.count()); } // testCount // | splitNode | // splitNode := SplitNode // branch: 1 // split: 20 // left: (CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'hello ' asAboraContent) // leftDsp: 12 // right: (CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent) // rightDsp: 80. // self should: [splitNode count = 11]! // // testCreate // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 7 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 7 // left: dataLeaf1 // right: dataLeaf2. // self should: [splitNode split = 7]. // self should: [splitNode left == dataLeaf1]. // self should: [splitNode right == dataLeaf2]. // self should: [dataLeaf1 parents = (OrderedCollection with: splitNode)]. // self should: [dataLeaf2 parents = (OrderedCollection with: splitNode)]! // // testCreateDsp // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 20 // left: dataLeaf1 // leftDsp: 14 // right: dataLeaf2 // rightDsp: -80. // self should: [splitNode split = 20]. // self should: [splitNode left == dataLeaf1]. // self should: [splitNode leftDsp = 14]. // self should: [splitNode right == dataLeaf2]. // self should: [splitNode rightDsp = -80]. // self should: [dataLeaf1 parents = (OrderedCollection with: splitNode)]. // self should: [dataLeaf2 parents = (OrderedCollection with: splitNode)]! // public void testDspForChild() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 99, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 19, leaf1, 14, leaf2, -80); assertEquals(14, split.dspForChild(leaf1)); assertEquals(-80, split.dspForChild(leaf2)); } // testDspForChild // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 20 // left: dataLeaf1 // leftDsp: 14 // right: dataLeaf2 // rightDsp: -80. // self should: [(splitNode dspForChild: dataLeaf1) = 14]. // self should: [(splitNode dspForChild: dataLeaf2) = -80]! // public void testDspSetForChild() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 99, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 19, leaf1, 14, leaf2, -80); split.setDspForChild(15, leaf1); assertEquals(15, split.dspForChild(leaf1)); assertEquals(-80, split.dspForChild(leaf2)); split.setDspForChild(-60, leaf2); assertEquals(15, split.dspForChild(leaf1)); assertEquals(-60, split.dspForChild(leaf2)); } public void testDspSetForChildUnknown() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 99, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 19, leaf1, 14, leaf2, -80); CollectionLeaf leaf3 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); try { split.setDspForChild(15, leaf3); fail(); } catch (IllegalStateException e) { assertEquals("unknown child", e.getMessage()); } } // testDspSetForChild // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 20 // left: dataLeaf1 // leftDsp: 14 // right: dataLeaf2 // rightDsp: -80. // splitNode dsp: 15 forChild: dataLeaf1. // self should: [(splitNode dspForChild: dataLeaf1) = 15]. // self should: [(splitNode dspForChild: dataLeaf2) = -80]. // splitNode dsp: -60 forChild: dataLeaf2. // self should: [(splitNode dspForChild: dataLeaf1) = 15]. // self should: [(splitNode dspForChild: dataLeaf2) = -60]! // // testDuplicate // | root1 split newSplit | // root1 := self createBalanced12345678. // self assertTextContentsOf: root1 is: '12345678'. // // "operation" // split := (root1 nodeAt: 8) singleParentFor: 1. // newSplit := split duplicateFor: 2. // // self should: [split ~~ newSplit]. // self assertTextContentsOf: root1 is: '12345678'. // self should: [newSplit left == split left]. // self should: [newSplit right == split right]. // self should: [newSplit leftDsp == split leftDsp]. // self should: [newSplit rightDsp == split rightDsp]. // self should: [newSplit parents isEmpty]. // self should: [split parents size = 1]. // // // // ! // // testDuplicateAndParents // | root1 originalChild duplicateSplit root2 | // root1 := self createBalanced12345678. // root2 := RootNode // edition: nil // branch: 2 // with: root1 child // dsp: root1 dsp. // originalChild := root2 child. // self assertTextContentsOf: root1 is: '12345678'. // // "operation" // duplicateSplit := ((root1 nodeAt: 8) singleParentFor: 1) duplicateWithParentsFor: 2. // self assertTextContentsOf: root1 is: '12345678'. // self assertTextContentsOf: root2 is: '12345678'. // self should: [root2 child ~~ originalChild]. // self should: [root2 child right ~~ originalChild right]. // self should: [root2 child left == originalChild left]. // self should: [root2 child right right ~~ originalChild right right]. // self should: [root2 child right left == originalChild right left]. // self should: [root2 child right right right == originalChild right right right]. // self assertTextContentsOf: originalChild is: '12345678'! // // testDuplicateAndParentsSameRevision // | root1 originalChild duplicateSplit originalSplit | // root1 := self createBalanced12345678. // originalChild := root1 child. // self assertTextContentsOf: root1 is: '12345678'. // originalSplit := (root1 nodeAt: 8) singleParentFor: 1. // // "operation" // duplicateSplit := originalSplit duplicateWithParentsFor: 1. // self should: [duplicateSplit == originalSplit]. // self assertTextContentsOf: root1 is: '12345678'. // self should: [root1 child == originalChild]. // self should: [((root1 nodeAt: 8) singleParentFor: 1) == originalSplit]. // self should: [originalSplit parents size = 1].! // // testDuplicateBadRevision // | root1 node | // root1 := self createBalanced12345678. // self assertTextContentsOf: root1 is: '12345678'. // // "operation" // node := (root1 nodeAt: 8) singleParentFor: 1. // self should: [node duplicateFor: 0] raise: EntError.! // // testDuplicateSameRevision // | root1 split newSplit | // root1 := self createBalanced12345678. // self assertTextContentsOf: root1 is: '12345678'. // // "operation" // split := (root1 nodeAt: 8) singleParentFor: 1. // newSplit := split duplicateFor: 1. // // self should: [split == newSplit].! // public void testIsLeft() { CollectionLeaf leaf1 = new CollectionLeaf(new SequenceNumber(1), 2, AboraConverter.toAboraContent("hello ")); CollectionLeaf leaf2 = new CollectionLeaf(new SequenceNumber(1), 99, AboraConverter.toAboraContent("there")); SplitNode split = new SplitNode(new SequenceNumber(1), 19, leaf1, 14, leaf2, -80); assertTrue(split.isLeft(17)); assertTrue(split.isLeft(18)); assertFalse(split.isLeft(19)); assertFalse(split.isLeft(20)); } // testIsLeft // | dataLeaf1 dataLeaf2 splitNode | // dataLeaf1 := CollectionLeaf // branch: 1 // startPosition: 3 // elements: 'hello ' asAboraContent. // dataLeaf2 := CollectionLeaf // branch: 1 // startPosition: 100 // elements: 'there' asAboraContent. // // "test" // splitNode := SplitNode // branch: 1 // split: 20 // left: dataLeaf1 // leftDsp: 14 // right: dataLeaf2 // rightDsp: -80. // self should: [splitNode isLeft: 18]. // self should: [splitNode isLeft: 19]. // self shouldnt: [splitNode isLeft: 20]. // self shouldnt: [splitNode isLeft: 21]! // // testSingleRotateLeftDifferentForRevision // | split1 split2 root1 root2 | // split1 := SplitNode // branch: 1 // split: 2 // left: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'a' asAboraContent) // leftDsp: 1 // right: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'b' asAboraContent) // rightDsp: 2. // split2 := SplitNode // branch: 2 // split: 6 // left: split1 // leftDsp: 3 // right: (CollectionLeaf // branch: 2 // startPosition: 0 // elements: 'c' asAboraContent) // rightDsp: 6. // root1 := RootNode // edition: nil // branch: 1 // with: split1. // root2 := RootNode // edition: nil // branch: 2 // with: split2 // dsp: 4. // self should: [(root2 contentsAt: 8) = $a codePoint]. // self should: [(root2 contentsAt: 9) = $b codePoint]. // self should: [(root2 contentsAt: 10) = $c codePoint]. // self should: [(root1 contentsAt: 1) = $a codePoint]. // self should: [(root1 contentsAt: 2) = $b codePoint]. // split2 singleRotateLeftFor: 2. // "split2 should have been duplicated due to the version difference between split1 & split2" // self should: [root2 child ~~ split1]. // self should: [root2 child ~~ split2]. // self should: [root2 child right == split2]. // self should: [root1 child == split1]. // self should: [(root2 contentsAt: 8) = $a codePoint]. // self should: [(root2 contentsAt: 9) = $b codePoint]. // self should: [(root2 contentsAt: 10) = $c codePoint]. // self should: [(root1 contentsAt: 1) = $a codePoint]. // self should: [(root1 contentsAt: 2) = $b codePoint]! // // testSingleRotateLeftFor // | split1 split2 root | // split1 := SplitNode // branch: 1 // split: 2 // left: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'a' asAboraContent) // leftDsp: 1 // right: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'b' asAboraContent) // rightDsp: 2. // split2 := SplitNode // branch: 1 // split: 6 // left: split1 // leftDsp: 3 // right: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'c' asAboraContent) // rightDsp: 6. // root := RootNode // edition: nil // branch: 1 // with: split2 // dsp: 4. // self should: [(root contentsAt: 8) = $a codePoint]. // self should: [(root contentsAt: 9) = $b codePoint]. // self should: [(root contentsAt: 10) = $c codePoint]. // split2 singleRotateLeftFor: 1. // self should: [root child == split1]. // self should: [split1 right == split2]. // self should: [(root contentsAt: 8) = $a codePoint]. // self should: [(root contentsAt: 9) = $b codePoint]. // self should: [(root contentsAt: 10) = $c codePoint]! // // testSingleRotateRightFor // | split1 split2 root | // split1 := SplitNode // branch: 1 // split: -1 // left: (CollectionLeaf // branch: 1 // startPosition: -4 // elements: 'b' asAboraContent) // leftDsp: 2 // right: (CollectionLeaf // branch: 1 // startPosition: -7 // elements: 'c' asAboraContent) // rightDsp: 6. // split2 := SplitNode // branch: 1 // split: 2 // left: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'a' asAboraContent) // leftDsp: 1 // right: split1 // rightDsp: 4. // root := RootNode // edition: nil // branch: 1 // with: split2 // dsp: 5. // self should: [(root contentsAt: 6) = $a codePoint]. // self should: [(root contentsAt: 7) = $b codePoint]. // self should: [(root contentsAt: 8) = $c codePoint]. // split2 singleRotateRightFor: 1. // self should: [root child == split1]. // self should: [split1 left == split2]. // self should: [(root contentsAt: 6) = $a codePoint]. // self should: [(root contentsAt: 7) = $b codePoint]. // self should: [(root contentsAt: 8) = $c codePoint]! // // testSingleRotateRightForDifferentRevision // | split1 split2 root1 root2 | // split1 := SplitNode // branch: 1 // split: -1 // left: (CollectionLeaf // branch: 1 // startPosition: -4 // elements: 'b' asAboraContent) // leftDsp: 2 // right: (CollectionLeaf // branch: 1 // startPosition: -7 // elements: 'c' asAboraContent) // rightDsp: 6. // split2 := SplitNode // branch: 2 // split: 2 // left: (CollectionLeaf // branch: 1 // startPosition: 0 // elements: 'a' asAboraContent) // leftDsp: 1 // right: split1 // rightDsp: 4. // root1 := RootNode // edition: nil // branch: 1 // with: split1. // root2 := RootNode // edition: nil // branch: 2 // with: split2 // dsp: 5. // self should: [(root2 contentsAt: 6) = $a codePoint]. // self should: [(root2 contentsAt: 7) = $b codePoint]. // self should: [(root2 contentsAt: 8) = $c codePoint]. // self should: [(root1 contentsAt: -2) = $b codePoint]. // self should: [(root1 contentsAt: -1) = $c codePoint]. // split2 singleRotateRightFor: 2. // "split2 should have been duplicated due to the version difference between split1 & split2" // self should: [root2 child ~~ split1]. // self should: [root2 child ~~ split2]. // self should: [root2 child left == split2]. // self should: [root1 child == split1]. // self should: [(root2 contentsAt: 6) = $a codePoint]. // self should: [(root2 contentsAt: 7) = $b codePoint]. // self should: [(root2 contentsAt: 8) = $c codePoint]. // self should: [(root1 contentsAt: -2) = $b codePoint]. // self should: [(root1 contentsAt: -1) = $c codePoint]! ! // !SplitNodeTest categoriesFor: #testAssertIsChild!public! ! // !SplitNodeTest categoriesFor: #testChildren!public! ! // !SplitNodeTest categoriesFor: #testContents!public! ! // !SplitNodeTest categoriesFor: #testContentsAt!public! ! // !SplitNodeTest categoriesFor: #testContentsAtBadPosition!public! ! // !SplitNodeTest categoriesFor: #testContentsFromExtentDo!public! ! // !SplitNodeTest categoriesFor: #testCount!public! ! // !SplitNodeTest categoriesFor: #testCreate!public! ! // !SplitNodeTest categoriesFor: #testCreateDsp!public! ! // !SplitNodeTest categoriesFor: #testDspForChild!public! ! // !SplitNodeTest categoriesFor: #testDspSetForChild!public! ! // !SplitNodeTest categoriesFor: #testDuplicate!public! ! // !SplitNodeTest categoriesFor: #testDuplicateAndParents!public! ! // !SplitNodeTest categoriesFor: #testDuplicateAndParentsSameRevision!public! ! // !SplitNodeTest categoriesFor: #testDuplicateBadRevision!public! ! // !SplitNodeTest categoriesFor: #testDuplicateSameRevision!public! ! // !SplitNodeTest categoriesFor: #testIsLeft!public! ! // !SplitNodeTest categoriesFor: #testSingleRotateLeftDifferentForRevision!public! ! // !SplitNodeTest categoriesFor: #testSingleRotateLeftFor!public! ! // !SplitNodeTest categoriesFor: #testSingleRotateRightFor!public! ! // !SplitNodeTest categoriesFor: #testSingleRotateRightForDifferentRevision!public! ! // } Index: AllTests.java =================================================================== RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests/AllTests.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** AllTests.java 8 May 2003 13:53:09 -0000 1.2 --- AllTests.java 9 May 2003 13:58:47 -0000 1.3 *************** *** 22,25 **** --- 22,26 ---- suite.addTest(new TestSuite(RootNodeTest.class)); suite.addTest(new TestSuite(SequenceNumberTest.class)); + suite.addTest(new TestSuite(SplitNodeTest.class)); //$JUnit-END$ return suite; Index: CollectionLeafTest.java =================================================================== RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests/CollectionLeafTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CollectionLeafTest.java 8 May 2003 13:53:09 -0000 1.1 --- CollectionLeafTest.java 9 May 2003 13:58:47 -0000 1.2 *************** *** 7,14 **** package org.abora.ash.ent.tests; import org.abora.ash.engine.AboraConverter; import org.abora.ash.ent.CollectionLeaf; import org.abora.ash.ent.SequenceNumber; ! /** --- 7,19 ---- package org.abora.ash.ent.tests; + import java.util.List; + + import org.abora.ash.content.BeCollectionHolder; + import org.abora.ash.content.BeEdition; import org.abora.ash.engine.AboraConverter; import org.abora.ash.ent.CollectionLeaf; + import org.abora.ash.ent.RootNode; import org.abora.ash.ent.SequenceNumber; ! import org.abora.ash.space.IntegerRegion; /** *************** *** 32,35 **** --- 37,54 ---- //!CollectionLeafTest methodsFor! // + + public void testAllEditions() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 10, AboraConverter.toAboraContent("abcdef")); + BeEdition edition1 = new BeEdition(); + RootNode root1 = new RootNode(edition1, new SequenceNumber(1), leaf); + BeEdition edition2 = new BeEdition(); + RootNode root2 = new RootNode(edition2, new SequenceNumber(2), leaf); + + List allEditions = leaf.allEditions(); + assertEquals(2, allEditions.size()); + assertTrue(allEditions.contains(edition1)); + assertTrue(allEditions.contains(edition2)); + } + //testAllEditions // | leaf root1 edition1 root2 edition2 | *************** *** 52,55 **** --- 71,88 ---- // self should: [leaf allEditions includes: edition2]! // + + public void testAllRoots() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 10, AboraConverter.toAboraContent("abcdef")); + BeEdition edition1 = new BeEdition(); + RootNode root1 = new RootNode(edition1, new SequenceNumber(1), leaf); + BeEdition edition2 = new BeEdition(); + RootNode root2 = new RootNode(edition2, new SequenceNumber(2), leaf); + + List allRoots = leaf.allRoots(); + assertEquals(2, allRoots.size()); + assertTrue(allRoots.contains(root1)); + assertTrue(allRoots.contains(root2)); + } + //testAllRoots // | leaf root1 root2 | *************** *** 147,150 **** --- 180,195 ---- // self should: [out = '']! // + + public void testCount() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 10, AboraConverter.toAboraContent("hello")); + assertEquals(5, leaf.count()); + } + + public void testCountRegion() { + BeCollectionHolder holder = new BeCollectionHolder(AboraConverter.toAboraContent("Hello")); + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 10, holder, IntegerRegion.startExtent(1, 2)); + assertEquals(2, leaf.count()); + } + //testCount // | leaf | *************** *** 158,162 **** public void testCreate() { CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(3), 2, AboraConverter.toAboraContent("hello")); ! //TODO assertEquals("hello", AboraConverter.toJavaString(leaf.getElements())); assertEquals(new SequenceNumber(3), leaf.getBranch()); assertEquals(2, leaf.getStartPosition()); --- 203,207 ---- public void testCreate() { CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(3), 2, AboraConverter.toAboraContent("hello")); ! //TODO assertEquals("hello", AboraConverter.toJavaString(leaf.getElements())); assertEquals(new SequenceNumber(3), leaf.getBranch()); assertEquals(2, leaf.getStartPosition()); *************** *** 173,176 **** --- 218,232 ---- // self should: [leaf startPosition = 2]! // + + public void testDuplicateFor() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); + try { + leaf.duplicateFor(new SequenceNumber(1)); + fail(); + } catch (UnsupportedOperationException e) { + assertEquals("duplicateFor", e.getMessage()); + } + } + //testDuplicateFor // | leaf | *************** *** 311,314 **** --- 367,377 ---- // self should: [leaf isMinNodeFor: 1]! // + + public void testMaxNode() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); + assertSame(leaf, leaf.maxNode()); + } + + //testMaxNode // | leaf | *************** *** 319,322 **** --- 382,391 ---- // self should: [leaf maxNode == leaf]! // + + public void testMinNode() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); + assertSame(leaf, leaf.minNode()); + } + //testMinNode // | leaf | *************** *** 560,563 **** --- 629,661 ---- // self should: [leaf parents = (OrderedCollection with: root)]! // + + public void testSplitAboutBadAbout() { + CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); + try { + leaf.splitAbout(1, -1); + fail("-1"); + } catch (IndexOutOfBoundsException e) { + assertEquals("-1", e.getMessage()); + } + try { + leaf.splitAbout(1, 0); + fail("0"); + } catch (IndexOutOfBoundsException e) { + assertEquals("0", e.getMessage()); + } + try { + leaf.splitAbout(1, 5); + fail("5"); + } catch (IndexOutOfBoundsException e) { + assertEquals("5", e.getMessage()); + } + try { + leaf.splitAbout(1, 6); + fail("6"); + } catch (IndexOutOfBoundsException e) { + assertEquals("6", e.getMessage()); + } + } + //testSplitAboutBadAbout // | root leaf splitNode | |
|
From: <dg...@us...> - 2003-05-09 13:58:50
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent
In directory sc8-pr-cvs1:/tmp/cvs-serv2145/src/org/abora/ash/ent
Modified Files:
SplitNode.java CollectionLeaf.java
Log Message:
-Start split node testing
Index: SplitNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/SplitNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** SplitNode.java 8 May 2003 13:53:09 -0000 1.2
--- SplitNode.java 9 May 2003 13:58:47 -0000 1.3
***************
*** 143,147 ****
}
! protected void setDspForChild(int dsp, EntNode node) {
assertIsChild(node);
if (left == node) {
--- 143,147 ----
}
! public void setDspForChild(int dsp, EntNode node) {
assertIsChild(node);
if (left == node) {
***************
*** 158,162 ****
//
! protected int dspForChild(EntNode node) {
if (left == node) {
return getLeftDsp();
--- 158,162 ----
//
! public int dspForChild(EntNode node) {
if (left == node) {
return getLeftDsp();
***************
*** 224,227 ****
--- 224,232 ----
// ^dsp negated!
//
+
+ public boolean isLeft(int position) {
+ return position < getSplit();
+ }
+
// isLeft: position
// ^position < self split!
Index: CollectionLeaf.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/CollectionLeaf.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** CollectionLeaf.java 8 May 2003 13:53:09 -0000 1.2
--- CollectionLeaf.java 9 May 2003 13:58:47 -0000 1.3
***************
*** 111,115 ****
//
! protected SplitNode splitAbout(int newSplit, int elementsPosition) {
if (elementsPosition < 1 || elementsPosition >= count()) {
throw new IndexOutOfBoundsException(String.valueOf(elementsPosition));
--- 111,115 ----
//
! public SplitNode splitAbout(int newSplit, int elementsPosition) {
if (elementsPosition < 1 || elementsPosition >= count()) {
throw new IndexOutOfBoundsException(String.valueOf(elementsPosition));
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent
In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/ent
Modified Files:
EntException.java ContentLeaf.java EntNode.java
CollectionLeaf.java SplitNode.java LeafNode.java
ChildNode.java RootNode.java
Log Message:
-STart leaf tests
Index: EntException.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/EntException.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** EntException.java 4 May 2003 18:32:06 -0000 1.1
--- EntException.java 8 May 2003 13:53:08 -0000 1.2
***************
*** 7,15 ****
package org.abora.ash.ent;
- import org.abora.ash.engine.AboraException;
/**
*/
! public class EntException extends AboraException {
/**
--- 7,14 ----
package org.abora.ash.ent;
/**
*/
! public class EntException extends RuntimeException {
/**
Index: ContentLeaf.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/ContentLeaf.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** ContentLeaf.java 4 May 2003 18:32:06 -0000 1.1
--- ContentLeaf.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 27,33 ****
--- 27,49 ----
// !ContentLeaf methodsFor!
//
+
+ public BeContentElement getContentElement() {
+ return contentElement;
+ }
+
// contentElement
// ^contentElement!
//
+
+ private void setContentElement(BeContentElement contentElement) {
+ if (this.contentElement != null) {
+ this.contentElement.removeParent(this);
+ }
+ this.contentElement = contentElement;
+ if (contentElement != null) {
+ contentElement.addParent(this);
+ }
+ }
+
// contentElement: aContentElement
// contentElement notNil ifTrue: [contentElement removeParent: self].
***************
*** 88,91 ****
--- 104,112 ----
// mappings add: (Array with: globalRegion with: anotherRegion)]]!
//
+
+ public SplitNode splitAbout(int newSplit, int elementsPosition) {
+ throw new UnsupportedOperationException("should not implement");
+ }
+
// split: newSplit about: elementsPosition
// "Private - Answer a new SplitNode with two data children with elements before and equal and after elementsPosition."
***************
*** 125,129 ****
public ContentLeaf(SequenceNumber branch, int startPosition, BeContentElement contentElement) {
super(branch, startPosition);
! this.contentElement = contentElement;
}
--- 146,150 ----
public ContentLeaf(SequenceNumber branch, int startPosition, BeContentElement contentElement) {
super(branch, startPosition);
! setContentElement(contentElement);
}
Index: EntNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/EntNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** EntNode.java 4 May 2003 18:32:06 -0000 1.1
--- EntNode.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 7,10 ****
--- 7,11 ----
package org.abora.ash.ent;
+ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
***************
*** 23,29 ****
--- 24,47 ----
protected abstract void addToParent(EntNode node);
+ public List allEditions() {
+ List roots = allRoots();
+ List editions = new ArrayList(roots.size());
+ for (Iterator iter = roots.iterator(); iter.hasNext();) {
+ RootNode root = (RootNode) iter.next();
+ editions.add(root.getEdition());
+ }
+ return editions;
+ }
+
// allEditions
// ^self allRoots collect: [:root | root edition]!
//
+
+ public List allRoots() {
+ List roots = new ArrayList();
+ allRoots(roots);
+ return roots;
+ }
+
// allRoots
// | roots |
***************
*** 32,40 ****
// ^roots!
//
// allRoots: allRoots
// self parents do: [:parent | parent allRoots: allRoots]!
//
! protected EntNode basicParentSplit() {
return null;
}
--- 50,66 ----
// ^roots!
//
+
+ protected void allRoots(List allRoots) {
+ for (Iterator iter = getParents().iterator(); iter.hasNext();) {
+ EntNode node = (EntNode) iter.next();
+ node.allRoots(allRoots);
+ }
+ }
+
// allRoots: allRoots
// self parents do: [:parent | parent allRoots: allRoots]!
//
! protected SplitNode basicParentSplit() {
return null;
}
***************
*** 43,46 ****
--- 69,75 ----
// ^nil!
//
+
+ protected abstract EntNode basicSplayFor(SequenceNumber matchingBranch);
+
public SequenceNumber getBranch() {
return branch;
***************
*** 54,58 ****
//
! protected abstract List children();
// children
--- 83,87 ----
//
! public abstract List children();
// children
***************
*** 88,92 ****
protected abstract void setDspForChild(int dsp, EntNode child);
! protected abstract EntNode duplicateFor(SequenceNumber newBranch) throws EntException;
// duplicateFor: newBranch
--- 117,121 ----
protected abstract void setDspForChild(int dsp, EntNode child);
! public abstract EntNode duplicateFor(SequenceNumber newBranch) throws EntException;
// duplicateFor: newBranch
***************
*** 150,153 ****
--- 179,185 ----
// ^singleParent!
//
+
+ public abstract void insertLeaf(LeafNode leaf, int position, RootNode root);
+
protected boolean isCompatibleFor(SequenceNumber matchingBranch) {
return branch.isBranchingBeforeOrEqual(matchingBranch);
***************
*** 182,190 ****
//
! protected abstract List getParents();
// parents
// self subclassResponsibility!
//
// parentSplit: matchingBranch
// | parent |
--- 214,232 ----
//
! public abstract List getParents();
// parents
// self subclassResponsibility!
//
+
+ protected SplitNode parentSplit(SequenceNumber matchingBranch) {
+ EntNode parent = singleParentFor(matchingBranch);
+ if (parent != null) {
+ return parent.basicParentSplit();
+ } else {
+ return null;
+ }
+ }
+
// parentSplit: matchingBranch
// | parent |
Index: CollectionLeaf.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/CollectionLeaf.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** CollectionLeaf.java 4 May 2003 18:32:06 -0000 1.1
--- CollectionLeaf.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 17,24 ****
protected IntegerRegion collectionRegion;
- public CollectionLeaf(SequenceNumber branch, int startPosition, byte[] contents) {
- super(branch, startPosition);
- //@todo
- }
// "Filed out from Dolphin Smalltalk 2002 release 5.00"!
//
--- 17,20 ----
***************
*** 114,117 ****
--- 110,123 ----
// mappings add: (Array with: selfRegion with: anotherRegion)]]]!
//
+
+ protected SplitNode splitAbout(int newSplit, int elementsPosition) {
+ if (elementsPosition < 1 || elementsPosition >= count()) {
+ throw new IndexOutOfBoundsException(String.valueOf(elementsPosition));
+ }
+ CollectionLeaf left = new CollectionLeaf(getBranch(), getStartPosition(), collectionHolder, IntegerRegion.startEnd(collectionRegion.getStartPosition(), collectionRegion.getStartPosition()+elementsPosition-1));
+ CollectionLeaf right = new CollectionLeaf(getBranch(), getStartPosition() + elementsPosition - 1, collectionHolder, IntegerRegion.startEnd(collectionRegion.getStartPosition() + elementsPosition - 1, collectionRegion.getEndPosition()));
+ return new SplitNode(getBranch(), newSplit, left, right);
+ }
+
// split: newSplit about: elementsPosition
// "Private - Answer a new SplitNode with two data children with elements before and equal and after elementsPosition."
***************
*** 174,177 ****
--- 180,192 ----
// !CollectionLeaf class methodsFor!
//
+
+ public CollectionLeaf(SequenceNumber branch, int startPosition, byte[] contents) {
+ this(branch, startPosition, new BeCollectionHolder(contents));
+ }
+
+ public CollectionLeaf(SequenceNumber branch, int startPosition, BeCollectionHolder dataCollection) {
+ this(branch, startPosition, dataCollection, IntegerRegion.startExtent(1, dataCollection.count()));
+ }
+
// branch: branch startPosition: startPosition collection: dataCollection
// ^self
***************
*** 181,184 ****
--- 196,206 ----
// region: (IntegerRegion startPosition: 1 endPosition: dataCollection collection size)!
//
+
+ public CollectionLeaf(SequenceNumber branch, int startPosition, BeCollectionHolder collectionHolder, IntegerRegion collectionRegion) {
+ super(branch, startPosition);
+ this.collectionHolder = collectionHolder;
+ this.collectionRegion = collectionRegion;
+ }
+
// branch: branch startPosition: startPosition collection: dataCollection region: collectionRegion
// ^(self basicNew)
Index: SplitNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/SplitNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** SplitNode.java 4 May 2003 18:32:06 -0000 1.1
--- SplitNode.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 8,11 ****
--- 8,12 ----
import java.util.ArrayList;
+ import java.util.Iterator;
import java.util.List;
***************
*** 40,44 ****
return position + invertDsp(dsp);
}
[...984 lines suppressed...]
! // !SplitNode categoriesFor: #leftDsp:!accessing!private! !
! // !SplitNode categoriesFor: #nodeAt:!public! !
! // !SplitNode categoriesFor: #removeChild:branch:!public! !
! // !SplitNode categoriesFor: #removeChildLeft!private! !
! // !SplitNode categoriesFor: #removeChildLeftFromRoot!private! !
! // !SplitNode categoriesFor: #removeChildRightMaxElement!private! !
! // !SplitNode categoriesFor: #replaceChild:with:!public! !
! // !SplitNode categoriesFor: #right!accessing!private! !
! // !SplitNode categoriesFor: #right:!accessing!private! !
! // !SplitNode categoriesFor: #rightDsp!accessing!private! !
! // !SplitNode categoriesFor: #rightDsp:!accessing!private! !
! // !SplitNode categoriesFor: #singleRotateLeftFor:!private! !
! // !SplitNode categoriesFor: #singleRotateRightFor:!private! !
! // !SplitNode categoriesFor: #split!accessing!private! !
! // !SplitNode categoriesFor: #split:!accessing!private! !
! // !SplitNode categoriesFor: #transclusionsFrom:extent:found:!accessing!public! !
! //
! //
! //
}
Index: LeafNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/LeafNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** LeafNode.java 4 May 2003 18:32:06 -0000 1.1
--- LeafNode.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 7,11 ****
--- 7,13 ----
package org.abora.ash.ent;
+ import java.util.ArrayList;
import java.util.Collections;
+ import java.util.Iterator;
import java.util.List;
***************
*** 14,288 ****
public abstract class LeafNode extends ChildNode {
protected int startPosition = 0;
!
protected LeafNode(SequenceNumber branch, int startPosition) {
super(branch);
this.startPosition = startPosition;
}
-
- // "Filed out from Dolphin Smalltalk 2002 release 5.00"!
- //
- // ChildNode subclass: #LeafNode
- // instanceVariableNames: 'startPosition'
- // classVariableNames: ''
- // poolDictionaries: ''
- // classInstanceVariableNames: ''!
- // LeafNode guid: (GUID fromString: '{F64D0B1E-54DA-4D5C-97C8-665909D3718D}')!
- // LeafNode comment: ''!
- // !LeafNode categoriesForClass!Kernel-Objects! !
- // !LeafNode methodsFor!
- //
- // basicInsert: dataLeaf at: position root: root
- // | index |
- // index := position - startPosition + 1.
- // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position].
- // index = 1
- // ifTrue:
- // ["insert before"
- //
- // (self isMinNodeFor: root branch)
- // ifTrue: [self basicInsertBeforeEnt: dataLeaf root: root]
- // ifFalse:
- // [^self
- // basicInsertBeforeSelf: dataLeaf
- // at: position
- // root: root]]
- // ifFalse:
- // [index <= self count
- // ifTrue:
- // ["split then insert"
- //
- // | splitNode |
- // splitNode := self replaceWithSplit: position about: index.
- // ^splitNode right
- // insert: dataLeaf
- // at: position
- // root: root]
- // ifFalse:
- // [(self isMaxNodeFor: root branch)
- // ifTrue: [self basicInsertAfterEnt: dataLeaf root: root]
- // ifFalse: [self errorSubscriptBounds: position]]]!
- //
- // basicInsertAfterEnt: dataLeaf root: root
- // "add to end of entire ent"
- //
- // | splitNode |
- // splitNode := SplitNode
- // branch: root branch
- // split: dataLeaf startPosition
- // left: root child
- // leftDsp: root dsp
- // right: dataLeaf.
- // root child: splitNode.
- // root dsp: 0!
- //
- // basicInsertBeforeEnt: dataLeaf root: root
- // "add to beginning of entire ent"
- //
- // | splitNode |
- // splitNode := SplitNode
- // branch: root branch
- // split: dataLeaf count + dataLeaf startPosition
- // left: dataLeaf
- // right: root child
- // rightDsp: dataLeaf count + root dsp.
- // root child: splitNode.
- // root dsp: 0!
- //
- // basicInsertBeforeSelf: dataLeaf at: position root: root
- // "add before self"
- //
- // | parent newBranch |
- // newBranch := root branch.
- // parent := self parentSplit: newBranch.
- // self assert: [parent notNil].
- // self assert: [parent left == self or: [parent right == self]].
- // (parent left == self or: [(parent parentSplit: newBranch) isNil])
- // ifTrue:
- // [| a b |
- // (root child isSameFor: newBranch) ifTrue: [root child right removeFromParent: root child].
- // a := SplitNode
- // branch: newBranch
- // split: dataLeaf startPosition + dataLeaf count
- // left: dataLeaf
- // right: root child right
- // rightDsp: dataLeaf count + root child rightDsp + root dsp.
- // (root child isSameFor: newBranch) ifTrue: [root child left removeFromParent: root child].
- // b := SplitNode
- // branch: newBranch
- // split: dataLeaf startPosition
- // left: root child left
- // leftDsp: root child leftDsp + root dsp
- // right: a.
- // root child: b.
- // root dsp: 0]
- // ifFalse:
- // ["Force self to other side of parent by splaying"
- //
- // parent basicSplayFor: newBranch.
- // ^self
- // basicInsert: dataLeaf
- // at: position
- // root: root]!
- //
- // basicSplayFor: matchingBranch
- // ^(self singleParentFor: matchingBranch) basicSplayFor: matchingBranch!
- //
- // children
- // ^#()
- // !
! public List children() {
! return Collections.EMPTY_LIST;
! }
! //
! // constrainedIndexFrom: position
! // | index |
! // index := position - self startPosition + 1.
! // (index < 1 or: [index > self count]) ifTrue: [self errorSubscriptBounds: index].
! // ^index!
! //
! // contents
! // ^self contentsFrom: self startPosition extent: self count!
! //
! // contentsAt: position
! // | index |
! // index := self constrainedIndexFrom: position.
! // ^self contentsAtConstrainedIndex: index!
! //
! // contentsAtConstrainedIndex: index
! // self subclassResponsibility!
! //
! // duplicateFor: newBranch
! // self shouldNotImplement!
! public EntNode duplicateFor(SequenceNumber newBranch) {
! throw new UnsupportedOperationException("duplicateFor");
!
! }
! //
! // firstNodeFrom: position extent: extent shouldSplit: shouldSplit
! // | index |
! // index := self constrainedIndexFrom: position.
! // shouldSplit ifFalse: [^self].
! // ^index > 1
! // ifTrue:
! // [| newParent |
! // newParent := self replaceWithSplit: position about: index.
! // newParent right
! // firstNodeFrom: position
! // extent: extent
! // shouldSplit: shouldSplit]
! // ifFalse:
! // [extent < self count
! // ifTrue:
! // [| newParent |
! // newParent := self replaceWithSplit: position + extent about: extent + 1.
! // newParent left]
! // ifFalse: [self]]!
! //
! // globalPositionFor: matchingBranch
! // ^self globalPositionFor: matchingBranch to: nil!
! //
! // globalPositionFor: matchingBranch to: topParent
! // | position node parent |
! // position := self startPosition.
! // node := self.
! // [(parent := node singleParentFor: matchingBranch) ~~ topParent] whileTrue:
! // [position := position + (parent dspForChild: node).
! // node := parent].
! // ^position!
! //
! // globalRegionFor: forBranch
! // ^IntegerRegion startPosition: (self globalPositionFor: forBranch) extent: self count!
! //
! // insert: dataLeaf at: position root: root
! // | index |
! // index := position - startPosition + 1.
! // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position].
! // self basicSplayFor: root branch.
! // self
! // basicInsert: dataLeaf
! // at: position
! // root: root!
! //
! // isMaxNodeFor: matchingBranch
! // | node parent |
! // node := self.
! // [(parent := node parentSplit: matchingBranch) notNil] whileTrue:
! // [parent right == node ifFalse: [^false].
! // node := parent].
! // ^true!
! //
! // isMinNodeFor: matchingBranch
! // | node parent |
! // node := self.
! // [(parent := node parentSplit: matchingBranch) notNil] whileTrue:
! // [parent left == node ifFalse: [^false].
! // node := parent].
! // ^true!
! //
! // maxNode
! // ^self!
! //
! // minNode
! // ^self!
! //
! // nodeAt: position
! // | index |
! // index := self constrainedIndexFrom: position.
! // ^self!
! //
! // removeFor: newBranch
! // self basicSplayFor: newBranch.
! // (self singleParentFor: newBranch) removeChild: self branch: newBranch!
! //
! // replaceWithSplit: newSplit about: elementsPosition
! // "Answer a new SplitNode with two data children with elements before and equal and after elementsPosition.
! // NOTE: This operation is unusual in that all parent versions are redirected to point to the replacement split node."
! //
! // | splitNode |
! // splitNode := self split: newSplit about: elementsPosition.
! // self parents do: [:parent | parent replaceChild: self with: splitNode].
! // self assert: [self parents isEmpty].
! // ^splitNode!
! //
! // split: newSplit about: elementsPosition
! // self subclassResponsibility!
! //
! // startPosition
! // ^startPosition!
! //
! // startPosition: anObject
! // startPosition := anObject! !
! // !LeafNode categoriesFor: #basicInsert:at:root:!private! !
! // !LeafNode categoriesFor: #basicInsertAfterEnt:root:!private! !
! // !LeafNode categoriesFor: #basicInsertBeforeEnt:root:!private! !
! // !LeafNode categoriesFor: #basicInsertBeforeSelf:at:root:!private! !
! // !LeafNode categoriesFor: #basicSplayFor:!private! !
! // !LeafNode categoriesFor: #children!public! !
! // !LeafNode categoriesFor: #constrainedIndexFrom:!private! !
! // !LeafNode categoriesFor: #contents!public! !
! // !LeafNode categoriesFor: #contentsAt:!public! !
! // !LeafNode categoriesFor: #contentsAtConstrainedIndex:!public! !
! // !LeafNode categoriesFor: #duplicateFor:!public! !
! // !LeafNode categoriesFor: #firstNodeFrom:extent:shouldSplit:!public! !
! // !LeafNode categoriesFor: #globalPositionFor:!public! !
! // !LeafNode categoriesFor: #globalPositionFor:to:!private! !
! // !LeafNode categoriesFor: #globalRegionFor:!public! !
! // !LeafNode categoriesFor: #insert:at:root:!public! !
! // !LeafNode categoriesFor: #isMaxNodeFor:!public! !
! // !LeafNode categoriesFor: #isMinNodeFor:!public! !
! // !LeafNode categoriesFor: #maxNode!public! !
! // !LeafNode categoriesFor: #minNode!public! !
! // !LeafNode categoriesFor: #nodeAt:!public! !
! // !LeafNode categoriesFor: #removeFor:!public! !
! // !LeafNode categoriesFor: #replaceWithSplit:about:!public! !
! // !LeafNode categoriesFor: #split:about:!public! !
! // !LeafNode categoriesFor: #startPosition!accessing!private! !
! // !LeafNode categoriesFor: #startPosition:!accessing!private! !
! //
! //
! //
protected void replaceChild(EntNode existingChild, EntNode newChild) {
throw new UnsupportedOperationException("no children");
--- 16,436 ----
public abstract class LeafNode extends ChildNode {
protected int startPosition = 0;
!
protected LeafNode(SequenceNumber branch, int startPosition) {
super(branch);
this.startPosition = startPosition;
}
! // "Filed out from Dolphin Smalltalk 2002 release 5.00"!
! //
! // ChildNode subclass: #LeafNode
! // instanceVariableNames: 'startPosition'
! // classVariableNames: ''
! // poolDictionaries: ''
! // classInstanceVariableNames: ''!
! // LeafNode guid: (GUID fromString: '{F64D0B1E-54DA-4D5C-97C8-665909D3718D}')!
! // LeafNode comment: ''!
! // !LeafNode categoriesForClass!Kernel-Objects! !
! // !LeafNode methodsFor!
! //
! protected void basicInsertChild(LeafNode leaf, int position, RootNode root) {
! int index = position - startPosition + 1;
! if (index < 0 || index > count()) {
! throw new IndexOutOfBoundsException(String.valueOf(position));
! }
! if (index == 0) {
! // Insert before
! if (isMinNodeFor(root.getBranch())) {
! basicInsertBeforeEnt(leaf, root);
! } else {
! basicInsertBeforeSelf(leaf, position, root);
! }
! } else {
! if (index < count()) {
! //TODO split then insert
! SplitNode splitNode = replaceWithSplit(position, index);
! splitNode.getRight().insertLeaf(leaf, position, root);
! } else {
! if (isMaxNodeFor(root.getBranch())) {
! basicInsertAfterEnt(leaf, root);
! } else {
! throw new IndexOutOfBoundsException(String.valueOf(position));
! }
! }
! }
! }
! // basicInsert: dataLeaf at: position root: root
! // | index |
! // index := position - startPosition + 1.
! // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position].
! // index = 1
! // ifTrue:
! // ["insert before"
! //
! // (self isMinNodeFor: root branch)
! // ifTrue: [self basicInsertBeforeEnt: dataLeaf root: root]
! // ifFalse:
! // [^self
! // basicInsertBeforeSelf: dataLeaf
! // at: position
! // root: root]]
! // ifFalse:
! // [index <= self count
! // ifTrue:
! // ["split then insert"
! //
! // | splitNode |
! // splitNode := self replaceWithSplit: position about: index.
! // ^splitNode right
! // insert: dataLeaf
! // at: position
! // root: root]
! // ifFalse:
! // [(self isMaxNodeFor: root branch)
! // ifTrue: [self basicInsertAfterEnt: dataLeaf root: root]
! // ifFalse: [self errorSubscriptBounds: position]]]!
! //
!
! protected void basicInsertAfterEnt(LeafNode leaf, RootNode root) {
! SplitNode splitNode = new SplitNode(root.getBranch(), leaf.getStartPosition(), root.getChild(), root.getDsp(), leaf);
! root.setChild(splitNode);
! root.setDspForChild(0, splitNode);
! }
!
! // basicInsertAfterEnt: dataLeaf root: root
! // "add to end of entire ent"
! //
! // | splitNode |
! // splitNode := SplitNode
! // branch: root branch
! // split: dataLeaf startPosition
! // left: root child
! // leftDsp: root dsp
! // right: dataLeaf.
! // root child: splitNode.
! // root dsp: 0!
! //
!
! protected void basicInsertBeforeEnt(LeafNode leaf, RootNode root) {
! SplitNode splitNode =
! new SplitNode(root.getBranch(), leaf.count() + leaf.getStartPosition(), leaf, root.getChild(), leaf.count() + root.getDsp());
! root.setChild(splitNode);
! root.setDspForChild(0, splitNode);
! }
!
! // basicInsertBeforeEnt: dataLeaf root: root
! // "add to beginning of entire ent"
! //
! // | splitNode |
! // splitNode := SplitNode
! // branch: root branch
! // split: dataLeaf count + dataLeaf startPosition
! // left: dataLeaf
! // right: root child
! // rightDsp: dataLeaf count + root dsp.
! // root child: splitNode.
! // root dsp: 0!
! //
!
! protected void basicInsertBeforeSelf(LeafNode leaf, int position, RootNode root) {
! SequenceNumber newBranch = root.getBranch();
! SplitNode parent = parentSplit(newBranch);
! assert parent != null;
! assert parent.getLeft() == this || parent.getRight() == this;
! if (parent.getLeft() == this || parent.parentSplit(newBranch) == null) {
! SplitNode rootChild = (SplitNode) root.getChild();
! if (rootChild.isSameFor(newBranch)) {
! rootChild.getRight().removeFromParent(rootChild);
! }
! SplitNode a =
! new SplitNode(
! newBranch,
! leaf.getStartPosition() + leaf.count(),
! leaf,
! rootChild.getRight(),
! leaf.count() + rootChild.getRightDsp() + root.getDsp());
! if (rootChild.isSameFor(newBranch)) {
! rootChild.getLeft().removeFromParent(root.getChild());
! }
! SplitNode b = new SplitNode(newBranch, leaf.getStartPosition(), rootChild.getLeft(), rootChild.getLeftDsp() + root.getDsp(), a);
! root.setChild(b);
! root.setDsp(0);
! } else {
! // Force self to other side of parent by re-splaying
! parent.basicSplayFor(newBranch);
! basicInsertChild(leaf, position, root);
! }
! }
!
! // basicInsertBeforeSelf: dataLeaf at: position root: root
! // "add before self"
! //
! // | parent newBranch |
! // newBranch := root branch.
! // parent := self parentSplit: newBranch.
! // self assert: [parent notNil].
! // self assert: [parent left == self or: [parent right == self]].
! // (parent left == self or: [(parent parentSplit: newBranch) isNil])
! // ifTrue:
! // [| a b |
! // (root child isSameFor: newBranch) ifTrue: [root child right removeFromParent: root child].
! // a := SplitNode
! // branch: newBranch
! // split: dataLeaf startPosition + dataLeaf count
! // left: dataLeaf
! // right: root child right
! // rightDsp: dataLeaf count + root child rightDsp + root dsp.
! // (root child isSameFor: newBranch) ifTrue: [root child left removeFromParent: root child].
! // b := SplitNode
! // branch: newBranch
! // split: dataLeaf startPosition
! // left: root child left
! // leftDsp: root child leftDsp + root dsp
! // right: a.
! // root child: b.
! // root dsp: 0]
! // ifFalse:
! // ["Force self to other side of parent by splaying"
! //
! // parent basicSplayFor: newBranch.
! // ^self
! // basicInsert: dataLeaf
! // at: position
! // root: root]!
! //
!
! protected EntNode basicSplayFor(SequenceNumber matchingBranch) {
! return singleParentFor(matchingBranch).basicSplayFor(matchingBranch);
! }
!
! // basicSplayFor: matchingBranch
! // ^(self singleParentFor: matchingBranch) basicSplayFor: matchingBranch!
! //
!
! public List children() {
! return Collections.EMPTY_LIST;
! }
!
! // children
! // ^#()
! // !
! //
! // constrainedIndexFrom: position
! // | index |
! // index := position - self startPosition + 1.
! // (index < 1 or: [index > self count]) ifTrue: [self errorSubscriptBounds: index].
! // ^index!
! //
! // contents
! // ^self contentsFrom: self startPosition extent: self count!
! //
! // contentsAt: position
! // | index |
! // index := self constrainedIndexFrom: position.
! // ^self contentsAtConstrainedIndex: index!
! //
! // contentsAtConstrainedIndex: index
! // self subclassResponsibility!
! //
!
! public EntNode duplicateFor(SequenceNumber newBranch) {
! throw new UnsupportedOperationException("duplicateFor");
!
! }
!
! // duplicateFor: newBranch
! // self shouldNotImplement!
! //
! // firstNodeFrom: position extent: extent shouldSplit: shouldSplit
! // | index |
! // index := self constrainedIndexFrom: position.
! // shouldSplit ifFalse: [^self].
! // ^index > 1
! // ifTrue:
! // [| newParent |
! // newParent := self replaceWithSplit: position about: index.
! // newParent right
! // firstNodeFrom: position
! // extent: extent
! // shouldSplit: shouldSplit]
! // ifFalse:
! // [extent < self count
! // ifTrue:
! // [| newParent |
! // newParent := self replaceWithSplit: position + extent about: extent + 1.
! // newParent left]
! // ifFalse: [self]]!
! //
! // globalPositionFor: matchingBranch
! // ^self globalPositionFor: matchingBranch to: nil!
! //
! // globalPositionFor: matchingBranch to: topParent
! // | position node parent |
! // position := self startPosition.
! // node := self.
! // [(parent := node singleParentFor: matchingBranch) ~~ topParent] whileTrue:
! // [position := position + (parent dspForChild: node).
! // node := parent].
! // ^position!
! //
! // globalRegionFor: forBranch
! // ^IntegerRegion startPosition: (self globalPositionFor: forBranch) extent: self count!
! //
!
! public void insertLeaf(LeafNode leaf, int position, RootNode root) {
! int index = position - startPosition + 1;
! if (index < 0 || index > count()) {
! throw new IndexOutOfBoundsException(String.valueOf(position));
! }
! basicSplayFor(root.getBranch());
! basicInsertChild(leaf, position, root);
! }
!
! // insert: dataLeaf at: position root: root
! // | index |
! // index := position - startPosition + 1.
! // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position].
! // self basicSplayFor: root branch.
! // self
! // basicInsert: dataLeaf
! // at: position
! // root: root!
! //
!
! public boolean isMaxNodeFor(SequenceNumber matchingBranch) {
! EntNode node = this;
! SplitNode splitParent;
! while ((splitParent = node.parentSplit(matchingBranch)) != null) {
! if (splitParent.getRight() != node) {
! return false;
! }
! node = splitParent;
! }
! return true;
! }
!
! // isMaxNodeFor: matchingBranch
! // | node parent |
! // node := self.
! // [(parent := node parentSplit: matchingBranch) notNil] whileTrue:
! // [parent right == node ifFalse: [^false].
! // node := parent].
! // ^true!
! //
!
! public boolean isMinNodeFor(SequenceNumber matchingBranch) {
! EntNode node = this;
! SplitNode splitParent;
! while ((splitParent = node.parentSplit(matchingBranch)) != null) {
! if (splitParent.getLeft() != node) {
! return false;
! }
! node = splitParent;
! }
! return true;
! }
!
! // isMinNodeFor: matchingBranch
! // | node parent |
! // node := self.
! // [(parent := node parentSplit: matchingBranch) notNil] whileTrue:
! // [parent left == node ifFalse: [^false].
! // node := parent].
! // ^true!
! //
!
! public EntNode maxNode() {
! return this;
! }
!
! // maxNode
! // ^self!
! //
!
! public EntNode minNode() {
! return this;
! }
!
! // minNode
! // ^self!
! //
! // nodeAt: position
! // | index |
! // index := self constrainedIndexFrom: position.
! // ^self!
! //
! // removeFor: newBranch
! // self basicSplayFor: newBranch.
! // (self singleParentFor: newBranch) removeChild: self branch: newBranch!
! //
!
! protected SplitNode replaceWithSplit(int newSplit, int elementsPosition) {
! SplitNode splitNode = splitAbout(newSplit, elementsPosition);
! List parentsCopy = new ArrayList(getParents());
! for (Iterator iter = parentsCopy.iterator(); iter.hasNext();) {
! EntNode parent = (EntNode) iter.next();
! parent.replaceChild(this, splitNode);
! }
! assert getParents().isEmpty();
! return splitNode;
! }
!
! // replaceWithSplit: newSplit about: elementsPosition
! // "Answer a new SplitNode with two data children with elements before and equal and after elementsPosition.
! // NOTE: This operation is unusual in that all parent versions are redirected to point to the replacement split node."
! //
! // | splitNode |
! // splitNode := self split: newSplit about: elementsPosition.
! // self parents do: [:parent | parent replaceChild: self with: splitNode].
! // self assert: [self parents isEmpty].
! // ^splitNode!
! //
!
! protected abstract SplitNode splitAbout(int newSplit, int elementsPosition);
!
! // split: newSplit about: elementsPosition
! // self subclassResponsibility!
! //
!
! public int getStartPosition() {
! return startPosition;
! }
!
! // startPosition
! // ^startPosition!
! //
! // startPosition: anObject
! // startPosition := anObject! !
! // !LeafNode categoriesFor: #basicInsert:at:root:!private! !
! // !LeafNode categoriesFor: #basicInsertAfterEnt:root:!private! !
! // !LeafNode categoriesFor: #basicInsertBeforeEnt:root:!private! !
! // !LeafNode categoriesFor: #basicInsertBeforeSelf:at:root:!private! !
! // !LeafNode categoriesFor: #basicSplayFor:!private! !
! // !LeafNode categoriesFor: #children!public! !
! // !LeafNode categoriesFor: #constrainedIndexFrom:!private! !
! // !LeafNode categoriesFor: #contents!public! !
! // !LeafNode categoriesFor: #contentsAt:!public! !
! // !LeafNode categoriesFor: #contentsAtConstrainedIndex:!public! !
! // !LeafNode categoriesFor: #duplicateFor:!public! !
! // !LeafNode categoriesFor: #firstNodeFrom:extent:shouldSplit:!public! !
! // !LeafNode categoriesFor: #globalPositionFor:!public! !
! // !LeafNode categoriesFor: #globalPositionFor:to:!private! !
! // !LeafNode categoriesFor: #globalRegionFor:!public! !
! // !LeafNode categoriesFor: #insert:at:root:!public! !
! // !LeafNode categoriesFor: #isMaxNodeFor:!public! !
! // !LeafNode categoriesFor: #isMinNodeFor:!public! !
! // !LeafNode categoriesFor: #maxNode!public! !
! // !LeafNode categoriesFor: #minNode!public! !
! // !LeafNode categoriesFor: #nodeAt:!public! !
! // !LeafNode categoriesFor: #removeFor:!public! !
! // !LeafNode categoriesFor: #replaceWithSplit:about:!public! !
! // !LeafNode categoriesFor: #split:about:!public! !
! // !LeafNode categoriesFor: #startPosition!accessing!private! !
! // !LeafNode categoriesFor: #startPosition:!accessing!private! !
! //
! //
! //
protected void replaceChild(EntNode existingChild, EntNode newChild) {
throw new UnsupportedOperationException("no children");
Index: ChildNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/ChildNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** ChildNode.java 4 May 2003 18:32:06 -0000 1.1
--- ChildNode.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 26,30 ****
parents.remove(node);
}
! protected List getParents() {
return parents;
}
--- 26,30 ----
parents.remove(node);
}
! public List getParents() {
return parents;
}
Index: RootNode.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/RootNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** RootNode.java 4 May 2003 18:32:06 -0000 1.1
--- RootNode.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 25,44 ****
}
public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child) {
! super(branch);
! this.edition = edition;
! this.child = child;
}
public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child, int dsp) {
super(branch);
this.edition = edition;
- this.child = child;
this.dsp = dsp;
}
// allRoots: allRoots
// allRoots add: self!
//
// applyDspTo: position
// | dspPosition |
--- 25,50 ----
}
public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child) {
! this(edition, branch, child, 0);
}
public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child, int dsp) {
super(branch);
this.edition = edition;
this.dsp = dsp;
+ setChild(child);
}
+ protected void allRoots(List allRoots) {
+ allRoots.add(this);
+ }
// allRoots: allRoots
// allRoots add: self!
//
+
+ protected int applyDspTo(int position) {
+ return position + invertDsp();
+ }
+
// applyDspTo: position
// | dspPosition |
***************
*** 56,59 ****
--- 62,72 ----
// self child ~~ node ifTrue: [EntError signal: 'unknown child of root']!
//
+
+ protected EntNode basicSplayFor(SequenceNumber matchingBranch) {
+ //TODO only called in the case of a single child
+ ensureSameFor(matchingBranch);
+ return getChild();
+ }
+
// basicSplayFor: matchingBranch
// "only called in the case of a single child"
***************
*** 92,96 ****
// aNodeOrNil notNil ifTrue: [aNodeOrNil addToParent: self]!
//
! protected List children() {
if (!hasChild())
return Collections.EMPTY_LIST;
--- 105,109 ----
// aNodeOrNil notNil ifTrue: [aNodeOrNil addToParent: self]!
//
! public List children() {
if (!hasChild())
return Collections.EMPTY_LIST;
***************
*** 140,143 ****
--- 153,160 ----
return dsp;
}
+
+ public void setDsp(int dsp) {
+ this.dsp = dsp;
+ }
// dsp
// ^dsp!
***************
*** 166,170 ****
// ^self dsp!
//
! protected EntNode duplicateFor(SequenceNumber newBranch) throws NonSameBranchException {
// Do not duplicate RootNodes at the moment, as this forced to happen on newEdition.
// @todo is this the right behaviour - not duplicating?
--- 183,187 ----
// ^self dsp!
//
! public EntNode duplicateFor(SequenceNumber newBranch) {
// Do not duplicate RootNodes at the moment, as this forced to happen on newEdition.
// @todo is this the right behaviour - not duplicating?
***************
*** 213,216 ****
--- 230,254 ----
// self dsp: 0.!
//
+
+
+ public void insert(LeafNode leaf) {
+ //TODO what abut dsp?
+ ensureSameFor(leaf.getBranch());
+ if (hasChild()) {
+ child.insertLeaf(leaf, applyDspTo(leaf.getStartPosition()), this);
+ } else {
+ //TODO review this default location of 1
+ if (leaf.getStartPosition() == 0) {
+ setChild(leaf);
+ } else {
+ throw new IndexOutOfBoundsException(String.valueOf(leaf.getStartPosition()));
+ }
+ }
+ }
+
+ public void insertLeaf(LeafNode leaf, int position, RootNode root) {
+ throw new UnsupportedOperationException();
+ }
+
// insert: dataLeaf
// "what about dsp?"
***************
*** 231,234 ****
--- 269,277 ----
// root: self]!
//
+
+ protected int invertDsp() {
+ return -dsp;
+ }
+
// invertDsp
// ^dsp negated!
|
|
From: <dg...@us...> - 2003-05-08 13:53:42
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/engine/tests In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/engine/tests Modified Files: AllTests.java Added Files: AboraConverterTest.java Log Message: -STart leaf tests --- NEW FILE: AboraConverterTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine.tests; import org.abora.ash.engine.AboraConverter; import junit.framework.TestCase; /** */ public class AboraConverterTest extends TestCase { public void testToAboraContent() { String s = "hello"; byte[] converted = AboraConverter.toAboraContent(s); assertEquals(s, AboraConverter.toJavaString(converted)); } } Index: AllTests.java =================================================================== RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/engine/tests/AllTests.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AllTests.java 4 May 2003 18:32:06 -0000 1.1 --- AllTests.java 8 May 2003 13:53:08 -0000 1.2 *************** *** 16,22 **** public static Test suite() { ! TestSuite suite = new TestSuite("Test for org.abora.be.tests"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(IdTest.class)); //$JUnit-END$ return suite; --- 16,23 ---- public static Test suite() { ! TestSuite suite = new TestSuite("Test for org.abora.ash.engine.tests"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(IdTest.class)); + suite.addTest(new TestSuite(AboraConverterTest.class)); //$JUnit-END$ return suite; |
|
From: <dg...@us...> - 2003-05-08 13:53:15
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/engine
In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/engine
Modified Files:
AboraConverter.java
Log Message:
-STart leaf tests
Index: AboraConverter.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/engine/AboraConverter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** AboraConverter.java 4 May 2003 18:32:06 -0000 1.1
--- AboraConverter.java 8 May 2003 13:53:10 -0000 1.2
***************
*** 22,24 ****
--- 22,28 ----
}
+ public static String toJavaString(byte[] bytes) {
+ return new String(bytes);
+ }
+
}
|
|
From: <dg...@us...> - 2003-05-08 13:53:15
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/tests
Modified Files:
AllTests.java
Log Message:
-STart leaf tests
Index: AllTests.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/tests/AllTests.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** AllTests.java 4 May 2003 18:32:07 -0000 1.1
--- AllTests.java 8 May 2003 13:53:10 -0000 1.2
***************
*** 16,21 ****
public static Test suite() {
! TestSuite suite = new TestSuite("Test for org.abora.violet.tests");
//$JUnit-BEGIN$
suite.addTest(org.abora.ash.engine.tests.AllTests.suite());
suite.addTest(org.abora.ash.ent.tests.AllTests.suite());
--- 16,22 ----
public static Test suite() {
! TestSuite suite = new TestSuite("Test for org.abora.content.tests");
//$JUnit-BEGIN$
+ suite.addTest(org.abora.ash.content.tests.AllTests.suite());
suite.addTest(org.abora.ash.engine.tests.AllTests.suite());
suite.addTest(org.abora.ash.ent.tests.AllTests.suite());
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/ent/tests Modified Files: RootNodeTest.java AllTests.java Added Files: ContentLeafTest.java CollectionLeafTest.java EntTestCase.java Log Message: -STart leaf tests --- NEW FILE: ContentLeafTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import org.abora.ash.content.BeCollectionHolder; import org.abora.ash.content.BeContentElement; import org.abora.ash.content.BeEdition; import org.abora.ash.ent.ContentLeaf; import org.abora.ash.ent.RootNode; import org.abora.ash.ent.SequenceNumber; /** */ public class ContentLeafTest extends EntTestCase { public ContentLeafTest(String arg0) { super(arg0); } // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // AboraBeTests subclass: #ContentLeafTest // instanceVariableNames: '' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // ContentLeafTest guid: (GUID fromString: '{0D230093-2E44-4D9C-839C-7678FC96F2B5}')! // ContentLeafTest comment: ''! // !ContentLeafTest categoriesForClass!Kernel-Objects! ! // !ContentLeafTest methodsFor! // // testContentsAt // | leaf content | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // self should: [(leaf contentsAt: 2) == content]! // // testContentsAtBadPosition // | leaf content | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // self should: [leaf contentsAt: 1] raise: BoundsError. // self should: [leaf contentsAt: 3] raise: BoundsError! // // testContentsFromExtentDo // | leaf content out | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // out := OrderedCollection new. // leaf // contentsFrom: 2 // extent: 1 // do: [:data | out add: data]. // self should: [out = (OrderedCollection with: content)]. // out := OrderedCollection new. // leaf // contentsFrom: 1 // extent: 3 // do: [:data | out add: data]. // self should: [out = (OrderedCollection with: content)]! // public void testCount() { BeContentElement content = new BeEdition(); ContentLeaf leaf = new ContentLeaf(new SequenceNumber(3), 2, content); assertEquals(1, leaf.count()); } // testCount // | leaf content | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // self should: [leaf count = 1]! // public void testCountCollection() { BeContentElement content = new BeCollectionHolder(new byte[] { 0, 1, 2 }); ContentLeaf leaf = new ContentLeaf(new SequenceNumber(3), 2, content); assertEquals(1, leaf.count()); } // testCountCollection // | leaf content | // content := BeDataHolder value: 'hello'. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // self should: [leaf count = 1]! // public void testCreate() { BeContentElement content = new BeEdition(); assertTrue(content.getParents().isEmpty()); ContentLeaf leaf = new ContentLeaf(new SequenceNumber(3), 2, content); assertEquals(content, leaf.getContentElement()); assertEquals(new SequenceNumber(3), leaf.getBranch()); assertEquals(2, leaf.getStartPosition()); assertEquals(1, content.getParents().size()); assertTrue(content.getParents().contains(leaf)); } // testCreate // | leaf content | // content := BeDataHolder value: 123. // self should: [content parents isEmpty]. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // self should: [leaf contentElement = content]. // self should: [leaf branch = 3]. // self should: [leaf startPosition = 2]. // self should: [content parents = (OrderedCollection with: leaf)]! // // testSharedWithForMappingsMultiple // | leaf content edition anotherEdition mappings | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 1 // startPosition: 1 // contentElement: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: content. // anotherEdition := anotherEdition append: (BeDataHolder value: 9). // anotherEdition := anotherEdition append: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 2]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 1)]. // self should: [mappings first last = (IntegerRegion startPosition: 1 extent: 1)]. // self should: [mappings last first = (IntegerRegion startPosition: 1 extent: 1)]. // self should: [mappings last last = (IntegerRegion startPosition: 3 extent: 1)]! // // testSharedWithForMappingsNone // | leaf content edition anotherEdition mappings | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 1 // startPosition: 1 // contentElement: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition new. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings isEmpty]! // // testSharedWithForMappingsSimpleDisplacement // | leaf content edition anotherEdition mappings | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 1 // startPosition: 1 // contentElement: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: (BeDataHolder value: 9). // anotherEdition := anotherEdition append: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 1]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 1)]. // self should: [mappings first last = (IntegerRegion startPosition: 2 extent: 1)]! // // testSharedWithForMappingsStraight // | leaf content edition anotherEdition mappings | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 1 // startPosition: 1 // contentElement: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 1]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 1)]. // self should: [mappings first last = (IntegerRegion startPosition: 1 extent: 1)]! // public void testSplitAbout() { BeContentElement content = new BeEdition(); ContentLeaf leaf = new ContentLeaf(new SequenceNumber(3), 2, content); RootNode root = new RootNode(null, new SequenceNumber(3), leaf); try { leaf.splitAbout(1, 2); fail(); } catch (UnsupportedOperationException e) { assertEquals("should not implement", e.getMessage()); } } // testSplitAbout // | leaf content root | // content := BeDataHolder value: 123. // leaf := ContentLeaf // branch: 3 // startPosition: 2 // contentElement: content. // root := RootNode // edition: nil // branch: 1 // with: leaf. // // "test" // self // should: [leaf split: 1 about: 2] // raise: Error // description: 'ContentLeaf should not implement #split:about:'! ! // !ContentLeafTest categoriesFor: #testContentsAt!public! ! // !ContentLeafTest categoriesFor: #testContentsAtBadPosition!public! ! // !ContentLeafTest categoriesFor: #testContentsFromExtentDo!public! ! // !ContentLeafTest categoriesFor: #testCount!public! ! // !ContentLeafTest categoriesFor: #testCountCollection!public! ! // !ContentLeafTest categoriesFor: #testCreate!public! ! // !ContentLeafTest categoriesFor: #testSharedWithForMappingsMultiple!public! ! // !ContentLeafTest categoriesFor: #testSharedWithForMappingsNone!public! ! // !ContentLeafTest categoriesFor: #testSharedWithForMappingsSimpleDisplacement!public! ! // !ContentLeafTest categoriesFor: #testSharedWithForMappingsStraight!public! ! // !ContentLeafTest categoriesFor: #testSplitAbout!public! ! } --- NEW FILE: CollectionLeafTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import org.abora.ash.engine.AboraConverter; import org.abora.ash.ent.CollectionLeaf; import org.abora.ash.ent.SequenceNumber; /** */ public class CollectionLeafTest extends EntTestCase { public CollectionLeafTest(String arg0) { super(arg0); } //:"Filed out from Dolphin Smalltalk 2002 release 5.00"! // //AboraBeTests subclass: #CollectionLeafTest // instanceVariableNames: '' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! //CollectionLeafTest guid: (GUID fromString: '{5D1379AA-01B5-4DC8-AEF9-C5B54A1529AD}')! //CollectionLeafTest comment: ''! //!CollectionLeafTest categoriesForClass!SUnit! ! //!CollectionLeafTest methodsFor! // //testAllEditions // | leaf root1 edition1 root2 edition2 | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // edition1 := BeEdition new. // root1 := RootNode // edition: edition1 // branch: 1 // with: leaf. // edition2 := BeEdition new. // root2 := RootNode // edition: edition2 // branch: 2 // with: leaf. // self should: [leaf allEditions size = 2]. // self should: [leaf allEditions includes: edition1]. // self should: [leaf allEditions includes: edition2]! // //testAllRoots // | leaf root1 root2 | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // root1 := RootNode // edition: nil // branch: 1 // with: leaf. // root2 := RootNode // edition: nil // branch: 2 // with: leaf. // self should: [leaf allRoots size = 2]. // self should: [leaf allRoots includes: root1]. // self should: [leaf allRoots includes: root2]! // //testContents // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // self should: [leaf contents = 'abcdef' asAboraContent]! // //testContentsAt // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // self should: [(leaf contentsAt: 10) = $a codePoint]. // self should: [(leaf contentsAt: 11) = $b codePoint]. // self should: [(leaf contentsAt: 15) = $f codePoint]! // //testContentsAtBadPosition // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // self should: [leaf contentsAt: 9] raise: BoundsError. // self should: [leaf contentsAt: 16] raise: BoundsError! // //testContentsFromExtentDo // | leaf out do | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'abcdef' asAboraContent. // out := ''. // do := [:int | out := out , (Character codePoint: int) asString]. // leaf // contentsFrom: 10 // extent: 6 // do: do. // self should: [out = 'abcdef']. // out := ''. // leaf // contentsFrom: 11 // extent: 3 // do: do. // self should: [out = 'bcd']. // out := ''. // leaf // contentsFrom: 8 // extent: 13 // do: do. // self should: [out = 'abcdef']. // out := ''. // leaf // contentsFrom: 8 // extent: 3 // do: do. // self should: [out = 'a']. // out := ''. // leaf // contentsFrom: 15 // extent: 6 // do: do. // self should: [out = 'f']. // out := ''. // leaf // contentsFrom: 5 // extent: 5 // do: do. // self should: [out = '']. // out := ''. // leaf // contentsFrom: 16 // extent: 5 // do: do. // self should: [out = '']! // //testCount // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'hello' asAboraContent. // self should: [leaf count = 5]! // public void testCreate() { CollectionLeaf leaf = new CollectionLeaf(new SequenceNumber(3), 2, AboraConverter.toAboraContent("hello")); //TODO assertEquals("hello", AboraConverter.toJavaString(leaf.getElements())); assertEquals(new SequenceNumber(3), leaf.getBranch()); assertEquals(2, leaf.getStartPosition()); } //testCreate // | leaf | // leaf := CollectionLeaf // branch: 3 // startPosition: 2 // elements: 'hello' asAboraContent. // self should: [leaf elements = 'hello' asAboraContent]. // self should: [leaf branch = 3]. // self should: [leaf startPosition = 2]! // //testDuplicateFor // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [leaf duplicateFor: 1] raise: Error! // //testGlobalPositionFor // | leaf1 leaf2 split root | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 4 // elements: '12' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 5 // elements: '3' asAboraContent. // split := SplitNode // branch: 1 // split: 7 // left: leaf1 // leftDsp: 1 // right: leaf2 // rightDsp: 2. // root := RootNode // edition: nil // branch: 1 // with: split // dsp: -4. // self assertTextContentsOf: root is: '123'. // // "test" // self should: [(leaf1 globalPositionFor: 1) = 1]. // self should: [(leaf2 globalPositionFor: 1) = 3]! // //testGlobalPositionForSimple // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [(leaf globalPositionFor: 1) = 1]! // //testGlobalRegionFor // | leaf1 leaf2 split root | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 4 // elements: '12' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 5 // elements: '3' asAboraContent. // split := SplitNode // branch: 1 // split: 7 // left: leaf1 // leftDsp: 1 // right: leaf2 // rightDsp: 2. // root := RootNode // edition: nil // branch: 1 // with: split // dsp: -4. // self assertTextContentsOf: root is: '123'. // // "test" // self should: [(leaf1 globalRegionFor: 1) = (IntegerRegion startPosition: 1 extent: 2)]. // self should: [(leaf2 globalRegionFor: 1) = (IntegerRegion startPosition: 3 extent: 1)]! // //testInsertAtRootBadPosition // | root leaf insertedNode | // leaf := CollectionLeaf // branch: 3 // startPosition: 4 // elements: 'hello' asAboraContent. // root := RootNode // edition: nil // branch: 4 // with: leaf // dsp: -3. // insertedNode := CollectionLeaf // branch: 3 // startPosition: 0 // elements: 'ab' asAboraContent. // self should: // [leaf // insert: insertedNode // at: 3 // root: root] // raise: BoundsError. // self should: // [leaf // insert: insertedNode // at: 9 + 1 // root: root] // raise: BoundsError! // //testIsMaxNodeFor // | root leaf | // root := self createBalanced12345678. // 1 to: 7 // do: // [:index | // leaf := root nodeAt: index. // self should: [(leaf isMaxNodeFor: 1) not]]. // leaf := root nodeAt: 8. // self should: [leaf isMaxNodeFor: 1]! // //testIsMaxNodeForSingle // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [leaf isMaxNodeFor: 1]! // //testIsMinNodeFor // | root leaf | // root := self createBalanced12345678. // 2 to: 8 // do: // [:index | // leaf := root nodeAt: index. // self should: [(leaf isMinNodeFor: 1) not]]. // leaf := root nodeAt: 1. // self should: [leaf isMinNodeFor: 1]! // //testIsMinNodeForSingle // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [leaf isMinNodeFor: 1]! // //testMaxNode // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [leaf maxNode == leaf]! // //testMinNode // | leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // self should: [leaf minNode == leaf]! // //testRemoveFromRoot // | root leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf. // // "test" // leaf removeFor: 1. // self should: [root count = 0]. // self assertTextContentsOf: root is: ''! // //testRemoveFromSplitLeft // | root leaf1 leaf2 splitNode | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'a' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 2 // elements: 'b' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 2 // left: leaf1 // right: leaf2. // root := RootNode // edition: nil // branch: 1 // with: splitNode. // // "test" // leaf1 removeFor: 1. // self assertTextContentsOf: root is: 'b'! // //testRemoveFromSplitRight // | root leaf1 leaf2 splitNode | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'a' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 2 // elements: 'b' asAboraContent. // splitNode := SplitNode // branch: 1 // split: 2 // left: leaf1 // right: leaf2. // root := RootNode // edition: nil // branch: 1 // with: splitNode. // // "test" // leaf2 removeFor: 1. // self assertTextContentsOf: root is: 'a'! // //testReplaceWithSplitAbout // | root leaf splitNode collection | // collection := BeCollectionHolder collection: 'hello' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: collection. // root := RootNode // edition: nil // branch: 1 // with: leaf. // self should: [collection parents = (OrderedCollection with: leaf)]. // // "test" // splitNode := leaf replaceWithSplit: 1 about: 3. // self should: [splitNode left elements = 'he' asAboraContent]. // self should: [splitNode right elements = 'llo' asAboraContent]. // self should: [splitNode left parents = (OrderedCollection with: splitNode)]. // self should: [splitNode right parents = (OrderedCollection with: splitNode)]. // self // should: [collection parents = (OrderedCollection with: splitNode left with: splitNode right)]. // "existing parents should be updated with new splitNode" // self should: [leaf parents = OrderedCollection new]. // self should: [root child == splitNode]. // self should: [splitNode parents = (OrderedCollection with: root)]! // //testSharedWithForMappingsMultiple // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: content. // anotherEdition := anotherEdition append: 'abcde' asAboraContent. // anotherEdition := anotherEdition append: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 2]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 3)]. // self should: [mappings first last = (IntegerRegion startPosition: 1 extent: 3)]. // self should: [mappings last first = (IntegerRegion startPosition: 1 extent: 3)]. // self should: [mappings last last = (IntegerRegion startPosition: 9 extent: 3)]! // //testSharedWithForMappingsNone // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition new. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings isEmpty]! // //testSharedWithForMappingsNoneByPartialOverlap // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // edition := edition removeFrom: 1 extent: 2. // anotherEdition := BeEdition contents: content. // anotherEdition := anotherEdition removeFrom: 2 extent: 2. // mappings := OrderedCollection new. // self should: [edition root child contents = '3' asAboraContent]. // edition root child // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 0]! // //testSharedWithForMappingsPartialOverlap // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: 'abcd' asAboraContent. // anotherEdition := anotherEdition insert: content at: 5. // anotherEdition := anotherEdition removeFrom: 5 extent: 2. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 1]. // self should: [mappings first first = (IntegerRegion startPosition: 3 extent: 1)]. // self should: [mappings first last = (IntegerRegion startPosition: 5 extent: 1)]! // //testSharedWithForMappingsSimpleDisplacement // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: 'abcde' asAboraContent. // anotherEdition := anotherEdition append: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 1]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 3)]. // self should: [mappings first last = (IntegerRegion startPosition: 6 extent: 3)]! // //testSharedWithForMappingsStraight // | leaf content edition anotherEdition mappings | // content := BeCollectionHolder collection: '123' asAboraContent. // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // collection: content. // edition := BeEdition new. // edition root insert: leaf. // anotherEdition := BeEdition contents: content. // mappings := OrderedCollection new. // leaf // sharedWith: anotherEdition // for: anotherEdition branch // mappings: mappings. // self should: [mappings size = 1]. // self should: [mappings first first = (IntegerRegion startPosition: 1 extent: 3)]. // self should: [mappings first last = (IntegerRegion startPosition: 1 extent: 3)]! // //testSplitAbout // | root leaf splitNode | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf. // // "test" // splitNode := leaf split: 1 about: 3. // self should: [splitNode left elements = 'he' asAboraContent]. // self should: [splitNode right elements = 'llo' asAboraContent]. // self should: [splitNode left parents = (OrderedCollection with: splitNode)]. // self should: [splitNode right parents = (OrderedCollection with: splitNode)]. // self assertTextContentsOf: root is: 'hello'. // "existing parents should be left untouched" // self should: [splitNode parents = OrderedCollection new]. // self should: [root child == leaf]. // self should: [leaf parents = (OrderedCollection with: root)]! // //testSplitAboutBadAbout // | root leaf splitNode | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf. // // "test" // self should: [splitNode := leaf split: 1 about: 0] raise: BoundsError. // self should: [splitNode := leaf split: 1 about: 1] raise: BoundsError. // self should: [splitNode := leaf split: 1 about: 6] raise: BoundsError. // self should: [splitNode := leaf split: 1 about: 7] raise: BoundsError! ! //!CollectionLeafTest categoriesFor: #testAllEditions!public! ! //!CollectionLeafTest categoriesFor: #testAllRoots!public! ! //!CollectionLeafTest categoriesFor: #testContents!public! ! //!CollectionLeafTest categoriesFor: #testContentsAt!public! ! //!CollectionLeafTest categoriesFor: #testContentsAtBadPosition!public! ! //!CollectionLeafTest categoriesFor: #testContentsFromExtentDo!public! ! //!CollectionLeafTest categoriesFor: #testCount!public! ! //!CollectionLeafTest categoriesFor: #testCreate!public! ! //!CollectionLeafTest categoriesFor: #testDuplicateFor!public! ! //!CollectionLeafTest categoriesFor: #testGlobalPositionFor!public! ! //!CollectionLeafTest categoriesFor: #testGlobalPositionForSimple!public! ! //!CollectionLeafTest categoriesFor: #testGlobalRegionFor!public! ! //!CollectionLeafTest categoriesFor: #testInsertAtRootBadPosition!public! ! //!CollectionLeafTest categoriesFor: #testIsMaxNodeFor!public! ! //!CollectionLeafTest categoriesFor: #testIsMaxNodeForSingle!public! ! //!CollectionLeafTest categoriesFor: #testIsMinNodeFor!public! ! //!CollectionLeafTest categoriesFor: #testIsMinNodeForSingle!public! ! //!CollectionLeafTest categoriesFor: #testMaxNode!public! ! //!CollectionLeafTest categoriesFor: #testMinNode!public! ! //!CollectionLeafTest categoriesFor: #testRemoveFromRoot!public! ! //!CollectionLeafTest categoriesFor: #testRemoveFromSplitLeft!public! ! //!CollectionLeafTest categoriesFor: #testRemoveFromSplitRight!public! ! //!CollectionLeafTest categoriesFor: #testReplaceWithSplitAbout!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsMultiple!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsNone!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsNoneByPartialOverlap!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsPartialOverlap!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsSimpleDisplacement!public! ! //!CollectionLeafTest categoriesFor: #testSharedWithForMappingsStraight!public! ! //!CollectionLeafTest categoriesFor: #testSplitAbout!public! ! //!CollectionLeafTest categoriesFor: #testSplitAboutBadAbout!public! ! // } --- NEW FILE: EntTestCase.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import junit.framework.TestCase; import org.abora.ash.ent.EntNode; /** */ public class EntTestCase extends TestCase { public EntTestCase(String name) { super(name); } // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // AboraTests subclass: #AboraBeTests // instanceVariableNames: '' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // AboraBeTests guid: (GUID fromString: '{8B40BB18-EAF8-4BB9-8BBD-4644045F1CBE}')! // AboraBeTests comment: ''! // !AboraBeTests categoriesForClass!Kernel-Objects! ! // !AboraBeTests methodsFor! // protected void assertTextContents(String expectedText, EntNode node) { //TODO } // assertTextContentsOf: root is: expectedText // | actualText | // actualText := root contents asAboraText. // self should: [actualText = expectedText]. // expectedText // keysAndValuesDo: [:i :char | self should: [(root contentsAt: i) = char codePoint]]! // // createBalanced12345678 // | splitC1 splitC2 splitC3 splitA splitC4 splitB1 splitB2 | // splitC1 := SplitNode // branch: 1 // split: 2 // left: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '1' asAboraContent) // right: (CollectionLeaf // branch: 1 // startPosition: 2 // elements: '2' asAboraContent). // splitC2 := SplitNode // branch: 1 // split: 4 // left: (CollectionLeaf // branch: 1 // startPosition: 3 // elements: '3' asAboraContent) // right: (CollectionLeaf // branch: 1 // startPosition: 4 // elements: '4' asAboraContent). // splitC3 := SplitNode // branch: 1 // split: 6 // left: (CollectionLeaf // branch: 1 // startPosition: 5 // elements: '5' asAboraContent) // right: (CollectionLeaf // branch: 1 // startPosition: 6 // elements: '6' asAboraContent). // splitC4 := SplitNode // branch: 1 // split: 8 // left: (CollectionLeaf // branch: 1 // startPosition: 7 // elements: '7' asAboraContent) // right: (CollectionLeaf // branch: 1 // startPosition: 8 // elements: '8' asAboraContent). // splitB1 := SplitNode // branch: 1 // split: 3 // left: splitC1 // right: splitC2. // splitB2 := SplitNode // branch: 1 // split: 7 // left: splitC3 // right: splitC4. // splitA := SplitNode // branch: 1 // split: 5 // left: splitB1 // right: splitB2. // ^RootNode // edition: nil // branch: 1 // with: splitA! // // createSourceEdition12345678 // | edition | // edition := BeEdition new. // edition root insert: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345678' asAboraContent). // ^edition! ! // !AboraBeTests categoriesFor: #assertTextContentsOf:is:!public! ! // !AboraBeTests categoriesFor: #createBalanced12345678!private! ! // !AboraBeTests categoriesFor: #createSourceEdition12345678!private! ! // // !AboraBeTests class methodsFor! // // isAbstract // "Override to true if a TestCase subclass is Abstract and should not have // TestCase instances built from it" // // ^self name = #AboraBeTests! ! // !AboraBeTests class categoriesFor: #isAbstract!public! ! // } Index: RootNodeTest.java =================================================================== RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests/RootNodeTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RootNodeTest.java 4 May 2003 18:32:06 -0000 1.1 --- RootNodeTest.java 8 May 2003 13:53:09 -0000 1.2 *************** *** 7,23 **** package org.abora.ash.ent.tests; ! import org.abora.ash.engine.AboraConverter; import org.abora.ash.content.BeEdition; import org.abora.ash.ent.ChildNode; import org.abora.ash.ent.CollectionLeaf; import org.abora.ash.ent.NonCompatibleBranchException; import org.abora.ash.ent.RootNode; import org.abora.ash.ent.SequenceNumber; [...1233 lines suppressed...] ! // found := root splay: 4. ! // self assertTextContentsOf: root is: '12345678'. ! // self should: [found elements = '4' asAboraContent]. ! // self shouldHaveMatchingParents: root. ! // ! ! // ! // testSplayChild ! // | root found leaf | ! // leaf := CollectionLeaf ! // branch: 1 ! // startPosition: 1 ! // elements: '1' asAboraContent. ! // root := RootNode ! // edition: nil ! // branch: 1 ! // with: leaf. ! // root splay: 1. ! // self should: [root child == leaf]! ! } Index: AllTests.java =================================================================== RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests/AllTests.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AllTests.java 4 May 2003 18:32:06 -0000 1.1 --- AllTests.java 8 May 2003 13:53:09 -0000 1.2 *************** *** 18,23 **** TestSuite suite = new TestSuite("Test for org.abora.be.ent.tests"); //$JUnit-BEGIN$ ! suite.addTest(new TestSuite(SequenceNumberTest.class)); suite.addTest(new TestSuite(RootNodeTest.class)); //$JUnit-END$ return suite; --- 18,25 ---- TestSuite suite = new TestSuite("Test for org.abora.be.ent.tests"); //$JUnit-BEGIN$ ! suite.addTest(new TestSuite(CollectionLeafTest.class)); ! suite.addTest(new TestSuite(ContentLeafTest.class)); suite.addTest(new TestSuite(RootNodeTest.class)); + suite.addTest(new TestSuite(SequenceNumberTest.class)); //$JUnit-END$ return suite; |
|
From: <dg...@us...> - 2003-05-08 13:53:14
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/content
In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/content
Modified Files:
BeCollectionHolder.java BeContentElement.java
BeDataHolder.java
Log Message:
-STart leaf tests
Index: BeCollectionHolder.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/content/BeCollectionHolder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** BeCollectionHolder.java 4 May 2003 18:32:06 -0000 1.1
--- BeCollectionHolder.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 11,13 ****
--- 11,83 ----
public class BeCollectionHolder extends BeContentElement {
+ private final byte[] collection;
+
+ // "Filed out from Dolphin Smalltalk 2002 release 5.00"!
+ //
+ // BeContentElement subclass: #BeCollectionHolder
+ // instanceVariableNames: 'collection'
+ // classVariableNames: ''
+ // poolDictionaries: ''
+ // classInstanceVariableNames: ''!
+ // BeCollectionHolder guid: (GUID fromString: '{46785AAF-450D-4C62-8737-3DFC64C37622}')!
+ // BeCollectionHolder comment: ''!
+ // !BeCollectionHolder categoriesForClass!Kernel-Objects! !
+ // !BeCollectionHolder methodsFor!
+ //
+ // collection
+ // ^collection!
+ //
+ // collection: setCollection
+ // self ensureValidCollection: setCollection.
+ //
+ // collection := setCollection.!
+ //
+
+ public int count() {
+ return collection.length;
+ }
+
+ // createNodeAt: position for: forRevision
+ // ^CollectionLeaf
+ // branch: forRevision
+ // startPosition: position
+ // collection: self!
+ //
+ // ensureValidCollection: potentialCollection
+ // #todo "ensure that contents is either all integer or all float".
+ // ((potentialCollection isKindOf: Array) and: [potentialCollection allSatisfy: [:a | a isInteger]]) ifTrue: [^self].
+ //
+ // Error signal: 'invalid element to insert into ent'.
+ // !
+ //
+ // printOn: aStream
+ // self basicPrintOn: aStream.
+ // aStream nextPutAll: '('.
+ // self collection displayOn: aStream.
+ // aStream nextPutAll: ')'! !
+ // !BeCollectionHolder categoriesFor: #collection!accessing!private! !
+ // !BeCollectionHolder categoriesFor: #collection:!accessing!private! !
+ // !BeCollectionHolder categoriesFor: #createNodeAt:for:!public! !
+ // !BeCollectionHolder categoriesFor: #ensureValidCollection:!accessing!private! !
+ // !BeCollectionHolder categoriesFor: #printOn:!public! !
+ //
+ // !BeCollectionHolder class methodsFor!
+ //
+
+ public BeCollectionHolder(byte[] collection) {
+ super();
+ this.collection = collection;
+ }
+
+ public byte[] getCollection() {
+ return collection;
+ }
+
+ // collection: array
+ // ^(self new)
+ // collection: array;
+ // yourself! !
+ // !BeCollectionHolder class categoriesFor: #collection:!public! !
+ //
+
}
Index: BeContentElement.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/content/BeContentElement.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** BeContentElement.java 4 May 2003 18:32:06 -0000 1.1
--- BeContentElement.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 7,15 ****
--- 7,119 ----
package org.abora.ash.content;
+ import java.util.HashSet;
+ import java.util.Set;
+
import org.abora.ash.engine.AboraObject;
+ import org.abora.ash.ent.LeafNode;
/**
*/
public class BeContentElement extends AboraObject {
+
+ protected Set parents;
+
+ protected BeContentElement() {
+ parents = new HashSet();
+ }
+
+ // "Filed out from Dolphin Smalltalk 2002 release 5.00"!
+ //
+ // AboraObject subclass: #BeContentElement
+ // instanceVariableNames: 'parents'
+ // classVariableNames: ''
+ // poolDictionaries: ''
+ // classInstanceVariableNames: ''!
+ // BeContentElement guid: (GUID fromString: '{29FCADDE-72E1-4551-88EA-D8C71B0A338A}')!
+ // BeContentElement comment: ''!
+ // !BeContentElement categoriesForClass!Kernel-Objects! !
+ // !BeContentElement methodsFor!
+ //
+
+ public void addParent(LeafNode node) {
+ parents.add(node);
+ }
+
+ // addParent: parent
+ // parents add: parent!
+ //
+ // createNodeAt: position for: forRevision
+ // ^ContentLeaf
+ // branch: forRevision
+ // startPosition: position
+ // contentElement: self!
+ //
+ // filterTransclusions: editions by: filter
+ // ^editions select: [:edition | filter allSatisfy: [:requiredEdition | edition endorsements includes: requiredEdition]].!
+ //
+ // initialize
+ // super initialize.
+ //
+ // parents := OrderedCollection new.!
+ //
+ // makeFeProxy
+ // self subclassResponsibility!
+ //
+
+ public Set getParents() {
+ return parents;
+ }
+
+ // parents
+ // ^parents!
+ //
+
+ public void removeParent(LeafNode parent) {
+ parents.remove(parent);
+ }
+
+ // removeParent: parent
+ // parents remove: parent!
+ //
+ // stbSaveOn: anSTBOutFiler
+ // (anSTBOutFiler context isKindOf: BeSession)
+ // ifTrue:
+ // [anSTBOutFiler context addFeContentElementFor: self.
+ // anSTBOutFiler saveObject: self as: (STBBeContentElementForFE for: self)]
+ // ifFalse:
+ // [self assert: [anSTBOutFiler context ~~ #forBe].
+ // "self halt."
+ // super stbSaveOn: anSTBOutFiler]!
+ //
+ // transclusionsDirect
+ // "return an edition"
+ //
+ // | editions |
+ // #todo.
+ // editions := IdentitySet new.
+ // self parents do: [:leaf | editions addAll: leaf allEditions].
+ // editions remove: self
+ // ifAbsent:
+ // ["ignore"
+ //
+ // ].
+ // ^editions!
+ //
+ // transclusionsDirectFilteredBy: filter
+ // | editions |
+ // editions := self transclusionsDirect.
+ // ^self filterTransclusions: editions by: filter
+ // ! !
+ // !BeContentElement categoriesFor: #addParent:!must not strip!public! !
+ // !BeContentElement categoriesFor: #createNodeAt:for:!must not strip!public! !
+ // !BeContentElement categoriesFor: #filterTransclusions:by:!must not strip!public! !
+ // !BeContentElement categoriesFor: #initialize!private! !
+ // !BeContentElement categoriesFor: #makeFeProxy!private! !
+ // !BeContentElement categoriesFor: #parents!must not strip!public! !
+ // !BeContentElement categoriesFor: #removeParent:!must not strip!public! !
+ // !BeContentElement categoriesFor: #stbSaveOn:!private! !
+ // !BeContentElement categoriesFor: #transclusionsDirect!must not strip!public! !
+ // !BeContentElement categoriesFor: #transclusionsDirectFilteredBy:!must not strip!public! !
+ //
}
Index: BeDataHolder.java
===================================================================
RCS file: /cvsroot/abora/abora-ash/src/org/abora/ash/content/BeDataHolder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** BeDataHolder.java 4 May 2003 18:32:06 -0000 1.1
--- BeDataHolder.java 8 May 2003 13:53:09 -0000 1.2
***************
*** 9,13 ****
/**
*/
! public class BeDataHolder {
}
--- 9,62 ----
/**
*/
! public class BeDataHolder extends BeContentElement {
!
! private final BeContentElement value;
!
! public BeDataHolder(BeContentElement value) {
! super();
! this.value = value;
! }
!
! public BeContentElement getValue() {
! return value;
! }
!
!
!
! // "Filed out from Dolphin Smalltalk 2002 release 5.00"!
! //
! // BeContentElement subclass: #BeDataHolder
! // instanceVariableNames: 'value'
! // classVariableNames: ''
! // poolDictionaries: ''
! // classInstanceVariableNames: ''!
! // BeDataHolder guid: (GUID fromString: '{E7A180D5-EAC0-4DEB-B9E0-6ACDFA73FB06}')!
! // BeDataHolder comment: ''!
! // !BeDataHolder categoriesForClass!Kernel-Objects! !
! // !BeDataHolder methodsFor!
! //
! // printOn: aStream
! // self basicPrintOn: aStream.
! // aStream nextPutAll: '('.
! // self value displayOn: aStream.
! // aStream nextPutAll: ')'!
! //
! // value
! // ^value!
! //
! // value: anObject
! // value := anObject! !
! // !BeDataHolder categoriesFor: #printOn:!public! !
! // !BeDataHolder categoriesFor: #value!accessing!private! !
! // !BeDataHolder categoriesFor: #value:!accessing!private! !
! //
! // !BeDataHolder class methodsFor!
! //
! // value: dataValue
! // ^(self new)
! // value: dataValue;
! // yourself! !
! // !BeDataHolder class categoriesFor: #value:!public! !
! //
}
|
|
From: <dg...@us...> - 2003-05-08 13:53:13
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/content/tests In directory sc8-pr-cvs1:/tmp/cvs-serv11397/src/org/abora/ash/content/tests Added Files: AllTests.java BeCollectionHolderTest.java Log Message: -STart leaf tests --- NEW FILE: AllTests.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content.tests; import junit.framework.Test; import junit.framework.TestSuite; /** */ public class AllTests extends BeCollectionHolderTest { public static Test suite() { TestSuite suite = new TestSuite("Test for org.abora.ash.content.tests"); //$JUnit-BEGIN$ suite.addTestSuite(BeCollectionHolderTest.class); //$JUnit-END$ return suite; } } --- NEW FILE: BeCollectionHolderTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content.tests; import junit.framework.TestCase; import org.abora.ash.content.BeCollectionHolder; import org.abora.ash.engine.AboraConverter; /** */ public class BeCollectionHolderTest extends TestCase { // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // AboraBeTests subclass: #BeCollectionHolderTest // instanceVariableNames: '' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // BeCollectionHolderTest guid: (GUID fromString: '{057A8346-027D-402E-B62F-145355E68B95}')! // BeCollectionHolderTest comment: ''! // !BeCollectionHolderTest categoriesForClass!Kernel-Objects! ! // !BeCollectionHolderTest methodsFor! // public void testCount() { BeCollectionHolder holder = new BeCollectionHolder(AboraConverter.toAboraContent("hello")); assertEquals(5, holder.count()); } public void testCreate() { BeCollectionHolder holder = new BeCollectionHolder(AboraConverter.toAboraContent("hello")); assertEquals("hello", AboraConverter.toJavaString(holder.getCollection())); } // testCreate // | content | // content := BeCollectionHolder collection: 'hello' asAboraContent. // self should: [content collection = 'hello' asAboraContent]! // // testCreateBadCollection // self should: [BeCollectionHolder collection: 'hello'] raise: Error. // self should: [BeCollectionHolder collection: nil] raise: Error. // self should: [BeCollectionHolder collection: #(1 1.0)] raise: Error. // self should: [BeCollectionHolder collection: BeEdition new] raise: Error! // // testCreateNodeAtFor // | content node | // content := BeCollectionHolder collection: 'ABC' asAboraContent. // node := content createNodeAt: 1 for: 2 asBranchingNumber. // self should: [node contents = 'ABC' asAboraContent]. // self should: [node branch = 2 asBranchingNumber]. // self should: [node startPosition = 1].! // // testPrintOn // | content | // content := BeCollectionHolder collection: 'ABC' asAboraContent. // self should: [content printString = 'a BeCollectionHolder(#(65 66 67))']! ! // !BeCollectionHolderTest categoriesFor: #testCreate!public! ! // !BeCollectionHolderTest categoriesFor: #testCreateBadCollection!public! ! // !BeCollectionHolderTest categoriesFor: #testCreateNodeAtFor!public! ! // !BeCollectionHolderTest categoriesFor: #testPrintOn!public! ! // } |
|
From: <dg...@us...> - 2003-05-08 13:53:07
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/content/tests In directory sc8-pr-cvs1:/tmp/cvs-serv11350/src/org/abora/ash/content/tests Log Message: Directory /cvsroot/abora/abora-ash/src/org/abora/ash/content/tests added to the repository |
|
From: <dg...@us...> - 2003-05-04 18:45:31
|
Update of /cvsroot/abora/abora-ash
In directory sc8-pr-cvs1:/tmp/cvs-serv8217
Added Files:
build.xml
Log Message:
-Initial ant build file - based on abora-white
--- NEW FILE: build.xml ---
<project name="abora-ash" default="dist" basedir=".">
<description>
Abora server written in Java and based on earlier Dolphin Demo sub-project.
</description>
<!-- set global properties for this build -->
<property environment="env"/>
<property name="name" value="abora-ash"/>
<property name="Name" value="Abora-Ash"/>
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<property name="lib.dir" location="lib"/>
<property name="junit.dir" location="${build}/docs/junit"/>
<property name="javadoc.dir" location="${build}/docs/api"/>
<property name="clover.dir" location="${build}/docs/clover"/>
<property name="clover.history.dir" location="${build}/docs/clover-historical"/>
<property name="clover.includesource" value="true"/>
<property name="clover.home" value="${env.CLOVER_HOME}"/>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${build}/bin"/>
<mkdir dir="${build}/docs"/>
<path id="clover.classpath">
<pathelement path="${clover.home}/lib/clover.jar"/>
</path>
</target>
<target name="clean"
description="clean up" >
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<javac srcdir="${src}" destdir="${build}/bin" extdirs="${lib.dir}" />
</target>
<target name="dist" depends="with.clover, clean, init, compile, test, clover.historypoint, docs"
description="generate the distribution" >
<mkdir dir="${dist}/lib"/>
<jar jarfile="${dist}/lib/${name}-${DSTAMP}.jar" basedir="${build}/bin"/>
<!-- TODO following over-complexity is a poor attempt to get all
zipped content under a common root dir -->
<property name="parent.dir" value="${name}"/>
<zip destfile="${dist}/${name}-${DSTAMP}.src.zip" basedir=".." excludes="**/*">
<fileset dir="..">
<include name="${parent.dir}/build.xml"/>
<include name="${parent.dir}/ReadMe.txt"/>
<include name="${parent.dir}/src/**/*.java"/>
<include name="${parent.dir}/docs/**/*.html"/>
</fileset>
</zip>
</target>
<!--**************************************************************-->
<!--** JUnit tests ***********************************************-->
<!--**************************************************************-->
<target name="test" depends="compile">
<mkdir dir="${junit.dir}/report"/>
<junit printsummary="true" haltonerror="true">
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.dir}/report">
<fileset dir="${src}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
<classpath>
<pathelement path="${build}/bin"/>
</classpath>
<classpath refid="clover.classpath"/>
</junit>
</target>
<target name="test.report" depends="test">
<mkdir dir="${junit.dir}/html"/>
<junitreport todir="${junit.dir}/report">
<fileset dir="${junit.dir}/report">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junit.dir}/html"/>
</junitreport>
</target>
<!--**************************************************************-->
<!--** JavaDoc ***************************************************-->
<!--**************************************************************-->
<target name="javadoc" depends="compile">
<mkdir dir="${javadoc.dir}"/>
<delete dir="${javadoc.dir}"/>
<javadoc destdir="${javadoc.dir}"
author="true"
version="true"
use="false"
windowtitle="${Name} API"
noindex="true"
verbose="false"
nodeprecatedlist="true"
>
<!-- additionalparam="-linksource" -->
<packageset dir="${src}" defaultexcludes="yes">
<include name="org/abora/ash/**" />
<exclude name="**/tests/**"/>
</packageset>
<doctitle><![CDATA[<h1>${Name}</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright © 2003 David G Jones. All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:" />
<!-- <group title="Group 1 Packages" packages="com.dummy.test.a*"/> -->
<!-- <group title="Group 2 Packages" packages="com.dummy.test.b*:com.dummy.test.c*"/> -->
<!-- <link offline="true" href="http://java.sun.com/products/jdk/1.2/docs/api/" packagelistLoc="C:\tmp"/> -->
<!-- <link href="http://developer.java.sun.com/developer/products/xml/docs/api/"/> -->
</javadoc>
</target>
<target name="docs.copyoriginal" depends="init">
<copy todir="${build}/docs">
<fileset dir="docs"/>
</copy>
</target>
<target name="docs" depends="init, docs.copyoriginal, test.report, javadoc, clover.report"/>
<!--**************************************************************-->
<!--** Clover Code Coverage Support ******************************-->
<!--**************************************************************-->
<target name="with.clover" if="env.CLOVER_HOME">
<echo message="*** Including Clover support ***"/>
<taskdef resource="clovertasks"/>
<clover-setup initString="${build}/clover_coverage.db">
<files>
<exclude name="**/tests/**"/>
</files>
</clover-setup>
<property name="build.compiler" value="org.apache.tools.ant.taskdefs.CloverCompilerAdapter"/>
</target>
<target name="clover.report" depends="with.clover, init" if="env.CLOVER_HOME">
<clover-report>
<Current title="${Name}" outfile="${clover.dir}">
<format type="html" srcLevel="${clover.includesource}"/>
</Current>
<Historical title="${Name}" outfile="${clover.history.dir}" historyDir="${basedir}/clover-historical">
<format type="html"/>
</Historical>
</clover-report>
</target>
<target name="clover.historypoint" depends="with.clover, init" if="env.CLOVER_HOME">
<mkdir dir="${basedir}/clover-historical"/>
<clover-historypoint historyDir="${basedir}/clover-historical"/>
</target>
<target name="just.clover" depends="with.clover, clean, compile, test, clover.report"/>
<!--**************************************************************-->
</project>
|
|
From: <dg...@us...> - 2003-05-04 18:32:11
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/ent Added Files: NonSameBranchException.java EntException.java SplitNode.java CollectionLeaf.java LeafNode.java NonCompatibleBranchException.java ContentLeaf.java EntNode.java SequenceNumber.java ChildNode.java RootNode.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: NonSameBranchException.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; /** */ public class NonSameBranchException extends EntException { /** * Constructor for NonSameBranchException. */ public NonSameBranchException() { super(); } /** * Constructor for NonSameBranchException. * @param message */ public NonSameBranchException(String message) { super(message); } /** * Constructor for NonSameBranchException. * @param message * @param cause */ public NonSameBranchException(String message, Throwable cause) { super(message, cause); } /** * Constructor for NonSameBranchException. * @param cause */ public NonSameBranchException(Throwable cause) { super(cause); } } --- NEW FILE: EntException.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import org.abora.ash.engine.AboraException; /** */ public class EntException extends AboraException { /** * Constructor for EntException. */ public EntException() { super(); } /** * Constructor for EntException. * @param message */ public EntException(String message) { super(message); } /** * Constructor for EntException. * @param message * @param cause */ public EntException(String message, Throwable cause) { super(message, cause); } /** * Constructor for EntException. * @param cause */ public EntException(Throwable cause) { super(cause); } } --- NEW FILE: SplitNode.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.ArrayList; import java.util.List; /** */ public class SplitNode extends ChildNode { private int split = 0; private EntNode left = null; private EntNode right = null; private int leftDsp = 0; private int rightDsp = 0; public SplitNode(SequenceNumber branch, int split, EntNode left, int leftDsp, EntNode right) { this(branch, split, left, leftDsp, right, 0); } public SplitNode(SequenceNumber branch, int split, EntNode left, int leftDsp, EntNode right, int rightDsp) { super(branch); this.split = split; this.left = left; this.leftDsp = leftDsp; this.right = right; this.rightDsp = rightDsp; } public SplitNode(SequenceNumber branch, int split, EntNode left, EntNode right) { this(branch, split, left, 0, right, 0); } public SplitNode(SequenceNumber branch, int split, EntNode left, EntNode right, int rightDsp) { this(branch, split, left, 0, right, rightDsp); } private int applyDsp(int dsp, int position) { return position + invertDsp(dsp); } protected void assertIsChild(EntNode node) { if (left != node && right != node) { throw new IllegalStateException("unknown child"); } } // assertIsChild: node // (left ~~ node and: [right ~~ node]) ifTrue: [EntError signal: 'unknown child']. // #todo "ensure left !!= right"! protected EntNode basicParentSplit() { return this; } // basicSplayFor: matchingBranch // | parent grandParent newSelf | // parent := self parentSplit: matchingBranch. // parent isNil ifTrue: [^self]. // grandParent := parent parentSplit: matchingBranch. // newSelf := parent left == self // ifTrue: // [(grandParent notNil and: [parent = grandParent left]) // ifTrue: [parent := grandParent singleRotateLeftFor: matchingBranch]. // parent singleRotateLeftFor: matchingBranch] // ifFalse: // [(grandParent notNil and: [parent = grandParent right]) // ifTrue: [parent := grandParent singleRotateRightFor: matchingBranch]. // parent singleRotateRightFor: matchingBranch]. // newSelf basicSplayFor: matchingBranch. // ^newSelf! // // childFor: position do: duadic // | child dsp dspPosition | // (self isLeft: position) // ifTrue: // [child := self left. // dsp := self leftDsp] // ifFalse: // [child := self right. // dsp := self rightDsp]. // dspPosition := self applyDsp: dsp to: position. // ^duadic value: child value: dspPosition.! // public List children() { List list = new ArrayList(2); list.add(left); list.add(right); return list; } // children // ^Array with: self left with: self right // ! // // contents // | minElement position | // minElement := self minNode. // position := minElement globalPositionFor: self branch // to: (self singleParentFor: self branch). // ^self contentsFrom: position extent: self count! // // contentsAt: position // ^self childFor: position do: [:child :dspPosition | child contentsAt: dspPosition]! // // contentsFrom: position extent: extent do: operation // position < self split ifTrue: [self left contentsFrom: (self applyDsp: self leftDsp to: position) extent: extent do: operation]. // position + extent > self split ifTrue: [self right contentsFrom: (self applyDsp: self rightDsp to: position) extent: extent do: operation]. // ! // // contentsFrom: position extent: extent into: stream // position < self split ifTrue: [self left contentsFrom: (self applyDsp: self leftDsp to: position) extent: extent into: stream]. // position + extent > self split ifTrue: [self right contentsFrom: (self applyDsp: self rightDsp to: position) extent: extent into: stream]. // ! public int count() { return left.count() + right.count(); } protected void setDspForChild(int dsp, EntNode node) { assertIsChild(node); if (left == node) { leftDsp = dsp; } else if (right == node) { rightDsp = dsp; } } // dsp: dsp forChild: node // self assertIsChild: node. // left == node ifTrue: [self leftDsp: dsp]. // right == node ifTrue: [self rightDsp: dsp]! // // dspForChild: node // self assertIsChild: node. // left == node ifTrue: [^self leftDsp]. // right == node ifTrue: [^self rightDsp]! protected int dspForChild(EntNode node) { if (left == node) { return getLeftDsp(); } else if (right == node) { return getRightDsp(); } else { throw new IllegalArgumentException("unknown child"); } } // // duplicateFor: duplicateBranch // "Answer a copy of the receiver if self isn't of the required revision. // The duplicate connects to self children, but has no parents set." // // self ensureCompatibleFor: duplicateBranch. // #todo. "perhaps ^self in this case?" // (self isSameFor: duplicateBranch) ifTrue: [^self]. // ^self class // branch: duplicateBranch // split: self split // left: self left // leftDsp: self leftDsp // right: self right // rightDsp: self rightDsp! public EntNode duplicateFor(SequenceNumber duplicateBranch) throws NonCompatibleBranchException { ensureCompatibleFor(duplicateBranch); //TODO perhaps return this; in this case? if (isSameFor(duplicateBranch)) { return this; } return new SplitNode(duplicateBranch, getSplit(), getLeft(), getLeftDsp(), getRight(), getRightDsp()); } // // firstNodeFrom: position extent: extent shouldSplit: shouldSplit // ^self childFor: position // do: // [:child :dspPosition | // child // firstNodeFrom: dspPosition // extent: extent // shouldSplit: shouldSplit]! // // insert: dataLeaf at: position root: root // ^self childFor: position do: [:child :dspPosition | child insert: dataLeaf at: dspPosition root: root].! // // invertDsp: dsp // ^dsp negated! protected int invertDsp(int dsp) { return -dsp; } // // isLeft: position // ^position < self split! public EntNode getLeft() { return left; } public void setLeft(EntNode node) { if (left == node) return; if (left != null) left.removeFromParent(this); left = node; node.addToParent(this); } public int getLeftDsp() { return leftDsp; } // nodeAt: position // ^self childFor: position do: [:child :dspPosition | child nodeAt: dspPosition]! // // removeChild: existingChild branch: newBranch // | parent duplicate | // self assertIsChild: existingChild. // (right == existingChild and: [(right isMaxNodeFor: newBranch) not]) // ifTrue: // ["Splay to toggle childs location into one that we can handle" // // ^existingChild removeFor: newBranch]. // "duplicate self and parents chain to root, then just use the duplicates" // #todo. " only need to duplicate if node is being shared with outher versions" // duplicate := (self isSameFor: newBranch) // ifTrue: // ["existingChild" // // self] // ifFalse: [self duplicateWithParentsFor: newBranch]. // parent := duplicate singleParentFor: newBranch. // duplicate left == existingChild // ifTrue: // [parent == (duplicate rootFor: newBranch) // ifTrue: [duplicate removeChildLeftFromRoot] // ifFalse: [duplicate removeChildLeft]] // ifFalse: // [self assert: [duplicate right == existingChild]. // duplicate removeChildRightMaxElement]! protected void removeChildLeft() throws NonCompatibleBranchException { // Assumed to be a duplicate by this point EntNode parent = singleParentFor(branch); parent.setDspForChild(parent.dspForChild(this) + rightDsp, this); parent.replaceChild(this, right); right.removeFromParent(this); SplitNode rootChild = (SplitNode)right.rootFor(branch).getChild(); rootChild.rightDsp = rootChild.rightDsp - left.count(); } // removeChildLeft // "Assumed to be a duplicate by this point" // // | parent rootChild | // parent := self singleParentFor: self branch. // parent dsp: (parent dspForChild: self) + self rightDsp forChild: self. // parent replaceChild: self with: self right. // self right removeFromParent: self. // rootChild := (self right rootFor: self branch) child. // rootChild rightDsp: rootChild rightDsp - self left count! protected void removeChildLeftFromRoot() { EntNode parent = singleParentFor(branch); parent.setDspForChild(parent.dspForChild(this) + rightDsp - left.count(), this); parent.replaceChild(this, right); right.removeFromParent(this); } // removeChildLeftFromRoot // | parent | // parent := self singleParentFor: self branch. // parent dsp: (parent dspForChild: self) + self rightDsp - self left count forChild: self. // parent replaceChild: self with: self right. // self right removeFromParent: self! // removeChildRightMaxElement // | parent | // parent := self singleParentFor: self branch. // parent dsp: (parent dspForChild: self) + self leftDsp forChild: self. // parent replaceChild: self with: self left. // self left removeFromParent: self! // protected void replaceChild(EntNode existingChild, EntNode newChild) { assertIsChild(existingChild); if (left == existingChild) { setLeft(newChild); } else if (right == newChild) { setRight(newChild); } } // replaceChild: existingChild with: newChild // self assertIsChild: existingChild. // left == existingChild ifTrue: [self left: newChild]. // right == existingChild ifTrue: [self right: newChild]! // // right // ^right! public EntNode getRight() { return right; } public void setRight(EntNode node) { if (right == node) return; if (right != null) right.removeFromParent(this); right = node; node.addToParent(this); } // // right: aNode // right == aNode ifTrue: [^self]. // right notNil ifTrue: [right removeFromParent: self]. // right := aNode. // aNode addToParent: self! // // rightDsp // ^rightDsp! public int getRightDsp() { return rightDsp; } // // rightDsp: anObject // rightDsp := anObject! // // singleRotateLeftFor: matchingBranch // | node2 b c d e | // node2 := self left. // self assert: [node2 isMemberOf: self class]. // #todo. "mess!! + dont have to duplicate every different root branching off at this point" // (self isSameFor: node2 branch) // ifFalse: // [| myNewNode2 | // self assert: [node2 branch < self branch]. // node2 parents asArray do: // [:node2Parent | // | newNode2 | // node2Parent ~~ self // ifTrue: // [newNode2 := node2 duplicateFor: node2Parent branch. // node2Parent replaceChild: node2 with: newNode2]]. // myNewNode2 := node2 duplicateFor: self branch. // self replaceChild: node2 with: myNewNode2. // ^self singleRotateLeftFor: matchingBranch]. // node2 parents asArray do: // [:node2Parent | // | newNode2 | // node2Parent ~~ self // ifTrue: // [newNode2 := node2 duplicateFor: node2Parent branch. // node2Parent replaceChild: node2 with: newNode2]]. // "parent := self singleParent: matchingRevision." // "get existing dsp's" // "a := parent dspForChild: self." // b := self leftDsp. // c := self rightDsp. // d := self left leftDsp. // e := self left rightDsp. // "rotate left child (node2) to become parent of self" // self left: node2 right. // "parent replaceChild: self with: node2." // "update all dsps" // self parents do: // [:parent | // | a | // a := parent dspForChild: self. // parent replaceChild: self with: node2. // parent dsp: a + b forChild: node2]. // node2 right: self. // node2 leftDsp: d. // node2 rightDsp: b negated. // self leftDsp: b + e. // self rightDsp: c. // ^node2! // // singleRotateRightFor: matchingBranch // | node2 b c d e | // node2 := self right. // self assert: [node2 isMemberOf: self class]. // #todo. "mess!! + dont have to duplicate every different root branching off at this point" // (self isSameFor: node2 branch) // ifFalse: // [| myNewNode2 | // self assert: [node2 branch < self branch]. // node2 parents asArray do: // [:node2Parent | // | newNode2 | // node2Parent ~~ self // ifTrue: // [newNode2 := node2 duplicateFor: node2Parent branch. // node2Parent replaceChild: node2 with: newNode2]]. // myNewNode2 := node2 duplicateFor: self branch. // self replaceChild: node2 with: myNewNode2. // ^self singleRotateRightFor: matchingBranch]. // node2 parents asArray do: // [:node2Parent | // | newNode2 | // node2Parent ~~ self // ifTrue: // [newNode2 := node2 duplicateFor: node2Parent branch. // node2Parent replaceChild: node2 with: newNode2]]. // "parent := self singleParent: matchingRevision." // "get existing dsp's" // "a := parent dspForChild: self." // b := self leftDsp. // c := self rightDsp. // d := self right leftDsp. // e := self right rightDsp. // "rotate right child (node2) to become parent of self" // self right: node2 left. // "parent replaceChild: self with: node2." // "update all dsps" // self parents do: // [:parent | // | a | // a := parent dspForChild: self. // parent replaceChild: self with: node2. // parent dsp: a + c forChild: node2]. // node2 left: self. // node2 leftDsp: c negated. // node2 rightDsp: e. // node2 left leftDsp: b. // node2 left rightDsp: c + d. // ^node2! // // split // ^split! public int getSplit() { return split; } // // split: anObject // split := anObject! // // transclusionsFrom: position extent: extent found: transclusions // position < self split ifTrue: [self left transclusionsFrom: (self applyDsp: self leftDsp to: position) extent: extent found: transclusions]. // position + extent > self split ifTrue: [self right transclusionsFrom: (self applyDsp: self rightDsp to: position) extent: extent found: transclusions]. // ! ! // !SplitNode categoriesFor: #applyDsp:to:!private! ! // !SplitNode categoriesFor: #assertIsChild:!private! ! // !SplitNode categoriesFor: #basicParentSplit!accessing!private! ! // !SplitNode categoriesFor: #basicSplayFor:!private! ! // !SplitNode categoriesFor: #childFor:do:!private! ! // !SplitNode categoriesFor: #children!public! ! // !SplitNode categoriesFor: #contents!public! ! // !SplitNode categoriesFor: #contentsAt:!public! ! // !SplitNode categoriesFor: #contentsFrom:extent:do:!accessing!public! ! // !SplitNode categoriesFor: #contentsFrom:extent:into:!accessing!public! ! // !SplitNode categoriesFor: #count!accessing!public! ! // !SplitNode categoriesFor: #dsp:forChild:!private! ! // !SplitNode categoriesFor: #dspForChild:!private! ! // !SplitNode categoriesFor: #duplicateFor:!private! ! // !SplitNode categoriesFor: #firstNodeFrom:extent:shouldSplit:!public! ! // !SplitNode categoriesFor: #insert:at:root:!public! ! // !SplitNode categoriesFor: #invertDsp:!private! ! // !SplitNode categoriesFor: #isLeft:!public! ! // !SplitNode categoriesFor: #left!accessing!private! ! // !SplitNode categoriesFor: #left:!accessing!private! ! // !SplitNode categoriesFor: #leftDsp!accessing!private! ! // !SplitNode categoriesFor: #leftDsp:!accessing!private! ! // !SplitNode categoriesFor: #nodeAt:!public! ! // !SplitNode categoriesFor: #removeChild:branch:!public! ! // !SplitNode categoriesFor: #removeChildLeft!private! ! // !SplitNode categoriesFor: #removeChildLeftFromRoot!private! ! // !SplitNode categoriesFor: #removeChildRightMaxElement!private! ! // !SplitNode categoriesFor: #replaceChild:with:!public! ! // !SplitNode categoriesFor: #right!accessing!private! ! // !SplitNode categoriesFor: #right:!accessing!private! ! // !SplitNode categoriesFor: #rightDsp!accessing!private! ! // !SplitNode categoriesFor: #rightDsp:!accessing!private! ! // !SplitNode categoriesFor: #singleRotateLeftFor:!private! ! // !SplitNode categoriesFor: #singleRotateRightFor:!private! ! // !SplitNode categoriesFor: #split!accessing!private! ! // !SplitNode categoriesFor: #split:!accessing!private! ! // !SplitNode categoriesFor: #transclusionsFrom:extent:found:!accessing!public! ! // // // } --- NEW FILE: CollectionLeaf.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import org.abora.ash.content.BeCollectionHolder; import org.abora.ash.space.IntegerRegion; /** */ public class CollectionLeaf extends LeafNode { protected BeCollectionHolder collectionHolder; protected IntegerRegion collectionRegion; public CollectionLeaf(SequenceNumber branch, int startPosition, byte[] contents) { super(branch, startPosition); //@todo } // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // LeafNode subclass: #CollectionLeaf // instanceVariableNames: 'collectionHolder collectionRegion' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // CollectionLeaf guid: (GUID fromString: '{7CADDDFF-7DC3-488E-B703-E8B48954E7C9}')! // CollectionLeaf comment: ''! // !CollectionLeaf categoriesForClass!Kernel-Objects! ! // !CollectionLeaf methodsFor! // // collectionHolder // ^collectionHolder! // // collectionHolder: aBeCollectionHolder // collectionHolder notNil ifTrue: [collectionHolder removeParent: self]. // collectionHolder := aBeCollectionHolder. // collectionHolder notNil ifTrue: [collectionHolder addParent: self]! // // collectionRegion // ^collectionRegion! // // collectionRegion: anObject // collectionRegion := anObject! // // contentsAtConstrainedIndex: index // ^self collectionHolder collection at: index + collectionRegion startPosition - 1! // // contentsFrom: position extent: extent do: operation // | startIndex endIndex | // startIndex := position - self startPosition + 1. // endIndex := position - self startPosition + extent . // ^(startIndex max: 1) to: (endIndex min: self count) // do: [:index | operation value: (self contentsAtConstrainedIndex: index)]! // // contentsFrom: position extent: extent into: stream // | startIndex endIndex constrainedStartIndex constrainedEndIndex | // startIndex := position - self startPosition + 1. // endIndex := position - self startPosition + extent. // constrainedStartIndex := startIndex max: 1. // constrainedEndIndex := endIndex min: self count. // constrainedEndIndex >= constrainedStartIndex // ifTrue: // [stream // next: constrainedEndIndex - constrainedStartIndex + 1 // putAll: collectionHolder collection // startingAt: constrainedStartIndex + collectionRegion startPosition - 1]! // public int count() { return collectionRegion.getExtent(); } // count // ^self collectionRegion extent! // // elements // ^self collectionHolder collection copyFrom: collectionRegion startPosition // to: collectionRegion endPosition! // // replaceWithSplit: newSplit about: elementsPosition // "Answer a new SplitNode with two data children with elements before and equal and after elementsPosition. // NOTE: This operation is unusual in that all parent versions are redirected to point to the replacement split node." // // | splitNode | // splitNode := super replaceWithSplit: newSplit about: elementsPosition. // self collectionHolder: nil. // ^splitNode! // // sharedWith: anotherEdition for: forBranch mappings: mappings // | anotherEditionBranch | // anotherEditionBranch := anotherEdition branch. // self collectionHolder parents do: // [:leaf | // | root | // (leaf collectionRegion intersects: self collectionRegion) // ifTrue: // [root := leaf rootFor: anotherEditionBranch. // (root notNil and: [root edition == anotherEdition]) // ifTrue: // [| intersection selfRegion anotherRegion | // intersection := self collectionRegion intersection: leaf collectionRegion. // selfRegion := IntegerRegion // startPosition: (self globalPositionFor: forBranch) + intersection startPosition // - self collectionRegion startPosition // extent: intersection extent. // anotherRegion := IntegerRegion // startPosition: (leaf globalPositionFor: anotherEditionBranch) + intersection startPosition // - leaf collectionRegion startPosition // extent: intersection extent. // mappings add: (Array with: selfRegion with: anotherRegion)]]]! // // split: newSplit about: elementsPosition // "Private - Answer a new SplitNode with two data children with elements before and equal and after elementsPosition." // // | dataLeft dataRight | // (elementsPosition < 2 or: [elementsPosition > self count]) // ifTrue: [self errorSubscriptBounds: elementsPosition]. // dataLeft := self class // branch: self branch // startPosition: self startPosition // collection: self collectionHolder // region: (IntegerRegion startPosition: collectionRegion startPosition // endPosition: collectionRegion startPosition + elementsPosition - 2). // dataRight := self class // branch: self branch // startPosition: self startPosition + elementsPosition - 1 // collection: self collectionHolder // region: (IntegerRegion // startPosition: collectionRegion startPosition + elementsPosition - 1 // endPosition: collectionRegion endPosition). // ^SplitNode // branch: self branch // split: newSplit // left: dataLeft // right: dataRight! // // transclusions: transclusions // self collectionHolder parents do: // [:leaf | // (leaf collectionRegion intersects: self collectionRegion) // ifTrue: [transclusions addAll: leaf allEditions]]! // // transclusionsFrom: position extent: extent found: transclusions // | startIndex endIndex constrainedStartIndex constrainedEndIndex | // startIndex := position - self startPosition + 1. // endIndex := position - self startPosition + extent. // constrainedStartIndex := startIndex max: 1. // constrainedEndIndex := endIndex min: self count. // constrainedEndIndex >= constrainedStartIndex // ifTrue: // [self collectionHolder parents do: // [:transcluded | // (transcluded collectionRegion intersects: self collectionRegion) // ifTrue: [transclusions addAll: transcluded allEditions]]]! ! // !CollectionLeaf categoriesFor: #collectionHolder!accessing!private! ! // !CollectionLeaf categoriesFor: #collectionHolder:!accessing!private! ! // !CollectionLeaf categoriesFor: #collectionRegion!accessing!private! ! // !CollectionLeaf categoriesFor: #collectionRegion:!accessing!private! ! // !CollectionLeaf categoriesFor: #contentsAtConstrainedIndex:!private! ! // !CollectionLeaf categoriesFor: #contentsFrom:extent:do:!accessing!public! ! // !CollectionLeaf categoriesFor: #contentsFrom:extent:into:!accessing!public! ! // !CollectionLeaf categoriesFor: #count!public! ! // !CollectionLeaf categoriesFor: #elements!accessing!private! ! // !CollectionLeaf categoriesFor: #replaceWithSplit:about:!public! ! // !CollectionLeaf categoriesFor: #sharedWith:for:mappings:!public! ! // !CollectionLeaf categoriesFor: #split:about:!private! ! // !CollectionLeaf categoriesFor: #transclusions:!public! ! // !CollectionLeaf categoriesFor: #transclusionsFrom:extent:found:!accessing!public! ! // // !CollectionLeaf class methodsFor! // // branch: branch startPosition: startPosition collection: dataCollection // ^self // branch: branch // startPosition: startPosition // collection: dataCollection // region: (IntegerRegion startPosition: 1 endPosition: dataCollection collection size)! // // branch: branch startPosition: startPosition collection: dataCollection region: collectionRegion // ^(self basicNew) // branch: branch; // collectionHolder: dataCollection; // collectionRegion: collectionRegion; // startPosition: startPosition; // yourself! // // branch: branch startPosition: startPosition elements: array // self assert: [array isKindOf: Array]. // ^self // branch: branch // startPosition: startPosition // collection: (BeCollectionHolder collection: array)! // // branch: branch startPosition: startPosition from: collectionLeaf // ^self // branch: branch // startPosition: startPosition // collection: collectionLeaf collectionHolder // region: collectionLeaf collectionRegion! ! // !CollectionLeaf class categoriesFor: #branch:startPosition:collection:!public! ! // !CollectionLeaf class categoriesFor: #branch:startPosition:collection:region:!public! ! // !CollectionLeaf class categoriesFor: #branch:startPosition:elements:!public! ! // !CollectionLeaf class categoriesFor: #branch:startPosition:from:!public! ! // } --- NEW FILE: LeafNode.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.Collections; import java.util.List; /** */ public abstract class LeafNode extends ChildNode { protected int startPosition = 0; protected LeafNode(SequenceNumber branch, int startPosition) { super(branch); this.startPosition = startPosition; } // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // ChildNode subclass: #LeafNode // instanceVariableNames: 'startPosition' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // LeafNode guid: (GUID fromString: '{F64D0B1E-54DA-4D5C-97C8-665909D3718D}')! // LeafNode comment: ''! // !LeafNode categoriesForClass!Kernel-Objects! ! // !LeafNode methodsFor! // // basicInsert: dataLeaf at: position root: root // | index | // index := position - startPosition + 1. // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position]. // index = 1 // ifTrue: // ["insert before" // // (self isMinNodeFor: root branch) // ifTrue: [self basicInsertBeforeEnt: dataLeaf root: root] // ifFalse: // [^self // basicInsertBeforeSelf: dataLeaf // at: position // root: root]] // ifFalse: // [index <= self count // ifTrue: // ["split then insert" // // | splitNode | // splitNode := self replaceWithSplit: position about: index. // ^splitNode right // insert: dataLeaf // at: position // root: root] // ifFalse: // [(self isMaxNodeFor: root branch) // ifTrue: [self basicInsertAfterEnt: dataLeaf root: root] // ifFalse: [self errorSubscriptBounds: position]]]! // // basicInsertAfterEnt: dataLeaf root: root // "add to end of entire ent" // // | splitNode | // splitNode := SplitNode // branch: root branch // split: dataLeaf startPosition // left: root child // leftDsp: root dsp // right: dataLeaf. // root child: splitNode. // root dsp: 0! // // basicInsertBeforeEnt: dataLeaf root: root // "add to beginning of entire ent" // // | splitNode | // splitNode := SplitNode // branch: root branch // split: dataLeaf count + dataLeaf startPosition // left: dataLeaf // right: root child // rightDsp: dataLeaf count + root dsp. // root child: splitNode. // root dsp: 0! // // basicInsertBeforeSelf: dataLeaf at: position root: root // "add before self" // // | parent newBranch | // newBranch := root branch. // parent := self parentSplit: newBranch. // self assert: [parent notNil]. // self assert: [parent left == self or: [parent right == self]]. // (parent left == self or: [(parent parentSplit: newBranch) isNil]) // ifTrue: // [| a b | // (root child isSameFor: newBranch) ifTrue: [root child right removeFromParent: root child]. // a := SplitNode // branch: newBranch // split: dataLeaf startPosition + dataLeaf count // left: dataLeaf // right: root child right // rightDsp: dataLeaf count + root child rightDsp + root dsp. // (root child isSameFor: newBranch) ifTrue: [root child left removeFromParent: root child]. // b := SplitNode // branch: newBranch // split: dataLeaf startPosition // left: root child left // leftDsp: root child leftDsp + root dsp // right: a. // root child: b. // root dsp: 0] // ifFalse: // ["Force self to other side of parent by splaying" // // parent basicSplayFor: newBranch. // ^self // basicInsert: dataLeaf // at: position // root: root]! // // basicSplayFor: matchingBranch // ^(self singleParentFor: matchingBranch) basicSplayFor: matchingBranch! // // children // ^#() // ! public List children() { return Collections.EMPTY_LIST; } // // constrainedIndexFrom: position // | index | // index := position - self startPosition + 1. // (index < 1 or: [index > self count]) ifTrue: [self errorSubscriptBounds: index]. // ^index! // // contents // ^self contentsFrom: self startPosition extent: self count! // // contentsAt: position // | index | // index := self constrainedIndexFrom: position. // ^self contentsAtConstrainedIndex: index! // // contentsAtConstrainedIndex: index // self subclassResponsibility! // // duplicateFor: newBranch // self shouldNotImplement! public EntNode duplicateFor(SequenceNumber newBranch) { throw new UnsupportedOperationException("duplicateFor"); } // // firstNodeFrom: position extent: extent shouldSplit: shouldSplit // | index | // index := self constrainedIndexFrom: position. // shouldSplit ifFalse: [^self]. // ^index > 1 // ifTrue: // [| newParent | // newParent := self replaceWithSplit: position about: index. // newParent right // firstNodeFrom: position // extent: extent // shouldSplit: shouldSplit] // ifFalse: // [extent < self count // ifTrue: // [| newParent | // newParent := self replaceWithSplit: position + extent about: extent + 1. // newParent left] // ifFalse: [self]]! // // globalPositionFor: matchingBranch // ^self globalPositionFor: matchingBranch to: nil! // // globalPositionFor: matchingBranch to: topParent // | position node parent | // position := self startPosition. // node := self. // [(parent := node singleParentFor: matchingBranch) ~~ topParent] whileTrue: // [position := position + (parent dspForChild: node). // node := parent]. // ^position! // // globalRegionFor: forBranch // ^IntegerRegion startPosition: (self globalPositionFor: forBranch) extent: self count! // // insert: dataLeaf at: position root: root // | index | // index := position - startPosition + 1. // (index < 1 or: [index > (self count + 1)]) ifTrue: [self errorSubscriptBounds: position]. // self basicSplayFor: root branch. // self // basicInsert: dataLeaf // at: position // root: root! // // isMaxNodeFor: matchingBranch // | node parent | // node := self. // [(parent := node parentSplit: matchingBranch) notNil] whileTrue: // [parent right == node ifFalse: [^false]. // node := parent]. // ^true! // // isMinNodeFor: matchingBranch // | node parent | // node := self. // [(parent := node parentSplit: matchingBranch) notNil] whileTrue: // [parent left == node ifFalse: [^false]. // node := parent]. // ^true! // // maxNode // ^self! // // minNode // ^self! // // nodeAt: position // | index | // index := self constrainedIndexFrom: position. // ^self! // // removeFor: newBranch // self basicSplayFor: newBranch. // (self singleParentFor: newBranch) removeChild: self branch: newBranch! // // replaceWithSplit: newSplit about: elementsPosition // "Answer a new SplitNode with two data children with elements before and equal and after elementsPosition. // NOTE: This operation is unusual in that all parent versions are redirected to point to the replacement split node." // // | splitNode | // splitNode := self split: newSplit about: elementsPosition. // self parents do: [:parent | parent replaceChild: self with: splitNode]. // self assert: [self parents isEmpty]. // ^splitNode! // // split: newSplit about: elementsPosition // self subclassResponsibility! // // startPosition // ^startPosition! // // startPosition: anObject // startPosition := anObject! ! // !LeafNode categoriesFor: #basicInsert:at:root:!private! ! // !LeafNode categoriesFor: #basicInsertAfterEnt:root:!private! ! // !LeafNode categoriesFor: #basicInsertBeforeEnt:root:!private! ! // !LeafNode categoriesFor: #basicInsertBeforeSelf:at:root:!private! ! // !LeafNode categoriesFor: #basicSplayFor:!private! ! // !LeafNode categoriesFor: #children!public! ! // !LeafNode categoriesFor: #constrainedIndexFrom:!private! ! // !LeafNode categoriesFor: #contents!public! ! // !LeafNode categoriesFor: #contentsAt:!public! ! // !LeafNode categoriesFor: #contentsAtConstrainedIndex:!public! ! // !LeafNode categoriesFor: #duplicateFor:!public! ! // !LeafNode categoriesFor: #firstNodeFrom:extent:shouldSplit:!public! ! // !LeafNode categoriesFor: #globalPositionFor:!public! ! // !LeafNode categoriesFor: #globalPositionFor:to:!private! ! // !LeafNode categoriesFor: #globalRegionFor:!public! ! // !LeafNode categoriesFor: #insert:at:root:!public! ! // !LeafNode categoriesFor: #isMaxNodeFor:!public! ! // !LeafNode categoriesFor: #isMinNodeFor:!public! ! // !LeafNode categoriesFor: #maxNode!public! ! // !LeafNode categoriesFor: #minNode!public! ! // !LeafNode categoriesFor: #nodeAt:!public! ! // !LeafNode categoriesFor: #removeFor:!public! ! // !LeafNode categoriesFor: #replaceWithSplit:about:!public! ! // !LeafNode categoriesFor: #split:about:!public! ! // !LeafNode categoriesFor: #startPosition!accessing!private! ! // !LeafNode categoriesFor: #startPosition:!accessing!private! ! // // // protected void replaceChild(EntNode existingChild, EntNode newChild) { throw new UnsupportedOperationException("no children"); } protected void setDspForChild(int dsp, EntNode child) { throw new UnsupportedOperationException("no children"); } } --- NEW FILE: NonCompatibleBranchException.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; /** */ public class NonCompatibleBranchException extends EntException { /** * Constructor for NonCompatibleBranchException. */ public NonCompatibleBranchException() { super(); } /** * Constructor for NonCompatibleBranchException. * @param message */ public NonCompatibleBranchException(String message) { super(message); } /** * Constructor for NonCompatibleBranchException. * @param message * @param cause */ public NonCompatibleBranchException(String message, Throwable cause) { super(message, cause); } /** * Constructor for NonCompatibleBranchException. * @param cause */ public NonCompatibleBranchException(Throwable cause) { super(cause); } } --- NEW FILE: ContentLeaf.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import org.abora.ash.content.BeContentElement; /** */ public class ContentLeaf extends LeafNode { protected BeContentElement contentElement; // "Filed out from Dolphin Smalltalk 2002 release 5.00"! // // LeafNode subclass: #ContentLeaf // instanceVariableNames: 'contentElement' // classVariableNames: '' // poolDictionaries: '' // classInstanceVariableNames: ''! // ContentLeaf guid: (GUID fromString: '{E75C38F4-C73A-4AF8-A275-2FD6FBDD3F4C}')! // ContentLeaf comment: ''! // !ContentLeaf categoriesForClass!Kernel-Objects! ! // !ContentLeaf methodsFor! // // contentElement // ^contentElement! // // contentElement: aContentElement // contentElement notNil ifTrue: [contentElement removeParent: self]. // contentElement := aContentElement. // contentElement notNil ifTrue: [contentElement addParent: self]. // ! // // contentsAtConstrainedIndex: index // self assert: [index = 1]. // ^self contentElement! // // contentsFrom: position extent: extent do: operation // | startIndex endIndex limitedExtent | // startIndex := position - self startPosition + 1 max: 1. // endIndex := position - self startPosition + extent min: self count. // limitedExtent := endIndex - startIndex + 1. // ^limitedExtent > 0 // ifTrue: // [operation value: self contentElement] // ifFalse: ['']! // // contentsFrom: position extent: extent into: stream // | startIndex endIndex limitedExtent | // startIndex := position - self startPosition + 1 max: 1. // endIndex := position - self startPosition + extent min: self count. // limitedExtent := endIndex - startIndex + 1. // limitedExtent > 0 ifTrue: [stream nextPut: self contentElement]! // // count // ^1! // public int count() { return 1; } // printOn: aStream // aStream nextPutAll: 'Data(branch='. // self branch displayOn: aStream. // aStream nextPutAll: ', pos='. // self startPosition printOn: aStream. // aStream nextPutAll: ', data='. // self contentElement printOn: aStream. // aStream nextPutAll: ')'! // // sharedWith: anotherEdition for: forBranch mappings: mappings // | anotherEditionRevision globalRegion | // anotherEditionRevision := anotherEdition branch. // self contentElement parents do: // [:leaf | // | root | // root := leaf rootFor: anotherEditionRevision. // (root notNil and: [root edition == anotherEdition]) // ifTrue: // [| anotherRegion | // globalRegion isNil ifTrue: [globalRegion := self globalRegionFor: forBranch]. // anotherRegion := leaf globalRegionFor: anotherEditionRevision. // mappings add: (Array with: globalRegion with: anotherRegion)]]! // // split: newSplit about: elementsPosition // "Private - Answer a new SplitNode with two data children with elements before and equal and after elementsPosition." // // self shouldNotImplement! // // transclusions: transclusions // self contentElement parents do: [:leaf | transclusions addAll: leaf allEditions]! // // transclusionsFrom: position extent: extent found: transclusions // | startIndex endIndex limitedExtent | // startIndex := position - self startPosition + 1 max: 1. // endIndex := position - self startPosition + extent min: self count. // limitedExtent := endIndex - startIndex + 1. // limitedExtent > 0 ifTrue: [self transclusions: transclusions]! ! // !ContentLeaf categoriesFor: #contentElement!accessing!private! ! // !ContentLeaf categoriesFor: #contentElement:!accessing!private! ! // !ContentLeaf categoriesFor: #contentsAtConstrainedIndex:!public! ! // !ContentLeaf categoriesFor: #contentsFrom:extent:do:!public! ! // !ContentLeaf categoriesFor: #contentsFrom:extent:into:!public! ! // !ContentLeaf categoriesFor: #count!public! ! // !ContentLeaf categoriesFor: #printOn:!public! ! // !ContentLeaf categoriesFor: #sharedWith:for:mappings:!public! ! // !ContentLeaf categoriesFor: #split:about:!private! ! // !ContentLeaf categoriesFor: #transclusions:!public! ! // !ContentLeaf categoriesFor: #transclusionsFrom:extent:found:!public! ! // // !ContentLeaf class methodsFor! // // branch: branch startPosition: startPosition contentElement: contentElement // ^(self basicNew) // branch: branch; // startPosition: startPosition; // contentElement: contentElement; // yourself! public ContentLeaf(SequenceNumber branch, int startPosition, BeContentElement contentElement) { super(branch, startPosition); this.contentElement = contentElement; } // // branch: branch startPosition: startPosition from: contentLeaf // ^self // branch: branch // startPosition: startPosition // contentElement: contentLeaf contentElement! // // icon // ^Character icon! ! // !ContentLeaf class categoriesFor: #branch:startPosition:contentElement:!public! ! // !ContentLeaf class categoriesFor: #branch:startPosition:from:!public! ! // !ContentLeaf class categoriesFor: #icon!public! ! // } --- NEW FILE: EntNode.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.Iterator; import java.util.List; import org.abora.ash.engine.AboraObject; /** */ public abstract class EntNode extends AboraObject { protected SequenceNumber branch; public EntNode(SequenceNumber branch) { this.branch = branch; } protected abstract void addToParent(EntNode node); // allEditions // ^self allRoots collect: [:root | root edition]! // // allRoots // | roots | // roots := IdentitySet new. // self allRoots: roots. // ^roots! // // allRoots: allRoots // self parents do: [:parent | parent allRoots: allRoots]! // protected EntNode basicParentSplit() { return null; } // basicParentSplit // ^nil! // public SequenceNumber getBranch() { return branch; } // branch // ^branch! // // branch: anObject // branch := anObject! // protected abstract List children(); // children // self subclassResponsibility! // // contents // self subclassResponsibility! // // contentsAt: position // self subclassResponsibility! // // contentsFrom: position extent: extent // | contents | // #todo "max:". // extent < 0 ifTrue: [self halt]. // contents := WriteStream on: (Array new: (extent max: 0)). // self contentsFrom: position extent: extent into: contents. // " self contentsFrom: position extent: extent do: [:char | contents nextPut: char]." // ^contents contents! // // contentsFrom: position extent: extent into: stream // self subclassResponsibility! // public abstract int count(); // count // self subclassResponsibility! // //TODO shold this be in a ParentNode interface? protected abstract int dspForChild(EntNode node); protected abstract void setDspForChild(int dsp, EntNode child); protected abstract EntNode duplicateFor(SequenceNumber newBranch) throws EntException; // duplicateFor: newBranch // self subclassResponsibility! // // duplicateWithParentsFor: newBranch // | duplicate parent parentDuplicate | // duplicate := self duplicateFor: newBranch. // parent := self singleParentFor: newBranch. // parent notNil // ifTrue: // [parentDuplicate := parent duplicateWithParentsFor: newBranch. // parentDuplicate replaceChild: self with: duplicate]. // ^duplicate! // protected void ensureCompatibleFor(SequenceNumber matchingBranch) throws NonCompatibleBranchException { if (!isCompatibleFor(matchingBranch)) { throw new NonCompatibleBranchException(); } } // ensureCompatibleFor: matchingBranch // (self isCompatibleFor: matchingBranch) // ifFalse: [EntError signal: 'not-compatible ent revision']! // protected void ensureSameFor(SequenceNumber matchingBranch) throws NonSameBranchException { if (!isSameFor(matchingBranch)) { throw new NonSameBranchException(); } } // ensureSameFor: matchingBranch // (self isSameFor: matchingBranch) ifFalse: [EntError signal: 'not-same ent revision']! // protected EntNode findBestParentMatchFor(SequenceNumber matchingBranch) { EntNode singleParent = null; for (Iterator i = getParents().iterator(); i.hasNext(); ) { EntNode possibleParent = (EntNode) i.next(); if (possibleParent.isSameFor(matchingBranch)) { return possibleParent; } if (possibleParent.isCompatibleFor(matchingBranch) && ( singleParent == null || !possibleParent.getBranch().isBranchingAfter(singleParent.getBranch()))) { singleParent = possibleParent; } } return singleParent; } // findBestParentMatchFor: matchingBranch // | singleParent | // singleParent := nil. // self parents do: // [:possibleParent | // (possibleParent isSameFor: matchingBranch) ifTrue: [^possibleParent]. // ((possibleParent isCompatibleFor: matchingBranch) // and: [singleParent isNil or: [possibleParent branch > singleParent branch]]) // ifTrue: [singleParent := possibleParent]]. // ^singleParent! // protected boolean isCompatibleFor(SequenceNumber matchingBranch) { return branch.isBranchingBeforeOrEqual(matchingBranch); } // isCompatibleFor: matchingBranch // ^self branch isBeforeOrEqual: matchingBranch! // protected boolean isSameFor(SequenceNumber matchingBranch) { //@todo do we actually want something more specific - ie trailing zeros return branch.equals(matchingBranch); } // isSameFor: matchingBranch // ^self branch = matchingBranch! // protected EntNode maxNode() { List list = children(); return (EntNode)list.get(list.size() - 1); } // maxNode // ^self children last maxNode! // protected EntNode minNode() { return (EntNode)children().get(0); } // minNode // ^self children first minNode! // protected abstract List getParents(); // parents // self subclassResponsibility! // // parentSplit: matchingBranch // | parent | // parent := self singleParentFor: matchingBranch. // ^parent notNil ifTrue: [parent basicParentSplit] ifFalse: [nil]! // protected abstract void removeFromParent(EntNode oldParent); protected abstract void replaceChild(EntNode existingChild, EntNode newChild); protected RootNode rootFor(SequenceNumber matchingBranch) throws NonCompatibleBranchException { EntNode parent = singleParentFor(matchingBranch); //TODO null parent might indicate somethingt gone wrong if (parent != null) { return parent.rootFor(matchingBranch); } else { return null; } } // rootFor: matchingBranch // | parent | // parent := self singleParentFor: matchingBranch. // #todo. "null parent might indicate something gong wrong" // ^parent notNil ifTrue: [parent rootFor: matchingBranch] ifFalse: [nil]! // // sharedWith: anotherEdition for: forBranch mappings: mappings // self children do: // [:child | // child // sharedWith: anotherEdition // for: forBranch // mappings: mappings]! // protected EntNode singleParentFor(SequenceNumber matchingBranch) { if (getParents().isEmpty()) { return null; } else { EntNode singleParent = findBestParentMatchFor(matchingBranch); //TODO investigate the commenting out of the following //self assert: [singleParent notNil] return singleParent; } } // singleParentFor: matchingBranch // ^self parents isEmpty // ifTrue: [nil] // ifFalse: // [| singleParent | // singleParent := self findBestParentMatchFor: matchingBranch. // #todo. "investigate the commenting out of the following" // "self assert: [singleParent notNil]." // singleParent]! // // transclusions: transclusions // self children do: [:child | child transclusions: transclusions]! ! // !EntNode categoriesFor: #allEditions!public! ! // !EntNode categoriesFor: #allRoots!public! ! // !EntNode categoriesFor: #allRoots:!private! ! // !EntNode categoriesFor: #basicParentSplit!private! ! // !EntNode categoriesFor: #branch!accessing!public! ! // !EntNode categoriesFor: #branch:!accessing!private! ! // !EntNode categoriesFor: #children!public! ! // !EntNode categoriesFor: #contents!public! ! // !EntNode categoriesFor: #contentsAt:!public! ! // !EntNode categoriesFor: #contentsFrom:extent:!public! ! // !EntNode categoriesFor: #contentsFrom:extent:into:!public! ! // !EntNode categoriesFor: #count!public! ! // !EntNode categoriesFor: #duplicateFor:!private! ! // !EntNode categoriesFor: #duplicateWithParentsFor:!private! ! // !EntNode categoriesFor: #ensureCompatibleFor:!private! ! // !EntNode categoriesFor: #ensureSameFor:!private! ! // !EntNode categoriesFor: #findBestParentMatchFor:!private! ! // !EntNode categoriesFor: #isCompatibleFor:!private! ! // !EntNode categoriesFor: #isSameFor:!private! ! // !EntNode categoriesFor: #maxNode!public! ! // !EntNode categoriesFor: #minNode!public! ! // !EntNode categoriesFor: #parents!public! ! // !EntNode categoriesFor: #parentSplit:!private! ! // !EntNode categoriesFor: #rootFor:!private! ! // !EntNode categoriesFor: #sharedWith:for:mappings:!public! ! // !EntNode categoriesFor: #singleParentFor:!private! ! // !EntNode categoriesFor: #transclusions:!public! ! // // !EntNode class methodsFor! // // basicNew // ^(super basicNew) // initialize; // yourself! // // new // ^self shouldNotImplement! ! // !EntNode class categoriesFor: #basicNew!public! ! // !EntNode class categoriesFor: #new!public! ! // // } --- NEW FILE: SequenceNumber.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.Iterator; /** */ public class SequenceNumber implements Comparable { private final int digits[]; public SequenceNumber(int digit1) { digits = new int[] {digit1}; } public SequenceNumber(int digit1, int digit2) { digits = new int[] {digit1, digit2}; } public SequenceNumber(int digit1, int digit2, int digit3) { digits = new int[] {digit1, digit2, digit3}; } public SequenceNumber(int[] uncapturedDigits) { //@todo support empty digits? digits = new int[uncapturedDigits.length]; for (int i = 0; i < uncapturedDigits.length; i++) { int digit = uncapturedDigits[i]; digits[i] = digit; } } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object o) { return compareTo((SequenceNumber) o); } public int compareTo(SequenceNumber n) { if (this == n) return 0; for (DigitInterleavingIterator i = new DigitInterleavingIterator(digits, n.digits); i.hasNext();) { int digit1 = i.nextInt(); int digit2 = i.nextInt(); if (digit1 < digit2) return -1; else if (digit1 > digit2) return 1; } return 0; } public String toString() { StringBuffer buffer = new StringBuffer("SequenceNumber["); for (int i = 0; i < digits.length; i++) { if (i > 0) buffer.append(":"); buffer.append(digits[i]); } buffer.append("]"); return buffer.toString(); } protected class DigitInterleavingIterator implements Iterator { private final int[] digits1; private final int[] digits2; private int nextDigits1 = 0; private int nextDigits2 = 0; public DigitInterleavingIterator(int[] digits1, int[] digits2) { this.digits1 = digits1; this.digits2 = digits2; } public boolean hasNext() { return nextDigits1 < digits1.length || nextDigits2 < digits2.length; } public Object next() { return new Integer(nextInt()); } public int nextInt() { // if (!hasNext()) // throw new NoSuchElementException(); int value = 0; if (nextDigits1 <= nextDigits2) { if (nextDigits1 < digits1.length) { value = digits1[nextDigits1]; } nextDigits1++; } else { if (nextDigits2 < digits2.length) { value = digits2[nextDigits2]; } nextDigits2++; } return value; } public void remove() { throw new UnsupportedOperationException(); } } public SequenceNumber copyWith(int newDigit) { int[] newDigits = new int[digits.length + 1]; for (int i = 0; i < digits.length; i++) { int digit = digits[i]; newDigits[i] = digit; } newDigits[newDigits.length - 1] = newDigit; return new SequenceNumber(newDigits); } public boolean equals(Object o) { if (!(o instanceof SequenceNumber)) return false; return compareTo(o) == 0; } public int hashCode() { int value = 0; for (int i = 0; i < digits.length; i++) { int digit = digits[i]; if (digit != 0) { value = value << 1 | digit; } } return value; } public SequenceNumber incrementLast() { // @todo what if there are now digits? int[] newDigits = new int[digits.length]; for (int i = 0; i < digits.length; i++) { int digit = digits[i]; if (i == digits.length - 1) { digit++; } newDigits[i] = digit; } return new SequenceNumber(newDigits); } // subtractFromInteger: anInteger // "Private - Answer the result of subtracting the receiver from the known integer, // anInteger, by coercing the less general of it and the receiver. Overridden by // subclasses which can implement more efficiently." // // | newDigits | // newDigits := OrderedCollection new. // anInteger asSequenceMagnitude digitsWith: self do: [:digit1 :digit2 | newDigits add: digit1 - digit2]. // ^self class withAll: newDigits asArray. // ! public boolean isBranchingAfter(SequenceNumber n) { return n.isBranchingBefore(this); } public boolean isBranchingBefore(SequenceNumber n) { if (digits.length > n.digits.length) return false; for (int i = 0; i < digits.length - 1; i++) { int digit1 = digits[i]; int digit2 = n.digits[i]; if (digit1 != digit2) return false; } if (digits.length < n.digits.length) { return digits[digits.length - 1] <= n.digits[digits.length - 1]; } else { return digits[digits.length - 1] < n.digits[digits.length - 1]; } } public boolean isBranchingBeforeOrEqual(SequenceNumber n) { return isBranchingBefore(n) || equals(n); } public int[] toIntArray() { int[] newDigits = new int[digits.length]; for (int i = 0; i < digits.length; i++) { int digit = digits[i]; newDigits[i] = digit; } return newDigits; } } --- NEW FILE: ChildNode.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.ArrayList; import java.util.List; /** */ public abstract class ChildNode extends EntNode { //@todo should this be a set? protected List parents = new ArrayList(); protected ChildNode(SequenceNumber branch) { super(branch); } protected void addToParent(EntNode node) { parents.add(node); } protected void removeFromParent(EntNode node) { parents.remove(node); } protected List getParents() { return parents; } protected int dspForChild(EntNode node) { throw new UnsupportedOperationException(); } } --- NEW FILE: RootNode.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.abora.ash.content.BeEdition; /** */ public class RootNode extends EntNode { private EntNode child = null; private int dsp = 0; private final BeEdition edition; public RootNode(BeEdition edition, SequenceNumber branch) { super(branch); this.edition = edition; } public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child) { super(branch); this.edition = edition; this.child = child; } public RootNode(BeEdition edition, SequenceNumber branch, ChildNode child, int dsp) { super(branch); this.edition = edition; this.child = child; this.dsp = dsp; } // allRoots: allRoots // allRoots add: self! // // applyDspTo: position // | dspPosition | // dspPosition := position + (self invertDsp). // ^dspPosition! // protected void assertIsChild(EntNode node) { if (node != child) { throw new IllegalStateException("unknown child"); } } // assertIsChild: node // self child ~~ node ifTrue: [EntError signal: 'unknown child of root']! // // basicSplayFor: matchingBranch // "only called in the case of a single child" // // #todo. // self ensureSameFor: matchingBranch. // ^self child! // public EntNode getChild() { return child; } // child // ^child! // protected void setChild(EntNode node) { if (child == node) { return; } if (child != null) { child.removeFromParent(this); } child = node; //TODO reset dsp if nil? if (node != null) { node.addToParent(this); } } // child: aNodeOrNil // child == aNodeOrNil ifTrue: [^self]. // child notNil ifTrue: [child removeFromParent: self]. // child := aNodeOrNil. // #todo. "reset dsp if nil?" // aNodeOrNil notNil ifTrue: [aNodeOrNil addToParent: self]! // protected List children() { if (!hasChild()) return Collections.EMPTY_LIST; List children = new ArrayList(1); children.add(child); return children; } // children // ^self child notNil ifTrue: [Array with: self child] ifFalse: [#()]! // // contents // ^self contentsFrom: 1 extent: self count! // // contentsAt: position // child notNil // ifTrue: [^self child contentsAt: (self applyDspTo: position)] // ifFalse: [self errorSubscriptBounds: position]! // // contentsFrom: position extent: extent do: operation // ^self child notNil // ifTrue: // [self child // contentsFrom: (self applyDspTo: position) // extent: extent // do: operation] // ifFalse: ['']! // // contentsFrom: position extent: extent into: stream // self child notNil // ifTrue: // [self child // contentsFrom: (self applyDspTo: position) // extent: extent // into: stream] // ifFalse: []! public int count() { return hasChild() ? child.count() : 0; } // // count // ^child notNil ifTrue: [child count] ifFalse: [0]! // public int getDsp() { return dsp; } // dsp // ^dsp! // // dsp: anObject // dsp := anObject! // protected void setDspForChild(int dsp, EntNode node) { assertIsChild(node); this.dsp = dsp; } // dsp: newDsp forChild: node // self assertIsChild: node. // self dsp: newDsp! // protected int dspForChild(EntNode child) { assertIsChild(child); return dsp; } // dspForChild: node // self assertIsChild: node. // ^self dsp! // protected EntNode duplicateFor(SequenceNumber newBranch) throws NonSameBranchException { // Do not duplicate RootNodes at the moment, as this forced to happen on newEdition. // @todo is this the right behaviour - not duplicating? ensureSameFor(newBranch); return this; } // duplicateFor: newBranch // "Do not duplicate RootNodes at the moment, as this forced to happen on newEdition." // // "is this the right behaviour - not duplicating?" // // #todo. // self ensureSameFor: newBranch. // ^self! // public BeEdition getEdition() { return edition; } // edition // ^edition! // // edition: anObject // edition := anObject! // // firstNodeFrom: position extent: extent shouldSplit: shouldSplit // child notNil // ifTrue: // [^self child // firstNodeFrom: (self applyDspTo: position) // extent: extent // shouldSplit: shouldSplit] // ifFalse: [self errorSubscriptBounds: position]! // public boolean hasChild() { return child != null; } // hasChild // ^child notNil! // // initialize // super initialize. // // self dsp: 0.! // // insert: dataLeaf // "what about dsp?" // // #todo. // self ensureSameFor: dataLeaf branch. // child isNil // ifTrue: // [dataLeaf startPosition = 1 // ifTrue: // [child := dataLeaf. // dataLeaf addToParent: self] // ifFalse: [self errorSubscriptBounds: dataLeaf startPosition]] // ifFalse: // [self child // insert: dataLeaf // at: (self applyDspTo: dataLeaf startPosition) // root: self]! // // invertDsp // ^dsp negated! // // nodeAt: position // child notNil // ifTrue: [^self child nodeAt: (self applyDspTo: position)] // ifFalse: [self errorSubscriptBounds: position]! // // nodesFrom: startPosition extent: extent shouldSplit: shouldSplit // | position nodes extentLeft | // nodes := OrderedCollection new. // position := startPosition. // extentLeft := extent. // [extentLeft > 0] whileTrue: // [| node | // node := self // first... [truncated message content] |
|
From: <dg...@us...> - 2003-05-04 18:32:11
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/space In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/space Added Files: Region.java IntegerRegion.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: Region.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.space; import org.abora.ash.engine.AboraObject; /** */ public abstract class Region extends AboraObject { } --- NEW FILE: IntegerRegion.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.space; /** */ public class IntegerRegion extends Region { private final int startPosition; private final int extent; private static final IntegerRegion EMPTY_REGION = new IntegerRegion(0, 0); private IntegerRegion(int startPosition, int extent) { this.startPosition = startPosition; this.extent = extent; } public static IntegerRegion startExtent(int startPosition, int extent) { return new IntegerRegion(startPosition, extent); } public static IntegerRegion startEnd(int startPosition, int endPosition) { return new IntegerRegion(startPosition, endPosition - startPosition + 1); } public static IntegerRegion empty() { return EMPTY_REGION; } public boolean equals(Object o) { if (!(o instanceof IntegerRegion)) return false; IntegerRegion r = (IntegerRegion) o; return r.getStartPosition() == getStartPosition() && r.getExtent() == getExtent(); } public int getExtent() { return extent; } public int getStartPosition() { return startPosition; } public int getBeyondPosition() { return getStartPosition() + getExtent(); } public String asString() { return "IntegerRegion[" + getStartPosition() + ", " + getEndPosition() + "]"; } // do: operation // ^self startPosition to: self endPosition do: [:position | operation value: position]! public int getEndPosition() { return getStartPosition() + getExtent() - 1; } public int hashCode() { return getStartPosition() << 1 | getExtent(); } public boolean includes(int position) { final int relativePosition = relativePosition(position); return relativePosition >= 0 && relativePosition < getExtent(); } /** * Answer a region with positions the receiver and anotherRegion have in common. */ public IntegerRegion intersection(IntegerRegion anotherRegion) { if (intersects(anotherRegion)) { int newStart = Math.max(getStartPosition(), anotherRegion.getStartPosition()); int newEnd = Math.min(getEndPosition(), anotherRegion.getEndPosition()); return IntegerRegion.startEnd(newStart, newEnd); } else { return IntegerRegion.empty(); } } /* * Answer whether any position of the receiver can be found in anotherRegion. */ public boolean intersects(IntegerRegion anotherRegion) { return getStartPosition() <= anotherRegion.getEndPosition() && getEndPosition() >= anotherRegion.getStartPosition(); } public boolean isEmpty() { return getExtent() <= 0; } public int relativePosition(int position) { return position - getStartPosition(); } } |
|
From: <dg...@us...> - 2003-05-04 18:32:11
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/space/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/space/tests Added Files: IntegerRegionTest.java AllTests.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: IntegerRegionTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.space.tests; import org.abora.ash.space.IntegerRegion; import junit.framework.TestCase; /** */ public class IntegerRegionTest extends TestCase { public IntegerRegionTest(String arg0) { super(arg0); } public void testBeyondPosition() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertEquals(region.getBeyondPosition(), 13); } public void testNew() { IntegerRegion region = IntegerRegion.startExtent(10, 2); assertEquals(region.getStartPosition(), 10); assertEquals(region.getExtent(), 2); } public void testNew2() { IntegerRegion region = IntegerRegion.startEnd(10, 11); assertEquals(region.getStartPosition(), 10); assertEquals(region.getExtent(), 2); } public void testAsString() { assertEquals(IntegerRegion.startEnd(10, 11).asString(), "IntegerRegion[10, 11]"); assertEquals(IntegerRegion.startExtent(10, 1).asString(), "IntegerRegion[10, 10]"); } public void testEndPosition() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertEquals(region.getEndPosition(), 12); } public void testEquals() { IntegerRegion region = IntegerRegion.startExtent(10, 2); assertEquals(region, region); assertEquals(region, IntegerRegion.startExtent(10, 2)); assertFalse(region.equals(IntegerRegion.startExtent(10, 3))); assertFalse(region.equals(IntegerRegion.startExtent(10, 1))); assertFalse(region.equals(IntegerRegion.startExtent(9, 2))); assertFalse(region.equals(IntegerRegion.startExtent(9, 3))); assertFalse(region.equals(IntegerRegion.startExtent(10, 0))); } public void testHashCode() { IntegerRegion region = IntegerRegion.startExtent(10, 2); assertEquals(region.hashCode(), region.hashCode()); assertEquals(region.hashCode(), IntegerRegion.startExtent(10, 2).hashCode()); assertFalse(region.hashCode() == IntegerRegion.startExtent(10, 3).hashCode()); assertFalse(region.hashCode() == IntegerRegion.startExtent(10, 0).hashCode()); } public void testIncludes() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertTrue(region.includes(10)); assertTrue(region.includes(11)); assertTrue(region.includes(12)); assertFalse(region.includes(9)); assertFalse(region.includes(13)); } public void testIntersection() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertEquals(region.intersection(region), region); assertEquals(region.intersection(IntegerRegion.startExtent(9, 5)), IntegerRegion.startExtent(10, 3)); assertEquals(region.intersection(IntegerRegion.startExtent(9, 2)), IntegerRegion.startExtent(10, 1)); assertEquals(region.intersection(IntegerRegion.startExtent(12, 4)), IntegerRegion.startExtent(12, 1)); assertEquals(region.intersection(IntegerRegion.startExtent(11, 1)), IntegerRegion.startExtent(11, 1)); assertEquals(region.intersection(IntegerRegion.startExtent(9, 1)), IntegerRegion.empty()); assertEquals(region.intersection(IntegerRegion.startExtent(13, 4)), IntegerRegion.empty()); } public void testIntersects() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertTrue(region.intersects(region)); assertTrue(region.intersects(IntegerRegion.startExtent(9, 5))); assertTrue(region.intersects(IntegerRegion.startExtent(9, 2))); assertTrue(region.intersects(IntegerRegion.startExtent(12, 4))); assertTrue(region.intersects(IntegerRegion.startExtent(11, 1))); assertFalse(region.intersects(IntegerRegion.startExtent(9, 1))); assertFalse(region.intersects(IntegerRegion.startExtent(13, 4))); assertFalse(region.intersects(IntegerRegion.empty())); } public void testIsEmpty() { assertTrue(IntegerRegion.startExtent(10, 0).isEmpty()); assertTrue(IntegerRegion.startExtent(10, -1).isEmpty()); assertFalse(IntegerRegion.startExtent(10, 1).isEmpty()); } public void testRelativePosition() { IntegerRegion region = IntegerRegion.startExtent(10, 3); assertEquals(region.relativePosition(9), -1); assertEquals(region.relativePosition(10), 0); assertEquals(region.relativePosition(11), 1); assertEquals(region.relativePosition(12), 2); assertEquals(region.relativePosition(13), 3); assertEquals(region.relativePosition(14), 4); } } --- NEW FILE: AllTests.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.space.tests; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** */ public class AllTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Test for org.abora.be.space.tests"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(IntegerRegionTest.class)); //$JUnit-END$ return suite; } } |
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/content In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/content Added Files: BeContentElement.java BeEdition.java BeCollectionHolder.java BeWork.java BeDataHolder.java BeClub.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: BeContentElement.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; import org.abora.ash.engine.AboraObject; /** */ public class BeContentElement extends AboraObject { } --- NEW FILE: BeEdition.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; /** */ public class BeEdition extends BeContentElement { } --- NEW FILE: BeCollectionHolder.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; /** */ public class BeCollectionHolder extends BeContentElement { } --- NEW FILE: BeWork.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; /** */ public class BeWork extends BeContentElement { } --- NEW FILE: BeDataHolder.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; /** */ public class BeDataHolder { } --- NEW FILE: BeClub.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.content; /** */ public class BeClub extends BeWork { } |
|
From: <dg...@us...> - 2003-05-04 18:32:11
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/tests Added Files: AllTests.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: AllTests.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.tests; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** */ public class AllTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Test for org.abora.violet.tests"); //$JUnit-BEGIN$ suite.addTest(org.abora.ash.engine.tests.AllTests.suite()); suite.addTest(org.abora.ash.ent.tests.AllTests.suite()); suite.addTest(org.abora.ash.space.tests.AllTests.suite()); //$JUnit-END$ return suite; } } |
|
From: <dg...@us...> - 2003-05-04 18:32:11
|
Update of /cvsroot/abora/abora-ash
In directory sc8-pr-cvs1:/tmp/cvs-serv3306
Added Files:
.project .classpath
Log Message:
-Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code
--- NEW FILE: .project ---
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>abora-ash</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
--- NEW FILE: .classpath ---
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="C:/Program Files/eclipse/plugins/org.junit_3.8.1/junit.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/engine In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/engine Added Files: AboraException.java AboraConverter.java WorksStorage.java Endorsement.java Id.java AboraObject.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: AboraException.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; /** */ public class AboraException extends Exception { /** * Constructor for AboraException. */ public AboraException() { super(); } /** * Constructor for AboraException. * @param message */ public AboraException(String message) { super(message); } /** * Constructor for AboraException. * @param message * @param cause */ public AboraException(String message, Throwable cause) { super(message, cause); } /** * Constructor for AboraException. * @param cause */ public AboraException(Throwable cause) { super(cause); } } --- NEW FILE: AboraConverter.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; /** */ public class AboraConverter { /** * Constructor for AboraConverter. */ private AboraConverter() { super(); } public static byte[] toAboraContent(String s) { return s.getBytes(); } } --- NEW FILE: WorksStorage.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.WeakHashMap; import org.abora.ash.content.BeWork; /** */ public class WorksStorage extends AboraObject { private final Map idLookup = new WeakHashMap(); private final Set works = new HashSet(); private BeWork userHome = null; private static final WorksStorage INSTANCE = new WorksStorage(); // instanceVariableNames: 'works idLookup userHome' public void put(Id id, AboraObject value) { //@todo this should probably be somewhere else idLookup.put(id, new WeakReference(value)); } public void add(BeWork work) { works.add(work); } public int knownIds() { return idLookup.size(); } public AboraObject get(Id id) { //@todo this should probably be somewhere else WeakReference holder = (WeakReference) idLookup.get(id); AboraObject value = holder != null ? (AboraObject) holder.get() : null; if (value == null) throw new NoSuchElementException("Nothing associated with: "+id); return value; } public void remove(BeWork work) { works.remove(work); } // // works // ^works public static WorksStorage getInstance() { return INSTANCE; } /** * Returns the userHome. * @return BeWork */ public BeWork getUserHome() { return userHome; } /** * Sets the userHome. * @param userHome The userHome to set */ public void setUserHome(BeWork userHome) { this.userHome = userHome; } } --- NEW FILE: Endorsement.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; /** */ public class Endorsement extends AboraObject { private final Id endorseeId; private final Id itemId; public Endorsement(Id endorseeId, Id itemId) { this.endorseeId = endorseeId; this.itemId = itemId; } public boolean equals(Object o) { if (!(o instanceof Endorsement)) return false; Endorsement e = (Endorsement) o; return getEndorseeId().equals(e.getEndorseeId()) && getItemId().equals(e.getItemId()); } public boolean checkIntegrity() { return true; } public AboraObject endorsee() { throw new UnsupportedOperationException(); // #todo "WorksStorage references only make sense on server. Review!!!!!!". // ^WorksStorage current lookupId: endorseeId! } public Id getEndorseeId() { return endorseeId; } public Id getItemId() { return itemId; } public int hashCode() { return (getEndorseeId().hashCode() << 1) | getItemId().hashCode(); } public String asString() { return "Endorsement(endorseeId=" + getEndorseeId() + ", itemId=" + getItemId() + ")"; } } --- NEW FILE: Id.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; /** */ public class Id extends AboraObject { private final long value; private static long NEXT_VALUE= 1; public Id() { value = NEXT_VALUE++; } public Id(AboraObject o) { this(); WorksStorage.getInstance().put(this, o); } public boolean equals(Object o) { if (!(o instanceof Id)) return false; Id id = (Id) o; return getValue() == id.getValue(); } public int hashCode() { return (int)getValue(); } public long getValue() { return value; } public String asString() { return "Id("+getValue()+")"; } // nextId // | id | // id := (self new) // value: NextValue; // yourself. // NextValue := NextValue + 1. // ^id! // // nextIdFor: anObject // | id | // id := self nextId. // WorksStorage current addId: id with: anObject. // ^id! ! } --- NEW FILE: AboraObject.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine; /** */ public class AboraObject { } |
|
From: <dg...@us...> - 2003-05-04 18:32:10
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/ent/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/ent/tests Added Files: RootNodeTest.java AllTests.java SequenceNumberTest.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: RootNodeTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import org.abora.ash.engine.AboraConverter; import org.abora.ash.content.BeEdition; import org.abora.ash.ent.ChildNode; import org.abora.ash.ent.CollectionLeaf; import org.abora.ash.ent.NonCompatibleBranchException; import org.abora.ash.ent.RootNode; import org.abora.ash.ent.SequenceNumber; import junit.framework.TestCase; /** */ public class RootNodeTest extends TestCase { public RootNodeTest(String arg0) { super(arg0); } // // shouldHaveMatchingParents: node // node children do: [:child | // self should: [child parents size = 1 and: [child parents first == node]]. // self shouldHaveMatchingParents: child]. // // ! // // testAllEditions // | root edition editions | // edition := BeEdition new. // root := RootNode edition: edition branch: 10. // editions := root allEditions. // self should: [editions size = 1]. // self should: [editions includes: edition]! // // testAllRoots // | root roots | // root := RootNode edition: nil branch: 10. // "test" // roots := root allRoots. // self should: [roots size = 1]. // self should: [roots includes: root]! // // testAssertIsChild // | leaf1 leaf2 root | // leaf1 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345' asAboraContent. // leaf2 := CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf1. // self shouldnt: [root assertIsChild: leaf1] raise: EntError. // self // should: [root assertIsChild: leaf2] // raise: EntError // description: 'unknown child of root'! // // testChildren // | dataLeaf root | // dataLeaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: dataLeaf. // self should: [root children = (Array with: dataLeaf)]! // // testChildrenEmpty // | root | // root := RootNode edition: nil branch: 1. // self should: [root children isEmpty]! // // testContentsAt // | root | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'abcdef' asAboraContent). // self should: [(root contentsAt: 1) = $a codePoint]. // self should: [(root contentsAt: 2) = $b codePoint]. // self should: [(root contentsAt: 6) = $f codePoint]! // // testContentsAtBadPosition // | root | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'abcdef' asAboraContent). // self should: [root contentsAt: 0] raise: BoundsError. // self should: [root contentsAt: 7] raise: BoundsError! // // testContentsFromExtentDo // | root out do | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 2 // elements: 'abcdef' asAboraContent) // dsp: -1. // out := ''. // do := [:int | out := out , (Character codePoint: int) asString]. // root // contentsFrom: 1 // extent: 6 // do: do. // self should: [out = 'abcdef']. // out := ''. // root // contentsFrom: 2 // extent: 3 // do: do. // self should: [out = 'bcd']. // out := ''. // root // contentsFrom: 1 // extent: 13 // do: do. // self should: [out = 'abcdef']. // out := ''. // root // contentsFrom: -2 // extent: 4 // do: do. // self should: [out = 'a']. // out := ''. // root // contentsFrom: 6 // extent: 6 // do: do. // self should: [out = 'f']. // out := ''. // root // contentsFrom: -2 // extent: 3 // do: do. // self should: [out = '']. // out := ''. // root // contentsFrom: 7 // extent: 5 // do: do. // self should: [out = '']! // // testCount // | root | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345' asAboraContent). // self should: [root count = 5]! // public void testCountEmpty() { RootNode root = new RootNode(new BeEdition(), new SequenceNumber(1)); assertEquals(root.count(), 0); } // testCountEmpty // | root | // root := RootNode edition: nil branch: 1. // self should: [root count = 0]! // public void testNew() { BeEdition edition = new BeEdition(); RootNode root = new RootNode(edition, new SequenceNumber(10)); assertEquals(root.getBranch(), new SequenceNumber(10)); assertEquals(root.getDsp(), 0); assertNull(root.getChild()); assertEquals(root.getEdition(), edition); } // testCreate // | root edition | // edition := BeEdition new. // root := RootNode edition: edition branch: 10. // self should: [root branch = 10]. // self should: [root dsp = 0]. // self should: [root child isNil]. // self should: [root edition == edition]! // // testCreateWith // | root leaf edition | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // edition := BeEdition new. // root := RootNode // edition: edition // branch: 10 // with: leaf. // self should: [root branch = 10]. // self should: [root dsp = 0]. // self should: [root child == leaf]. // self should: [leaf parents = (OrderedCollection with: root)]. // self should: [root edition == edition]! // // testCreateWithDsp // | root leaf edition | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // edition := BeEdition new. // root := RootNode // edition: edition // branch: 10 // with: leaf // dsp: 9. // self should: [root branch = 10]. // self should: [root dsp = 9]. // self should: [root child == leaf]. // self should: [leaf parents = (OrderedCollection with: root)]. // self should: [root edition == edition]! // // testDuplicateFor // | root newRoot | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345' asAboraContent). // // "operation" // newRoot := root duplicateFor: 1. // self should: [root == newRoot]. // self assertTextContentsOf: newRoot is: '12345'! // public void testHashChild() { assertFalse(new RootNode(null, new SequenceNumber(1)).hasChild()); ChildNode leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); RootNode root = new RootNode(null, new SequenceNumber(1), leaf); assertTrue(root.hasChild()); } // testHasChild // self should: // [(RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent)) // hasChild]. // self shouldnt: [(RootNode edition: nil branch: 1) hasChild]! // // testInsertEmpty // | root dataLeaf | // root := RootNode edition: nil branch: 1. // dataLeaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // // "test" // root insert: dataLeaf. // self should: [root child == dataLeaf]. // self should: [dataLeaf parents = (OrderedCollection with: root)]! // // testInsertEmptyBadPosition // | root dataLeaf | // root := RootNode edition: nil branch: 1. // dataLeaf := CollectionLeaf // branch: 1 // startPosition: 2 // elements: 'hello' asAboraContent. // // "test" // self should: [root insert: dataLeaf] raise: BoundsError! // // testInsertEmptyBadRevision // | root dataLeaf | // root := RootNode edition: nil branch: 1. // dataLeaf := CollectionLeaf // branch: 2 // startPosition: 1 // elements: 'hello' asAboraContent. // // "test" // self should: [root insert: dataLeaf] raise: EntError! // // testInsertWithDsp // | root | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 10 // elements: 'hello' asAboraContent) // dsp: -9. // // "test" // root insert: (CollectionLeaf // branch: 1 // startPosition: 2 // elements: 'ab' asAboraContent). // self assertTextContentsOf: root is: 'habello'! // // testNodesFromExtent // | root found | // root := self createBalanced12345678. // root dsp: -1. // found := root // nodesFrom: 0 // extent: 1 // shouldSplit: false. // self should: [found size = 1 and: [found first elements = '1' asAboraContent]]. // found := root // nodesFrom: 1 // extent: 1 // shouldSplit: false. // self should: [found size = 1 and: [found first elements = '2' asAboraContent]]. // found := root // nodesFrom: 7 // extent: 1 // shouldSplit: false. // self should: [found size = 1 and: [found first elements = '8' asAboraContent]]. // found := root // nodesFrom: 1 // extent: 2 // shouldSplit: false. // self // should: [found size = 2 and: [found first elements = '2' asAboraContent and: [found last elements = '3' asAboraContent]]]. // found := root // nodesFrom: 0 // extent: 8 // shouldSplit: false. // self should: [found size = 8]. // found keysAndValuesDo: [:i :element | self should: [element elements = i printString asAboraContent]]! // // testNodesFromExtentShouldSplitLeft // | root found | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345678' asAboraContent). // found := root // nodesFrom: 1 // extent: 2 // shouldSplit: true. // self should: [found size = 1 and: [found first elements = '12' asAboraContent]]! // // testNodesFromExtentShouldSplitMiddle // | root found | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345678' asAboraContent). // found := root // nodesFrom: 2 // extent: 6 // shouldSplit: true. // self should: [found size = 1 and: [found first elements = '234567' asAboraContent]]! // // testNodesFromExtentShouldSplitMultiple // | root found | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12' asAboraContent). // root insert: (CollectionLeaf // branch: 1 // startPosition: 3 // elements: '345' asAboraContent). // root insert: (CollectionLeaf // branch: 1 // startPosition: 6 // elements: '67' asAboraContent). // root insert: (CollectionLeaf // branch: 1 // startPosition: 8 // elements: '89a' asAboraContent). // root insert: (CollectionLeaf // branch: 1 // startPosition: 11 // elements: 'bc' asAboraContent). // self assertTextContentsOf: root is: '123456789abc'. // found := root // nodesFrom: 4 // extent: 5 // shouldSplit: true. // self should: [found size = 3]. // self should: [found first elements = '45' asAboraContent]. // self should: [found second elements = '67' asAboraContent]. // self should: [found last elements = '8' asAboraContent]. // self assertTextContentsOf: root is: '123456789abc'! // // testNodesFromExtentShouldSplitRight // | root found | // root := RootNode // edition: nil // branch: 1 // with: (CollectionLeaf // branch: 1 // startPosition: 1 // elements: '12345678' asAboraContent). // found := root // nodesFrom: 7 // extent: 2 // shouldSplit: true. // self should: [found size = 1 and: [found first elements = '78' asAboraContent]]! // public void testParents() { ChildNode leaf = new CollectionLeaf(new SequenceNumber(1), 1, AboraConverter.toAboraContent("hello")); RootNode root = new RootNode(null, new SequenceNumber(10), leaf); assertTrue(root.getParents().isEmpty()); } // testParents // | root leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: 'hello' asAboraContent. // root := RootNode // edition: nil // branch: 10 // with: leaf. // self should: [root parents isEmpty]! // // testRemove // | root found leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 2 // elements: '1' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf // dsp: -1. // self assertTextContentsOf: root is: '1'. // leaf removeFor: 1. // self should: [root children isEmpty]. // self should: [root dsp = 0]! // // testRemoveBadRevision // | root found leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: '1' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf. // self should: [leaf removeFor: 2] raise: EntError! // public void testRootFor() throws Exception { RootNode root = new RootNode(null, new SequenceNumber(10)); assertSame(root.rootFor(new SequenceNumber(10)), root); assertSame(root.rootFor(new SequenceNumber(11)), root); try { assertSame(root.rootFor(new SequenceNumber(9)), root); fail(); } catch (NonCompatibleBranchException e) { // expected } } // testRootFor // | root | // root := RootNode edition: nil branch: 10. // self should: [(root rootFor: 10) == root]. // self should: [(root rootFor: 11) == root]. // self // should: [(root rootFor: 9) == root] // raise: EntError // description: 'revision is before my time'! // // testSplay // | root found | // root := self createBalanced12345678. // self shouldHaveMatchingParents: root. // found := root splay: 1. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '1' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 2. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '2' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 3. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '3' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 4. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '4' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 5. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '5' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 6. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '6' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 7. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '7' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 8. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '8' asAboraContent]. // self shouldHaveMatchingParents: root. // found := root splay: 4. // self assertTextContentsOf: root is: '12345678'. // self should: [found elements = '4' asAboraContent]. // self shouldHaveMatchingParents: root. // ! // // testSplayChild // | root found leaf | // leaf := CollectionLeaf // branch: 1 // startPosition: 1 // elements: '1' asAboraContent. // root := RootNode // edition: nil // branch: 1 // with: leaf. // root splay: 1. // self should: [root child == leaf]! ! } --- NEW FILE: AllTests.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** */ public class AllTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Test for org.abora.be.ent.tests"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(SequenceNumberTest.class)); suite.addTest(new TestSuite(RootNodeTest.class)); //$JUnit-END$ return suite; } } --- NEW FILE: SequenceNumberTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.ent.tests; import org.abora.ash.ent.SequenceNumber; import junit.framework.TestCase; /** */ public class SequenceNumberTest extends TestCase { public SequenceNumberTest(String arg0) { super(arg0); } private void assertEquals(int[] a, int[] b) { assertEquals("size", a.length, b.length); for (int i = 0; i < a.length; i++) { assertEquals("i"+i, a[i], b[i]); } } public void testCopyWith() { assertEquals(new SequenceNumber(1).copyWith(0).toIntArray(), new int[]{1,0}); assertEquals(new SequenceNumber(3).copyWith(1).toIntArray(), new int[]{3,1}); assertEquals(new SequenceNumber(1, 2).copyWith(3).toIntArray(), new int[]{1,2,3}); } public void testNew() { assertEquals(new SequenceNumber(1).toIntArray(), new int[]{1}); assertEquals(new SequenceNumber(1,2).toIntArray(), new int[]{1,2}); assertEquals(new SequenceNumber(1,2,3).toIntArray(), new int[]{1,2,3}); assertEquals(new SequenceNumber(new int[]{1,2,3}).toIntArray(), new int[]{1,2,3}); } public void testToString() { assertEquals(new SequenceNumber(1).toString(), "SequenceNumber[1]"); assertEquals(new SequenceNumber(1,2).toString(), "SequenceNumber[1:2]"); assertEquals(new SequenceNumber(1,2,3).toString(), "SequenceNumber[1:2:3]"); } public void testEquals() { assertEquals(new SequenceNumber(1), new SequenceNumber(1)); assertFalse(new SequenceNumber(1).equals(new SequenceNumber(2))); assertFalse(new SequenceNumber(1).equals(new SequenceNumber(0))); assertEquals(new SequenceNumber(1,2,3), new SequenceNumber(1,2,3)); assertFalse(new SequenceNumber(1,2,3).equals(new SequenceNumber(1,2,30))); assertFalse(new SequenceNumber(1,2,3).equals(new SequenceNumber(1,2))); assertFalse(new SequenceNumber(1,2).equals(new SequenceNumber(1,2,3))); } public void testHashCode() { SequenceNumber s = new SequenceNumber(1); assertEquals(s.hashCode(), s.hashCode()); assertEquals(s.hashCode(), new SequenceNumber(1).hashCode()); assertEquals(s.hashCode(), new SequenceNumber(1,0,0).hashCode()); assertFalse(s.hashCode() == new SequenceNumber(2).hashCode()); assertFalse(s.hashCode() == new SequenceNumber(0).hashCode()); assertFalse(s.hashCode() == new SequenceNumber(1,2,3).hashCode()); assertEquals(new SequenceNumber(1,2,3).hashCode(), new SequenceNumber(1,2,3).hashCode()); assertFalse(new SequenceNumber(1,2,3).hashCode() == new SequenceNumber(1,2,30).hashCode()); } public void testIncrementLast() { assertEquals(new SequenceNumber(1).incrementLast().toIntArray(), new int[]{2}); assertEquals(new SequenceNumber(1, 2).incrementLast().toIntArray(), new int[]{1,3}); } public void testCompareTo() { assertEquals(new SequenceNumber(1).compareTo(new SequenceNumber(2)), -1); assertEquals(new SequenceNumber(1).compareTo(new SequenceNumber(1)), 0); assertEquals(new SequenceNumber(1).compareTo(new SequenceNumber(0)), 1); assertEquals(new SequenceNumber(1).compareTo(new SequenceNumber(1,1)), -1); assertEquals(new SequenceNumber(1).compareTo(new SequenceNumber(1,0)), 0); assertEquals(new SequenceNumber(1,2,3).compareTo(new SequenceNumber(1,2,3)), 0); assertEquals(new SequenceNumber(new int[]{2,2,1,1,1}).compareTo(new SequenceNumber(new int[]{2,2,2})), -1); } public void testIsBranchingBefore() { assertTrue(new SequenceNumber(1).isBranchingBefore(new SequenceNumber(2))); assertFalse(new SequenceNumber(1).isBranchingBefore(new SequenceNumber(1))); assertFalse(new SequenceNumber(1).isBranchingBefore(new SequenceNumber(0))); assertTrue(new SequenceNumber(1).isBranchingBefore(new SequenceNumber(1,1))); assertTrue(new SequenceNumber(1).isBranchingBefore(new SequenceNumber(1,0))); assertTrue(new SequenceNumber(new int[]{2,2,1}).isBranchingBefore(new SequenceNumber(new int[]{2,2,2}))); assertTrue(new SequenceNumber(new int[]{2,2,1}).isBranchingBefore(new SequenceNumber(new int[]{2,2,1,1,1}))); assertFalse(new SequenceNumber(new int[]{2,2,1,1,1}).isBranchingBefore(new SequenceNumber(new int[]{2,2,2}))); assertFalse(new SequenceNumber(new int[]{2,2,1,1,1}).isBranchingBefore(new SequenceNumber(new int[]{2,2,2,1,1}))); assertFalse(new SequenceNumber(1,2,3).isBranchingBefore(new SequenceNumber(1,3,1))); assertFalse(new SequenceNumber(1,2,3).isBranchingBefore(new SequenceNumber(1,2,3))); } public void testIsBranchingBeforeOrEqual() { assertTrue(new SequenceNumber(1).isBranchingBeforeOrEqual(new SequenceNumber(2))); assertTrue(new SequenceNumber(1).isBranchingBeforeOrEqual(new SequenceNumber(1))); assertFalse(new SequenceNumber(1).isBranchingBeforeOrEqual(new SequenceNumber(0))); assertTrue(new SequenceNumber(1).isBranchingBeforeOrEqual(new SequenceNumber(1,1))); assertTrue(new SequenceNumber(1).isBranchingBeforeOrEqual(new SequenceNumber(1,0))); assertTrue(new SequenceNumber(new int[]{2,2,1}).isBranchingBeforeOrEqual(new SequenceNumber(new int[]{2,2,2}))); assertTrue(new SequenceNumber(new int[]{2,2,1}).isBranchingBeforeOrEqual(new SequenceNumber(new int[]{2,2,1,1,1}))); assertFalse(new SequenceNumber(new int[]{2,2,1,1,1}).isBranchingBeforeOrEqual(new SequenceNumber(new int[]{2,2,2}))); assertFalse(new SequenceNumber(new int[]{2,2,1,1,1}).isBranchingBeforeOrEqual(new SequenceNumber(new int[]{2,2,2,1,1}))); assertFalse(new SequenceNumber(1,2,3).isBranchingBeforeOrEqual(new SequenceNumber(1,3,1))); assertTrue(new SequenceNumber(1,2,3).isBranchingBeforeOrEqual(new SequenceNumber(1,2,3))); } } |
|
From: <dg...@us...> - 2003-05-04 18:32:10
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/engine/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3306/src/org/abora/ash/engine/tests Added Files: IdTest.java AllTests.java Log Message: -Add start of Ash subproject, which is currently the beginnings of a port of the dolphin-demo smalltalk server code --- NEW FILE: IdTest.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine.tests; import java.util.HashSet; import java.util.Set; import org.abora.ash.engine.Id; import junit.framework.TestCase; /** */ public class IdTest extends TestCase { /** * Constructor for IdTest. * @param arg0 */ public IdTest(String arg0) { super(arg0); } public void testNew() { Id id = new Id(); assertNotNull(id); } public void testNewUniqueness() { Set values = new HashSet(); for (int i = 0; i < 20; i++) { Id id = new Id(); Long value = new Long(id.getValue()); assertFalse(values.contains(value)); values.add(value); } } public void testEquals() { Id id = new Id(); assertEquals(id, id); assertFalse(id.equals(new Id())); } } --- NEW FILE: AllTests.java --- /* * Abora-Ash * Part of the Abora hypermedia project: http://www.abora.org * Copyright 2003 David G Jones */ package org.abora.ash.engine.tests; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** */ public class AllTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Test for org.abora.be.tests"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(IdTest.class)); //$JUnit-END$ return suite; } } |
|
From: <dg...@us...> - 2003-05-04 18:32:06
|
Update of /cvsroot/abora/abora-ash/src/org/abora/ash/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3149/src/org/abora/ash/tests Log Message: Directory /cvsroot/abora/abora-ash/src/org/abora/ash/tests added to the repository |