Initial commit to the PapyrusRT repository.
This is the initial commit as submitted to CQ 9646.
The repository contains two top-level folders:
- codegen: the code-generator
- rts: the run-time system
Also-by: Andrew Eidsness, Zeligsoft contractor, andrewe@jfront.com,
Barry Maher, Zeligsoft contractor, bmaher@gpinc.ca, Ernesto Posse,
Zeligsoft, eposse@zeligsoft.com, Tim McGuire, Zeligsoft,
tmcguire@zeligsoft.com, Young-Soo Roh, Zeligsoft, ysroh@zeligsoft.com,
Toby McClean, Zeligsoft, toby@zeligsoft.com, Charles Rivet, Zeligsoft,
charles@zeligsoft.com, Andreas Henriksson, Ericsson,
andreas.henriksson@ericsson.com, Akos Horvath, IncQuery Labs,
akos.horvath@incquerylabs.com, Gabor Batori, Ericsson,
Gabor.Batori@ericsson.com, Abel Hegedus, IncQuery Labs,
abel.hegedus@incquerylabs.com, Denes Harmath, IncQuery Labs,
harmathdenes@gmail.com
Signed-off-by: Ernesto Posse <eposse@gmail.com>
diff --git a/rts/umlrt/umlrthashmap.cc b/rts/umlrt/umlrthashmap.cc
new file mode 100644
index 0000000..e0189ea
--- /dev/null
+++ b/rts/umlrt/umlrthashmap.cc
@@ -0,0 +1,290 @@
+// umlrthashmap.hh
+
+/*******************************************************************************
+* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+
+#include "umlrthashmap.hh"
+#include "umlrtguard.hh"
+#include "basefatal.hh"
+#include <stdlib.h>
+#include <string.h>
+
+UMLRTHashMap::~UMLRTHashMap()
+{
+ mutex.take();
+
+ for (int i = 0; i < mapSize; ++i)
+ {
+ if (map[i].object != NULL)
+ {
+ free( (void *)map[i].object );
+ }
+ }
+ if (mapSize)
+ {
+ free( map );
+ }
+}
+
+/*static*/ int UMLRTHashMap::compareString( const void * k1, const void * k2 )
+{
+ if ((k1 == NULL) && (k2 != NULL))
+ {
+ return -1;
+ }
+ else if ((k1 != NULL) && (k2 == NULL))
+ {
+ return 1;
+ }
+ else if ((k1 == NULL) && (k2 == NULL))
+ {
+ return 0;
+ }
+ return strcmp((const char *)k1, (const char *)k2);
+}
+
+/*static*/ int UMLRTHashMap::compareValue( const void * k1, const void * k2 )
+{
+ return (char *)k1 - (char *)k2;
+}
+
+UMLRTHashMap::MapEntry * UMLRTHashMap::getEntry( const void * key ) const
+{
+ // Assumes mutex is taken.
+ MapEntry * entry = NULL;
+
+ int location = locate(key);
+
+ if ((location >= 0) && (location < mapSize))
+ {
+ if (compare(map[location].key, key) == 0)
+ {
+ entry = &map[location];
+ }
+ }
+ return entry;
+}
+
+void * UMLRTHashMap::getFirstObject() const
+{
+ // Return object associated with key. Return NULL if entry not found.
+ UMLRTGuard g(mutex);
+
+ void * object = NULL;
+ if (mapSize > 0)
+ {
+ object = map[0].object;
+ }
+ return object;
+}
+
+void * UMLRTHashMap::getObject( const void * key ) const
+{
+ // Return object associated with key. Return NULL if entry not found.
+ UMLRTGuard g(mutex);
+
+ void * object = NULL;
+ MapEntry * entry = getEntry(key);
+
+ if (entry != NULL)
+ {
+ object = entry->object;
+ }
+ return object;
+}
+
+const void * UMLRTHashMap::getKey( int location ) const
+{
+ // Return key associated with entry at location.
+ UMLRTGuard g(mutex);
+
+ const void * key = NULL;
+
+ if ((location >= 0) && (location < mapSize))
+ {
+ key = map[location].key;
+ }
+ return key;
+}
+
+void * UMLRTHashMap::getObject( int location ) const
+{
+ // Return key associated with entry at location.
+ UMLRTGuard g(mutex);
+
+ void * object = NULL;
+
+ if ((location >= 0) && (location < mapSize))
+ {
+ object = map[location].object;
+ }
+ return object;
+}
+
+void UMLRTHashMap::insert( const void * key, void * object )
+{
+ UMLRTGuard g(mutex);
+
+ MapEntry * entry = getEntry(key);
+ if (entry)
+ {
+ entry->object = object;
+ }
+ else
+ {
+ // Entry not find. Insert it.
+ int location = locate(key);
+
+ if (mapSize == 0)
+ {
+ map = (MapEntry *)malloc(sizeof(MapEntry));
+ }
+ else
+ {
+ map = (MapEntry *)realloc(map, (mapSize + 1) * sizeof(MapEntry));
+ memmove(&map[location + 1], &map[location], (mapSize - location) * sizeof(MapEntry));
+ }
+ ++mapSize;
+ map[location].key = key;
+ map[location].object = object;
+ }
+}
+
+int UMLRTHashMap::locate( const void * key ) const
+{
+ // Assumes mutex is taken.
+ // Returns either location of entry holding 'key' or the location where 'key' belongs (first entry where entry->key > input key).
+ int min, max, mid;
+ int location = -1;
+
+ min = 0;
+ max = mapSize - 1;
+
+ while (location == -1)
+ {
+ if (min > max)
+ {
+ // Zeroed in on location. It's 'min' or the one after.
+ location = min;
+ if (min < (mapSize-1))
+ {
+ if (compare(map[min].key, key) < 0)
+ {
+ // 'min' was one before location we want.
+ location = min + 1;
+ }
+ }
+ }
+ else
+ {
+ mid = (min + max) / 2;
+ if (compare(map[mid].key, key) == 0)
+ {
+ // located it
+ location = mid;
+ }
+ else if (compare(map[mid].key, key) < 0)
+ {
+ // location must be after 'mid'.
+ if ((min = (mid + 1)) >= mapSize)
+ {
+ // location falls after last item
+ location = mapSize;
+ }
+ }
+ else if ((max = (mid - 1)) < 0)
+ {
+ // location falls before first item
+ location = 0;
+ }
+ }
+ }
+ return location;
+}
+
+const void * UMLRTHashMap::remove( const void * key )
+{
+ UMLRTGuard g(mutex);
+
+ int location = locate(key);
+ const void * keyRemoved = NULL;
+
+ if (mapSize)
+ {
+ if (location < mapSize)
+ {
+ if (compare(map[location].key, key) == 0)
+ {
+ keyRemoved = map[location].key;
+ memmove(&map[location], &map[location + 1], (mapSize - location) * sizeof(MapEntry));
+ if ((--mapSize) == 0)
+ {
+ free(map);
+ map = NULL;
+ }
+ }
+ }
+ }
+ return keyRemoved;
+}
+
+UMLRTHashMap::Iterator UMLRTHashMap::getIterator() const
+{
+ if (!mapSize)
+ {
+ return Iterator(this, -1);
+ }
+ return Iterator(this, 0);
+}
+
+UMLRTHashMap::Iterator UMLRTHashMap::Iterator::end() const
+{
+ return Iterator(map, -1);
+}
+
+UMLRTHashMap::Iterator UMLRTHashMap::Iterator::next() const
+{
+ if (index == -1)
+ {
+ return end();
+ }
+ else if (map->isEmpty())
+ {
+ return end();
+ }
+ else if (index == (map->getSize() - 1))
+ {
+ return end();
+ }
+ return Iterator(map, index + 1);
+}
+
+const void * UMLRTHashMap::Iterator::getKey() const
+{
+ const void * key = NULL;
+
+ if (index != -1)
+ {
+ key = map->getKey(index);
+ }
+ return key;
+}
+
+void * UMLRTHashMap::Iterator::getObject() const
+{
+ void * object = NULL;
+
+ if (index != -1)
+ {
+ if (map->getSize() > 0)
+ {
+ object = map->getObject(index);
+ }
+ }
+ return object;
+}