SortedCollection.st
changeset 18508 cd84f2138c53
parent 16002 5fd1486ee60a
child 18509 85976deb6616
child 19074 e6e82ab60270
equal deleted inserted replaced
18507:d060f9801f9a 18508:cd84f2138c53
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1993 by Claus Gittinger
     4  COPYRIGHT (c) 1993 by Claus Gittinger
     3 	      All Rights Reserved
     5 	      All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
     8  be provided or otherwise made available to, or used by, any
    10  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
    11  other person.  No title to or ownership of the software is
    10  hereby transferred.
    12  hereby transferred.
    11 "
    13 "
    12 "{ Package: 'stx:libbasic' }"
    14 "{ Package: 'stx:libbasic' }"
       
    15 
       
    16 "{ NameSpace: Smalltalk }"
    13 
    17 
    14 OrderedCollection subclass:#SortedCollection
    18 OrderedCollection subclass:#SortedCollection
    15 	instanceVariableNames:'sortBlock'
    19 	instanceVariableNames:'sortBlock'
    16 	classVariableNames:'DefaultSortBlock'
    20 	classVariableNames:'DefaultSortBlock'
    17 	poolDictionaries:''
    21 	poolDictionaries:''
   347     "/ which often happens.
   351     "/ which often happens.
   348     "/ so we allow the code to be a bit more complicated...
   352     "/ so we allow the code to be a bit more complicated...
   349 
   353 
   350     (lastIndex < firstIndex "i.e. self size == 0"
   354     (lastIndex < firstIndex "i.e. self size == 0"
   351     or:[ 
   355     or:[ 
   352         lastElement := contentsArray at:lastIndex.
   356         lastElement := contentsArray basicAt:lastIndex.
   353         (sortBlock value:lastElement value:anObject)    
   357         (sortBlock value:lastElement value:anObject)    
   354     ]) ifTrue:[
   358     ]) ifTrue:[
   355         "/ empty or lastElement is smaller then newElement; add at the end
   359         "/ empty or lastElement is smaller then newElement; add at the end
   356         index := lastIndex.
   360         index := lastIndex.
   357         (index == contentsArray size) ifTrue:[
   361         (index == contentsArray size) ifTrue:[
   494 
   498 
   495     srcIndex1 := firstIndex.
   499     srcIndex1 := firstIndex.
   496     last1 := srcIndex1 + n1 -1.
   500     last1 := srcIndex1 + n1 -1.
   497 
   501 
   498     (srcIndex1 <= last1 and:[srcIndex2 <= last2]) ifTrue:[
   502     (srcIndex1 <= last1 and:[srcIndex2 <= last2]) ifTrue:[
   499         el1 := contentsArray at:srcIndex1.
   503         el1 := contentsArray basicAt:srcIndex1.
   500         el2 := contentsArray2 at:srcIndex2.
   504         el2 := contentsArray2 basicAt:srcIndex2.
   501         end1Reached := end2Reached := false.
   505         end1Reached := end2Reached := false.
   502 
   506 
   503         [end1Reached or:[end2Reached]] whileFalse:[
   507         [end1Reached or:[end2Reached]] whileFalse:[
   504             (sortBlock value:el1 value:el2) ifTrue:[
   508             (sortBlock value:el1 value:el2) ifTrue:[
   505                 "/ el1 to come before el2
   509                 "/ el1 to come before el2
   506                 newContentsArray at:destIndex put:el1. destIndex := destIndex + 1.
   510                 newContentsArray basicAt:destIndex put:el1. destIndex := destIndex + 1.
   507                 srcIndex1 := srcIndex1 + 1.
   511                 srcIndex1 := srcIndex1 + 1.
   508                 srcIndex1 <= last1 ifTrue:[
   512                 srcIndex1 <= last1 ifTrue:[
   509                     el1 := contentsArray at:srcIndex1.
   513                     el1 := contentsArray basicAt:srcIndex1.
   510                 ] ifFalse:[
   514                 ] ifFalse:[
   511                     end1Reached := true
   515                     end1Reached := true
   512                 ]
   516                 ]
   513             ] ifFalse:[
   517             ] ifFalse:[
   514                 "/ el2 to come before el1
   518                 "/ el2 to come before el1
   515                 newContentsArray at:destIndex put:el2. destIndex := destIndex + 1.
   519                 newContentsArray basicAt:destIndex put:el2. destIndex := destIndex + 1.
   516                 srcIndex2 := srcIndex2 + 1.
   520                 srcIndex2 := srcIndex2 + 1.
   517                 srcIndex2 <= last2 ifTrue:[
   521                 srcIndex2 <= last2 ifTrue:[
   518                     el2 := contentsArray2 at:srcIndex2.
   522                     el2 := contentsArray2 basicAt:srcIndex2.
   519                 ] ifFalse:[
   523                 ] ifFalse:[
   520                     end2Reached := true
   524                     end2Reached := true
   521                 ]
   525                 ]
   522             ]
   526             ]
   523         ]
   527         ]
   651 
   655 
   652     |newCollection
   656     |newCollection
   653      start  "{ Class:SmallInteger }"
   657      start  "{ Class:SmallInteger }"
   654      stop   "{ Class:SmallInteger }" |
   658      stop   "{ Class:SmallInteger }" |
   655 
   659 
   656     newCollection := OrderedCollection new:(self size).
   660     newCollection := self speciesForCollecting new:(self size).
   657     stop := lastIndex.
   661     stop := lastIndex.
   658     start := firstIndex.
   662     start := firstIndex.
   659     start to:stop do:[:index |
   663     start to:stop do:[:index |
   660 	newCollection add:(aBlock value:(contentsArray at:index)).
   664         newCollection add:(aBlock value:(contentsArray basicAt:index)).
   661     ].
   665     ].
   662     ^ newCollection
   666     ^ newCollection
   663 ! !
   667 ! !
   664 
   668 
   665 !SortedCollection methodsFor:'instance protocol'!
   669 !SortedCollection methodsFor:'instance protocol'!
   699     "
   703     "
   700 ! !
   704 ! !
   701 
   705 
   702 !SortedCollection methodsFor:'private'!
   706 !SortedCollection methodsFor:'private'!
   703 
   707 
       
   708 indexForInserting:anObject
       
   709     "search the index at which to insert anObject.
       
   710      Can also be used to search for an existing element
       
   711      by checking if the element at the returned index is the one we look for.
       
   712      Uses a binarySearch since we can depend on the elements being in sorted order.
       
   713      The returned index is a physical one, for accessing contentsArray."
       
   714 
       
   715     |low    "{ Class: SmallInteger}"
       
   716      high   "{ Class: SmallInteger}"
       
   717      middle "{ Class: SmallInteger}"
       
   718      element|
       
   719 
       
   720     "
       
   721      we can of course use a binary search - since the elements are sorted
       
   722     "
       
   723     low := firstIndex.
       
   724     high := lastIndex.
       
   725     [low > high] whileFalse:[
       
   726         middle := (low + high) // 2.
       
   727         element := contentsArray basicAt:middle.
       
   728         (sortBlock value:element value:anObject) ifTrue:[
       
   729             "middleelement is smaller than object"
       
   730             low := middle + 1
       
   731         ] ifFalse:[
       
   732             high := middle - 1
       
   733         ]
       
   734     ].
       
   735     ^ low
       
   736 
       
   737     "
       
   738      #(1 2 3 4 7 99 1313 981989 898989898) asSortedCollection indexForInserting:50
       
   739 
       
   740      #(1.0 2.0 3 4 7 49.0 51.0 99 1313 981989 898989898) asSortedCollection indexForInserting:50
       
   741 
       
   742     "
       
   743 
       
   744     "Modified: 12.4.1996 / 13:22:03 / cg"
       
   745 !
       
   746 
   704 setSortBlock: aSortBlock
   747 setSortBlock: aSortBlock
   705     "set the sortblock without resorting - private only"
   748     "set the sortblock without resorting - private only"
   706 
   749 
   707     sortBlock := aSortBlock
   750     sortBlock := aSortBlock
   708 ! !
   751 ! !
   726 
   769 
   727 isSortedCollection
   770 isSortedCollection
   728     "return true. if I am a sorted collection"
   771     "return true. if I am a sorted collection"
   729 
   772 
   730     ^ true
   773     ^ true
       
   774 !
       
   775 
       
   776 speciesForCollecting
       
   777     "Redefined to return an OrderedCollection;
       
   778      see X3J20 spec. (SortedCollection>>collect: should return an OrderedCollection)"
       
   779 
       
   780     ^ OrderedCollection
   731 ! !
   781 ! !
   732 
   782 
   733 !SortedCollection methodsFor:'searching'!
   783 !SortedCollection methodsFor:'searching'!
   734 
   784 
   735 after:anObject ifAbsent:exceptionBlock
   785 after:anObject ifAbsent:exceptionBlock
   740      exceptionBlock."
   790      exceptionBlock."
   741 
   791 
   742     |index      "{ Class: SmallInteger }"
   792     |index      "{ Class: SmallInteger }"
   743      last       "{ Class: SmallInteger }"|
   793      last       "{ Class: SmallInteger }"|
   744 
   794 
   745     index := self indexForInserting:anObject.
   795     index := self indexOf:anObject.
   746     ((index < firstIndex)
   796     index == 0 ifTrue:[
   747      or:[(contentsArray at:index) ~= anObject]) ifTrue:[^ exceptionBlock value].
   797         ^ exceptionBlock value.
       
   798     ].
   748 
   799 
   749     "skip multiple occurrences of the same ..."
   800     "skip multiple occurrences of the same ..."
   750 
   801     index := index + firstIndex - 1.
   751     last := lastIndex.
   802     last := lastIndex.
   752     [(index <= last) and:[(contentsArray at:index) = anObject]] whileTrue:[
   803     [(index <= last) and:[(contentsArray basicAt:index) = anObject]] whileTrue:[
   753 	index := index + 1
   804         index := index + 1
   754     ].
   805     ].
   755     (index > last) ifTrue:[^ nil].
   806     (index > last) ifTrue:[^ exceptionBlock value].
   756     ^ contentsArray at:index
   807     ^ contentsArray basicAt:index
   757 
   808 
   758     "Modified: 12.4.1996 / 13:20:33 / cg"
   809     "
       
   810      #(7 3 9 10 99) asSortedCollection after:50
       
   811      #(7 3 9 10 99) asSortedCollection after:3
       
   812      #(7 3 9 10 99) asSortedCollection after:1
       
   813      #(7 3 9 10 99) asSortedCollection after:10
       
   814      #(7 3 9 10 99) asSortedCollection after:7
       
   815      #(7 3 9 10 99) asSortedCollection after:99
       
   816      #(7 10 3 10 9 10 10 99) asSortedCollection after:9
       
   817      #(7 10 3 10 9 10 10 99) asSortedCollection after:10
       
   818     "
   759 !
   819 !
   760 
   820 
   761 before:anObject ifAbsent:exceptionBlock
   821 before:anObject ifAbsent:exceptionBlock
   762     "return the element before the argument, anObject; or nil if there is none.
   822     "return the element before the argument, anObject; or nil if there is none.
   763      If the receiver does not contain anObject, return the result from evaluating
   823      If the receiver does not contain anObject, return the result from evaluating
   764      exceptionBlock."
   824      exceptionBlock."
   765 
   825 
   766     |index      "{ Class: SmallInteger }"|
   826     |index      "{ Class: SmallInteger }"|
   767 
   827 
   768     index := self indexForInserting:anObject.
   828     index := self indexOf:anObject.
   769     ((index <= firstIndex)
   829     index <= 1 ifTrue:[
   770      or:[(contentsArray at:index) ~= anObject]) ifTrue:[^ exceptionBlock value].
   830         ^ exceptionBlock value.
   771 
   831     ].
   772     ^ contentsArray at:index - 1
   832     ^ contentsArray basicAt:firstIndex + index - 2
   773 
   833 
   774     "
   834     "
   775      #(7 3 9 10 99) asSortedCollection before:50
   835      #(7 3 9 10 99) asSortedCollection before:50
       
   836      #(7 3 9 10 99) asSortedCollection before:3
   776      #(7 3 9 10 99) asSortedCollection before:1
   837      #(7 3 9 10 99) asSortedCollection before:1
   777      #(7 3 9 10 99) asSortedCollection before:10
   838      #(7 3 9 10 99) asSortedCollection before:10
   778      #(7 3 9 10 99) asSortedCollection before:7
   839      #(7 3 9 10 99) asSortedCollection before:7
   779      #(7 3 9 10 99) asSortedCollection before:99
   840      #(7 3 9 10 99) asSortedCollection before:99
   780      #(7 10 3 10 9 10 10 99) asSortedCollection before:9
   841      #(7 10 3 10 9 10 10 99) asSortedCollection before:9
   781      #(7 10 3 10 9 10 10 99) asSortedCollection before:10
   842      #(7 10 3 10 9 10 10 99) asSortedCollection before:10
   782     "
   843     "
   783 !
   844 !
   784 
   845 
   785 indexForInserting:anObject
   846 indexOf:anObject
   786     "search the index at which to insert anObject.
   847     "return true, if the argument, anObject is in the collection.
   787      Can also be used to search for an existing element
   848      Redefined, since due to being sorted, the inclusion check can
   788      by checking if the element at the returned index is the one we look for.
   849      be done with log-n compares i.e. much faster."
   789      Uses a binarySearch since we can depend on the elements being in sorted order.
   850 
   790      The returned index is a physical one, for accessing contentsArray."
   851     |index "{ Class: SmallInteger }"
   791 
   852      initialIndex "{ Class: SmallInteger }"
   792     |low    "{ Class: SmallInteger}"
       
   793      high   "{ Class: SmallInteger}"
       
   794      middle "{ Class: SmallInteger}"
       
   795      element|
   853      element|
   796 
   854 
   797     "
   855     "/ if I am small, the inherited linear search is faster ...
   798      we can of course use a binary search - since the elements are sorted
   856     (lastIndex - firstIndex) < 20 ifTrue:[
   799     "
   857         firstIndex > lastIndex ifTrue:[
   800     low := firstIndex.
   858             "/ empty
   801     high := lastIndex.
   859             ^ 0
   802     [low > high] whileFalse:[
   860         ].
   803         middle := (low + high) // 2.
   861         ^ super indexOf:anObject.
   804         element := contentsArray at:middle.
   862     ].
   805         (sortBlock value:element value:anObject) ifTrue:[
   863 
   806             "middleelement is smaller than object"
   864     initialIndex := self indexForInserting:anObject.
   807             low := middle + 1
   865     initialIndex > lastIndex ifTrue:[
   808         ] ifFalse:[
   866         initialIndex := lastIndex
   809             high := middle - 1
   867     ] ifFalse:[
       
   868         initialIndex < firstIndex ifTrue:[
       
   869             initialIndex := firstIndex
   810         ]
   870         ]
   811     ].
   871     ].
   812     ^ low
   872 
   813 
   873     "the complex case: the collection may include elements, which are odered only by
   814     "
   874      a single component (e.g. Associations by key). So we have to test all
   815      #(1 2 3 4 7 99 1313 981989 898989898) asSortedCollection indexForInserting:50
   875      previous and next elements having the same component"
   816 
   876 
   817      #(1.0 2.0 3 4 7 49.0 51.0 99 1313 981989 898989898) asSortedCollection indexForInserting:50
   877     "for previous elements: while element is not smaller and not larger than anObject ... compare"
   818 
   878     index := initialIndex.
   819     "
   879     [index >= firstIndex 
   820 
   880      and:[
   821     "Modified: 12.4.1996 / 13:22:03 / cg"
   881         element := contentsArray basicAt:index. 
   822 !
   882         ((sortBlock value:element value:anObject) or:[sortBlock value:anObject value:element]) not]
   823 
   883     ] whileTrue:[
   824 indexOf:anElement
   884         element = anObject ifTrue:[
   825     "Return the index of anElement within the receiver.
   885             ^ index - firstIndex + 1.
   826      If the receiver does not contain anElement, return 0."
   886         ].
   827 
   887         index := index - 1.
   828     ^ self indexOf:anElement ifAbsent:0
   888     ].
       
   889 
       
   890     "for next elements: while element is not smaller and not larger than anObject ... compare"
       
   891     index := initialIndex.
       
   892     [index <= lastIndex 
       
   893      and:[
       
   894         element := contentsArray basicAt:index. 
       
   895         ((sortBlock value:element value:anObject) or:[sortBlock value:anObject value:element]) not]
       
   896     ] whileTrue:[
       
   897         element = anObject ifTrue:[
       
   898             ^ index - firstIndex + 1.
       
   899         ].
       
   900         index := index + 1.
       
   901     ].
       
   902 
       
   903     ^ 0.
       
   904 
       
   905     "
       
   906      #(7 3 9 10 99) asSortedCollection indexOf:50
       
   907      #(7 3 9 10 99) asSortedCollection indexOf:10
       
   908 
       
   909      #('aa' 'bb' 'cc' 'dd') asSortedCollection indexOf:'bb'
       
   910      #('aa' 'bb' 'cc' 'dd' 'aa' 'bb' 'cc' 'dd') asSortedCollection indexOf:'bb'
       
   911 
       
   912      |allSyms indices|
       
   913      allSyms := Symbol allInstances asSortedCollection.
       
   914      Time millisecondsToRun:[
       
   915          indices := allSyms collect:[:el | allSyms indexOf:el].
       
   916      ].
       
   917      indices = (1 to:allSyms size)
       
   918     "
   829 !
   919 !
   830 
   920 
   831 indexOf:anElement ifAbsent:exceptionBlock
   921 indexOf:anElement ifAbsent:exceptionBlock
   832     "Return the index of anElement within the receiver.
   922     "Return the index of anElement within the receiver.
   833      If the receiver does not contain anElement,
   923      If the receiver does not contain anElement,
   834      return the result of evaluating the argument, exceptionBlock."
   924      return the result of evaluating the argument, exceptionBlock."
   835 
   925 
   836     |insertionIndex index "{ Class: SmallInteger }"
   926     |idx|
   837      obj|
   927 
   838 
   928     idx := self indexOf:anElement.
   839     firstIndex > lastIndex ifTrue:[
   929     idx == 0 ifTrue:[^ exceptionBlock value].
   840 	"/ empty
   930     ^ idx.
   841 	^ exceptionBlock value
       
   842     ].
       
   843 
       
   844     "/ if I am small, the inherited linear search is faster ...
       
   845     (lastIndex - firstIndex) < 20 ifTrue:[
       
   846 	^ super indexOf:anElement ifAbsent:exceptionBlock
       
   847     ].
       
   848 
       
   849     insertionIndex := self indexForInserting:anElement.
       
   850     insertionIndex > lastIndex ifTrue:[
       
   851 	insertionIndex := lastIndex
       
   852     ] ifFalse:[
       
   853 	insertionIndex < firstIndex ifTrue:[
       
   854 	    insertionIndex := firstIndex
       
   855 	]
       
   856     ].
       
   857 
       
   858     index := insertionIndex.
       
   859     [index >= firstIndex
       
   860     and:[obj := contentsArray basicAt:index.
       
   861 	    anElement = obj ifTrue: [^ index - firstIndex + 1].
       
   862 	    [sortBlock value:anElement value:obj]]]
       
   863 		    whileTrue: [index := index - 1].
       
   864 
       
   865     index := insertionIndex.
       
   866     [index <= lastIndex
       
   867     and: [obj := contentsArray basicAt: index.
       
   868 	    anElement = obj ifTrue: [^ index - firstIndex + 1].
       
   869 	    [sortBlock value:obj value:anElement]]]
       
   870 		    whileTrue: [index := index + 1].
       
   871 
       
   872     ^exceptionBlock value
       
   873 
       
   874     "
       
   875      #('aa' 'bb' 'cc' 'dd') asSortedCollection indexOf:'bb'
       
   876      #('aa' 'bb' 'cc' 'dd' 'aa' 'bb' 'cc' 'dd') asSortedCollection indexOf:'bb'
       
   877 
       
   878      |allSyms indices|
       
   879      allSyms := Symbol allInstances asSortedCollection.
       
   880      Time millisecondsToRun:[
       
   881 	 indices := allSyms collect:[:el | allSyms indexOf:el].
       
   882      ].
       
   883      indices = (1 to:allSyms size)
       
   884     "
       
   885 !
   931 !
   886 
   932 
   887 largest:n
   933 largest:n
   888     "return a collection containing the n largest elements, largest last.
   934     "return a collection containing the n largest elements, largest last.
   889      Raises an exception, if the receiver does not contain at least n elements"
   935      Raises an exception, if the receiver does not contain at least n elements"
   963 !SortedCollection methodsFor:'statistical functions'!
  1009 !SortedCollection methodsFor:'statistical functions'!
   964 
  1010 
   965 median
  1011 median
   966     "Return the middle element, or as close as we can get."
  1012     "Return the middle element, or as close as we can get."
   967 
  1013 
   968     ^ self at:(self size + 1 // 2)
  1014     ^ self basicAt:(self size + 1 // 2)
   969 
  1015 
   970     "
  1016     "
   971      #(10 35 20 45 30 5) asSortedCollection median
  1017      #(10 35 20 45 30 5) asSortedCollection median
   972      #(10 35 20 45 30 5) median
  1018      #(10 35 20 45 30 5) median
   973     "
  1019     "
   978 includes:anObject
  1024 includes:anObject
   979     "return true, if the argument, anObject is in the collection.
  1025     "return true, if the argument, anObject is in the collection.
   980      Redefined, since due to being sorted, the inclusion check can
  1026      Redefined, since due to being sorted, the inclusion check can
   981      be done with log-n compares i.e. much faster."
  1027      be done with log-n compares i.e. much faster."
   982 
  1028 
   983     |index "{ Class: SmallInteger }"|
  1029     |index "{ Class: SmallInteger }"
   984 
  1030      initialIndex "{ Class: SmallInteger }"
   985     index := self indexForInserting:anObject.
  1031      element|
   986     ((index < firstIndex) or:[index > lastIndex]) ifTrue:[^ false].
  1032 
   987     ^ (contentsArray at:index) = anObject
  1033     "/ if I am small, the inherited linear search is faster ...
       
  1034     (lastIndex - firstIndex) < 20 ifTrue:[
       
  1035         firstIndex > lastIndex ifTrue:[
       
  1036             "/ empty
       
  1037             ^ false
       
  1038         ].
       
  1039         ^ super includes:anObject.
       
  1040     ].
       
  1041 
       
  1042     initialIndex := self indexForInserting:anObject.
       
  1043     ((initialIndex < firstIndex) or:[initialIndex > lastIndex]) ifTrue:[^ false].
       
  1044     (contentsArray basicAt:initialIndex) = anObject ifTrue:[
       
  1045         "the simple case - plain objects"
       
  1046         ^ true.
       
  1047     ].
       
  1048 
       
  1049     "the complex case: the collection may include elements, which are odered only by
       
  1050      a single component (e.g. Associations by key). So we have to test all
       
  1051      previous and next elements having the same component"
       
  1052 
       
  1053     "for previous elements: while element is not smaller and not larger than anObject ... compare"
       
  1054     index := initialIndex - 1.
       
  1055     [index >= firstIndex 
       
  1056      and:[
       
  1057         element := contentsArray basicAt:index. 
       
  1058         ((sortBlock value:element value:anObject) or:[sortBlock value:anObject value:element]) not]
       
  1059     ] whileTrue:[
       
  1060         element = anObject ifTrue:[
       
  1061             ^ true.
       
  1062         ].
       
  1063         index := index - 1.
       
  1064     ].
       
  1065 
       
  1066     "for next elements: while element is not smaller and not larger than anObject ... compare"
       
  1067     index := initialIndex + 1.
       
  1068     [index <= lastIndex 
       
  1069      and:[
       
  1070         element := contentsArray basicAt:index. 
       
  1071         ((sortBlock value:element value:anObject) or:[sortBlock value:anObject value:element]) not]
       
  1072     ] whileTrue:[
       
  1073         element = anObject ifTrue:[
       
  1074             ^ true.
       
  1075         ].
       
  1076         index := index + 1.
       
  1077     ].
       
  1078 
       
  1079     ^ false.
   988 
  1080 
   989     "
  1081     "
   990      #(7 3 9 10 99) asSortedCollection includes:50
  1082      #(7 3 9 10 99) asSortedCollection includes:50
   991      #(7 3 9 10 99) asSortedCollection includes:10
  1083      #(7 3 9 10 99) asSortedCollection includes:10
   992     "
  1084     "
  1000 
  1092 
  1001     |index      "{ Class: SmallInteger }"
  1093     |index      "{ Class: SmallInteger }"
  1002      tally      "{ Class: SmallInteger }"
  1094      tally      "{ Class: SmallInteger }"
  1003      last       "{ Class: SmallInteger }" |
  1095      last       "{ Class: SmallInteger }" |
  1004 
  1096 
  1005     index := self indexForInserting:anObject.
  1097     index := self indexOf:anObject.
       
  1098     index == 0 ifTrue:[
       
  1099         ^ 0
       
  1100     ].
       
  1101 
       
  1102     index := index + firstIndex - 1.
  1006     last := lastIndex.
  1103     last := lastIndex.
  1007     ((index < firstIndex) or:[index > last]) ifTrue:[^ 0].
       
  1008 
  1104 
  1009     "/ there may be multiple of them; count 'em
  1105     "/ there may be multiple of them; count 'em
  1010 
  1106 
  1011     tally := 0.
  1107     tally := 0.
  1012     [(index <= last) and:[(contentsArray at:index) = anObject]] whileTrue:[
  1108     [(index <= last) and:[(contentsArray basicAt:index) = anObject]] whileTrue:[
  1013 	tally := tally + 1.
  1109         tally := tally + 1.
  1014 	index := index + 1
  1110         index := index + 1
  1015     ].
  1111     ].
  1016     ^ tally
  1112     ^ tally
  1017 
  1113 
  1018     "
  1114     "
  1019      #(7 3 9 10 99) asSortedCollection occurrencesOf:50
  1115      #(7 3 9 10 99) asSortedCollection occurrencesOf:50
  1020      #(7 3 9 10 99) asSortedCollection occurrencesOf:10
  1116      #(7 3 9 10 99) asSortedCollection occurrencesOf:10
  1021      #(7 10 3 10 9 10 10 99) asSortedCollection occurrencesOf:10
  1117      #(7 10 3 10 9 10 10 10 10 10 10 10 10 99) asSortedCollection occurrencesOf:10
  1022     "
  1118     "
  1023 
  1119 
  1024     "Modified: 12.4.1996 / 18:48:40 / cg"
  1120     "Modified: 12.4.1996 / 18:48:40 / cg"
  1025 ! !
  1121 ! !
  1026 
  1122 
  1027 !SortedCollection class methodsFor:'documentation'!
  1123 !SortedCollection class methodsFor:'documentation'!
  1028 
  1124 
  1029 version
  1125 version
  1030     ^ '$Header: /cvs/stx/stx/libbasic/SortedCollection.st,v 1.78 2014-02-12 14:36:52 cg Exp $'
  1126     ^ '$Header$'
  1031 !
  1127 !
  1032 
  1128 
  1033 version_CVS
  1129 version_CVS
  1034     ^ '$Header: /cvs/stx/stx/libbasic/SortedCollection.st,v 1.78 2014-02-12 14:36:52 cg Exp $'
  1130     ^ '$Header$'
  1035 ! !
  1131 ! !
  1036 
  1132 
  1037 
  1133 
  1038 SortedCollection initialize!
  1134 SortedCollection initialize!