00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stlib/Set.h>
00025 #include <stlib/Array.h>
00026 #include <stlib/Iterator.h>
00027 #include <stlib/String.h>
00028 #include <stlib/NotFoundError.h>
00029
00030
00031
00032 Set::Set(int length)
00033 {
00034 content = new Array(length);
00035 tally = 0;
00036 }
00037
00038 Set::~Set(void)
00039 {
00040 delete content;
00041 }
00042
00043
00044 Set::Set(Set &origin)
00045 {
00046 tally = origin.tally;
00047 content = (Array *) origin.content->copy();
00048 }
00049
00050
00051 String *Set::className(void) const
00052 {
00053 return new String("Set");
00054 }
00055
00056
00057 long Set::capacity(void) const
00058 {
00059 return content->size();
00060 }
00061
00062 long Set::size(void) const
00063 {
00064 return tally;
00065 }
00066
00067 Object *Set::any(void)
00068 {
00069 return content->any();
00070 }
00071
00072
00073 void Set::add(Object *obj)
00074 {
00075 int index;
00076
00077 if (obj == nil) return;
00078 index = findElementOrNil(obj);
00079 if (isEmptyAt(index))
00080 atNewIndexPut(index, obj);
00081 }
00082
00083
00084 Set *Set::asSet(void)
00085 {
00086 return this;
00087 }
00088
00089
00090 Object *Set::copy(void)
00091 {
00092 return new Set(*this);
00093 }
00094
00095 Object *Set::copyEmpty(long size)
00096 {
00097 return new Set(size);
00098 }
00099
00100
00101 Object *Set::remove(Object *obj)
00102 {
00103 int index;
00104
00105 index = findElementOrNil(obj);
00106 if (isEmptyAt(index)) {
00107 (new NotFoundError(__PRETTY_FUNCTION__, obj))->raiseFrom(this);
00108 } else {
00109 content->put(index, nil);
00110 tally = tally - 1;
00111 fixCollisionsFrom(index);
00112 }
00113 return obj;
00114 }
00115
00116
00117 bool Set::includes(Object *obj)
00118 {
00119 return !isEmptyAt(findElementOrNil(obj));
00120 }
00121
00122
00123
00124 Object *Set::privNextForIterator(CollectionIterator *iter) const
00125 {
00126 Object *obj;
00127 long index = iter->position();
00128
00129 for (; index < capacity(); index += 1) {
00130 if ((obj = content->at(index)) != nil) {
00131 iter->position(index);
00132 return obj;
00133 }
00134 }
00135 iter->position(index);
00136 return nil;
00137 }
00138
00139
00140 void Set::atNewIndexPut(int index, Object *obj)
00141 {
00142 content->put(index, obj);
00143 tally = tally + 1;
00144 fullCheck();
00145 }
00146
00147 void Set::changeCapacity(long newCapacity)
00148 {
00149 Array *oldContent;
00150 Iterator *i;
00151
00152 oldContent = content;
00153 content = new Array(newCapacity);
00154 tally = 0;
00155 for (i = oldContent->iterator(); !i->finished(); i->next()) {
00156 if (i->value() != nil)
00157 add(i->value());
00158 }
00159 delete i;
00160 delete oldContent;
00161 }
00162
00163 int Set::findElementOrNil(Object *obj)
00164 {
00165 int pass, length = capacity();
00166 Object *elem;
00167 int index;
00168
00169 index = obj->hash() % length;
00170
00171 if (index < 0) index = length + index;
00172 pass = 1;
00173 while ((elem = content->at(index)) != nil && !elem->isEqual(obj)) {
00174 index++;
00175 if (index >= length) {
00176 index = 0;
00177 pass++;
00178 if (pass > 2) {
00179 grow();
00180 return findElementOrNil(obj);
00181 }
00182 }
00183 }
00184 return index;
00185 }
00186
00187 void Set::fixCollisionsFrom(int oldIndex)
00188 {
00189 int length, nextIndex;
00190 Object *nextObject = nil;
00191
00192 length = capacity();
00193 nextIndex = oldIndex;
00194 do {
00195 if (nextIndex != oldIndex) {
00196 content->put(nextIndex, nextObject);
00197 content->put(oldIndex, nil);
00198 }
00199 oldIndex = (oldIndex + 1) % length;
00200 nextObject = content->at(oldIndex);
00201 if (nextObject != nil)
00202 nextIndex = findElementOrNil(nextObject);
00203 } while (nextObject != nil);
00204 }
00205
00206 void Set::fullCheck(void)
00207 {
00208 int sizePlusOne, cap;
00209
00210 cap = capacity();
00211 sizePlusOne = size() + 1;
00212 if (sizePlusOne >= cap || cap - sizePlusOne < (cap >> 2))
00213 grow();
00214 }
00215
00216 void Set::grow(void)
00217 {
00218 changeCapacity(capacity() + growSize());
00219 }
00220
00221 bool Set::isEmptyAt(int index)
00222 {
00223 return content->at(index) == nil;
00224 }
00225
00226 Object *Set::privAtIndex(int index)
00227 {
00228 return content->at(index);
00229 }