From: <bi...@us...> - 2011-02-06 13:09:44
|
Revision: 6707 http://oorexx.svn.sourceforge.net/oorexx/?rev=6707&view=rev Author: bigrixx Date: 2011-02-06 13:09:37 +0000 (Sun, 06 Feb 2011) Log Message: ----------- [ oorexx-Feature Requests-2100054 ] Add a removeAll method to relation class. Modified Paths: -------------- main/trunk/interpreter/classes/RelationClass.cpp main/trunk/interpreter/classes/RelationClass.hpp main/trunk/interpreter/classes/support/RexxHashTable.cpp main/trunk/interpreter/classes/support/RexxHashTable.hpp main/trunk/interpreter/execution/CPPCode.cpp main/trunk/interpreter/memory/Setup.cpp Modified: main/trunk/interpreter/classes/RelationClass.cpp =================================================================== --- main/trunk/interpreter/classes/RelationClass.cpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/classes/RelationClass.cpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -190,6 +190,22 @@ } +/** + * Remove all items with a given index. + * + * @param _index The index to remove. + * + * @return An array of all removed items. Returns an empty array + * if the index is not found. + */ +RexxObject *RexxRelation::removeAll(RexxObject *_index) +{ + requiredArgument(_index, ARG_ONE); /* make sure we have an index */ + /* just get from the hash table */ + return this->contents->removeAll(_index); +} + + RexxObject *RexxRelation::put( RexxObject *_value, /* new value to add */ RexxObject *_index) /* index for insertion */ Modified: main/trunk/interpreter/classes/RelationClass.hpp =================================================================== --- main/trunk/interpreter/classes/RelationClass.hpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/classes/RelationClass.hpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -58,6 +58,7 @@ RexxObject *hasItem(RexxObject *, RexxObject *); RexxObject *allAt(RexxObject *); RexxObject *allIndex(RexxObject *); + RexxObject *removeAll(RexxObject *); RexxObject *itemsRexx(RexxObject *); RexxSupplier *supplier(RexxObject *); RexxObject *removeItem(RexxObject *, RexxObject *); Modified: main/trunk/interpreter/classes/support/RexxHashTable.cpp =================================================================== --- main/trunk/interpreter/classes/support/RexxHashTable.cpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/classes/support/RexxHashTable.cpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -324,6 +324,87 @@ return OREF_NULL; /* removed item not found */ } + +/** + * Remove all elements with a given index from a hashtable, + * returning an array of all items. + * + * @param _index The target index. + * + * @return An array of all matching items. + */ +RexxObject *RexxHashTable::removeAll(RexxObject *_index) +{ + // get a count of matching items + size_t count = countAll(_index); + HashLink position = hashIndex(_index); /* calculate the hash slot */ + RexxArray *result = new_array(count); /* get proper size result array */ + // only copy if we have something to remove + if (count > 0) + { + size_t i = 1; /* start at the first element */ + HashLink previous = NO_LINK; /* no previous slot yet */ + do + { /* while more items in chain */ + /* copy the value into our array */ + result->put(this->entries[position].value,i++); + /* if got a match */ + if (EQUAL_VALUE(_index, this->entries[position].index)) + { + /* get the next pointer */ + HashLink _next = this->entries[position].next; + if (_next == NO_MORE) + { /* end of the chain? */ + /* clear this slot entry */ + OrefSet(this,this->entries[position].index,OREF_NULL); + OrefSet(this,this->entries[position].value,OREF_NULL); + if (previous != NO_LINK) /* if not the first of the chain */ + { + /* IH: In this special case we delete an item from the overhead and + therefore might have to increase the free counter, otherwise + hash table will be extended unnecessarily !!! */ + if (position > this->free) + { + this->free = position; + } + /* break the link */ + this->entries[previous].next = NO_MORE; + } + return result; // we've hit the end of the chain, we're done + } /* non-terminal chain element */ + else + { + /* close up the link */ + this->entries[position].next = this->entries[_next].next; + /* copy value and index to current */ + OrefSet(this,this->entries[position].index,this->entries[_next].index); + OrefSet(this,this->entries[position].value,this->entries[_next].value); + /* clear the next entry */ + OrefSet(this,this->entries[_next].index,OREF_NULL); + OrefSet(this,this->entries[_next].value,OREF_NULL); + /* set to "pristine" condition */ + this->entries[_next].next = NO_MORE; + if (this->free < _next) /* new-low water mark? */ + { + this->free = _next; /* reset to this point */ + } + + // NOTE: We don't update either previous or position because we'll + // be looking at the same link again + } + } + else + { + // remember the previous position and step to the next one + previous = position; + position = this->entries[position].next; + } + /* step to the next link */ + } while (position != NO_MORE); + } + return result; /* return the result array */ +} + RexxObject *RexxHashTable::primitiveRemove( RexxObject *_index) /* index to remove */ /******************************************************************************/ Modified: main/trunk/interpreter/classes/support/RexxHashTable.hpp =================================================================== --- main/trunk/interpreter/classes/support/RexxHashTable.hpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/classes/support/RexxHashTable.hpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -90,6 +90,7 @@ RexxObject *mergeItem(RexxObject *value, RexxObject *index); RexxHashTable *add(RexxObject *value, RexxObject *key); RexxObject *remove(RexxObject *key); + RexxObject *removeAll(RexxObject *key); RexxArray *getAll(RexxObject *key); size_t countAll(RexxObject *key); RexxObject *get(RexxObject *key); Modified: main/trunk/interpreter/execution/CPPCode.cpp =================================================================== --- main/trunk/interpreter/execution/CPPCode.cpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/execution/CPPCode.cpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -952,6 +952,7 @@ CPPM(RexxRelation::put), /* Relation methods */ CPPM(RexxRelation::removeItemRexx), +CPPM(RexxRelation::removeAll), CPPM(RexxRelation::allIndex), CPPM(RexxRelation::itemsRexx), CPPM(RexxRelation::supplier), Modified: main/trunk/interpreter/memory/Setup.cpp =================================================================== --- main/trunk/interpreter/memory/Setup.cpp 2011-02-06 03:33:28 UTC (rev 6706) +++ main/trunk/interpreter/memory/Setup.cpp 2011-02-06 13:09:37 UTC (rev 6707) @@ -748,6 +748,7 @@ defineKernelMethod(CHAR_ALLINDEXES , TheRelationBehaviour, CPPM(RexxHashTableCollection::allIndexes), 0); defineKernelMethod(CHAR_EMPTY , TheRelationBehaviour, CPPM(RexxHashTableCollection::empty), 0); defineKernelMethod(CHAR_ISEMPTY , TheRelationBehaviour, CPPM(RexxHashTableCollection::isEmpty), 0); + defineKernelMethod("REMOVEALL" , TheRelationBehaviour, CPPM(RexxRelation::removeAll), 1); /* set the scope of the methods to */ /* this classes oref */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |