diff --git a/framework/libraries/HashMap/Examples/HelloHashMap/HelloHashMap.ino b/framework/libraries/HashMap/Examples/HelloHashMap/HelloHashMap.ino new file mode 100644 index 0000000..5ce0242 --- /dev/null +++ b/framework/libraries/HashMap/Examples/HelloHashMap/HelloHashMap.ino @@ -0,0 +1,38 @@ +#include + +//define hashmap storage variable +HashMap hashMap; + +void setup(){ + + Serial.begin(9600); + + //putting object into hashmap variable + hashMap.put("name",18); + hashMap.put("test",200); + hashMap.put("qwer",1234); + hashMap.put("abc",123); + hashMap.put("AlphaBeta",20); + + //getting value + Serial.println(hashMap.getValue("qwer")); //print 1234 + + + //containsKey function + Serial.println(hashMap.containsKey("test")); //print 1 + + Serial.println(hashMap.containsKey("ciaociao")); //print 0 + + + //length + Serial.println(hashMap.length()); //print 5 + + //remove + hashMap.remove("abc"); //remove object that is associated to "abc" key + + Serial.println(hashMap.length()); //print 4 + + +} + +void loop(){/*nothing to loop*/} diff --git a/framework/libraries/HashMap/HashMap.h b/framework/libraries/HashMap/HashMap.h index 3d1623b..2a89b83 100644 --- a/framework/libraries/HashMap/HashMap.h +++ b/framework/libraries/HashMap/HashMap.h @@ -1,238 +1,424 @@ -/* $Id: HashMap.h 1198 2011-06-14 21:08:27Z bhagman $ -|| -|| @author Alexander Brevig -|| @url http://wiring.org.co/ -|| @url http://alexanderbrevig.com/ -|| @contribution Brett Hagman -|| -|| @description -|| | Implementation of a HashMap data structure. -|| | -|| | Wiring Cross-platform Library -|| # -|| -|| @license Please see cores/Common/License.txt. -|| -*/ - -#ifndef HASHMAP_H -#define HASHMAP_H - -#include "Countable.h" - -//for convenience -#define CreateHashMap(hashM, ktype, vtype, capacity) HashMap hashM -#define CreateComplexHashMap(hashM, ktype, vtype, capacity, comparator) HashMap hashM(comparator) - -template -class HashMap -{ - public: - typedef bool (*comparator)(K, K); - - /* - || @constructor - || | Initialize this HashMap - || # - || - || @parameter compare optional function for comparing a key against another (for complex types) - */ - HashMap(comparator compare = 0) - { - cb_comparator = compare; - currentIndex = 0; - } - - /* - || @description - || | Get the size of this HashMap - || # - || - || @return The size of this HashMap - */ - unsigned int size() const - { - return currentIndex; - } - - /* - || @description - || | Get a key at a specified index - || # - || - || @parameter idx the index to get the key at - || - || @return The key at index idx - */ - K keyAt(unsigned int idx) - { - return keys[idx]; - } - - /* - || @description - || | Get a value at a specified index - || # - || - || @parameter idx the index to get the value at - || - || @return The value at index idx - */ - V valueAt(unsigned int idx) - { - return values[idx]; - } - - /* - || @description - || | Check if a new assignment will overflow this HashMap - || # - || - || @return true if next assignment will overflow this HashMap - */ - bool willOverflow() - { - return (currentIndex + 1 > capacity); - } - - /* - || @description - || | An indexer for accessing and assigning a value to a key - || | If a key is used that exists, it returns the value for that key - || | If there exists no value for that key, the key is added - || # - || - || @parameter key the key to get the value for - || - || @return The const value for key - */ - const V& operator[](const K key) const - { - return operator[](key); - } - - /* - || @description - || | An indexer for accessing and assigning a value to a key - || | If a key is used that exists, it returns the value for that key - || | If there exists no value for that key, the key is added - || # - || - || @parameter key the key to get the value for - || - || @return The value for key - */ - V& operator[](const K key) - { - if (contains(key)) - { - return values[indexOf(key)]; - } - else if (currentIndex < capacity) - { - keys[currentIndex] = key; - values[currentIndex] = nil; - currentIndex++; - return values[currentIndex - 1]; - } - return nil; - } - - /* - || @description - || | Get the index of a key - || # - || - || @parameter key the key to get the index for - || - || @return The index of the key, or -1 if key does not exist - */ - unsigned int indexOf(K key) - { - for (int i = 0; i < currentIndex; i++) - { - if (cb_comparator) - { - if (cb_comparator(key, keys[i])) - { - return i; - } - } - else - { - if (key == keys[i]) - { - return i; - } - } - } - return -1; - } - - /* - || @description - || | Check if a key is contained within this HashMap - || # - || - || @parameter key the key to check if is contained within this HashMap - || - || @return true if it is contained in this HashMap - */ - bool contains(K key) - { - for (int i = 0; i < currentIndex; i++) - { - if (cb_comparator) - { - if (cb_comparator(key, keys[i])) - { - return true; - } - } - else - { - if (key == keys[i]) - { - return true; - } - } - } - return false; - } - - /* - || @description - || | Check if a key is contained within this HashMap - || # - || - || @parameter key the key to remove from this HashMap - */ - void remove(K key) - { - int index = indexOf(key); - if (contains(key)) - { - for (int i = index; i < capacity - 1; i++) - { - keys[i] = keys[i + 1]; - values[i] = values[i + 1]; - } - currentIndex--; - } - } - - void setNullValue(V nullv) - { - nil = nullv; - } - - protected: - K keys[capacity]; - V values[capacity]; - V nil; - int currentIndex; - comparator cb_comparator; +#ifndef __HASHMAP_H__ +#define __HASHMAP_H__ + + +#include + + +/* Handle association */ +template + +class HashType { + + public: + + HashType(){ + reset(); + } + + ~HashType(){ //distruttore + + //Serial.println("HashType destructing..."); + //hashCode.~hash(); + //hashCode.~hash(); + //Serial.println("HashType destruct"); + } + + HashType(hash code, map value): hashCode(code), mappedValue(value){} + + void reset(){ + hashCode = 0; mappedValue = 0; + } + + hash getHash(){ + return hashCode; + } + + void setHash(hash code){ + hashCode = code; + } + + map getValue(){ + return mappedValue; + } + + void setValue(map value){ + mappedValue = value; + } + + HashType& operator()(hash code, map value){ + setHash( code ); + setValue( value ); + } + private: + hash hashCode; + map mappedValue; +}; + + +//classe nodo per la lista + +template + +class HashNode { + + public: + + HashNode(hash code, map value) { + + hashType = new HashType(code, value); + + previus = 0; + + next = 0; + + } + + ~HashNode() { //distruttore + //Serial.println("HashNode destructing..."); + + delete hashType; + + //Serial.println("HashNode destruct"); + } + + HashType * getHashType() { + return hashType; + } + + HashNode * getPrevius() { + return previus; + } + + HashNode * getNext() { + return next; + } + + void setPrevius(HashNode * previus) { + + this->previus = previus; + + } + + void setNext(HashNode * next) { + + this->next = next; + + } + + + private: + + HashType * hashType; + + HashNode * previus; + + HashNode * next; + + +}; + + +//classe che gestisce l'hash map +template +class HashMap { + + private: + HashNode * start; + + HashNode * finish; + + HashNode * position; + + int size; + + + HashNode * getPosition(hash key) { //get di un elemento + + for(HashNode * pointer = start; pointer != 0; pointer = pointer->getNext()) { + + HashType * hashType = pointer->getHashType(); + + if (key == hashType->getHash()) { + + return pointer; + + } + + } + + return 0; + + } + + + void remove(HashNode * pointer) { //rimuove l'elemento selezionato + + if (size == 1) { //1 elemento presente 1 elemento da eliminare + + //Serial.println("1 solo: remove p"); + + start = finish = 0; + + } else { //pių di un elemento presente + + if (pointer == start) { //elemto da rimuovere č la testa + + start = start->getNext(); + + start->setPrevius(0); + + } else if (pointer == finish) { //elemnto da rimuovere č la coda + + finish = finish->getPrevius(); + + finish->setNext(0); + + } else { //elemento da rimuovere in mezzo alla lista + + pointer->getPrevius()->setNext(pointer->getNext()); + + pointer->getNext()->setPrevius(pointer->getPrevius()); + + } + + } + + size--; + + + //Serial.println("dealloc"); + + + delete pointer; + + } + + + public: + + HashMap(){ + + start = 0; + finish = 0; + position = 0; + + size = 0; + + } + + ~HashMap(){ //distruttore + + //Serial.println("HashMap destructing..."); + //Serial.print("n: "); + //Serial.println(length()); + + if (moveToFirst()) { + + do { + + remove(); + + } while (moveToNext()); + + } + + + //Serial.println("HashMap destruct"); + + } + + void put(hash key, map value) { //inserisce un nuovo nodo contenente i dati + + if (start == 0) { + + start = finish = new HashNode(key, value); + + } else { + + HashNode * temp = new HashNode(key, value); + + finish->setNext(temp); + + temp->setPrevius(finish); + + finish = temp; + + } + + size++; + + } + + map getValue(hash key) { //get di un elemento + + HashNode * pointer = getPosition(key); + + if (pointer != 0) { + + return pointer->getHashType()->getValue(); + + } + + } + + + int containsKey(hash key) { //1 se contiene la chiave 0 altrimenti + + if (getPosition(key) != 0) { + + return 1; + + } else { + + return 0; + + } + + } + + void remove(hash key) { + + HashNode * pointer = getPosition(key); + + if (pointer != 0) { + + remove(pointer); + + } + + + } + + int length() { + + return size; + + } + + + //metodi per implementare la mia interfaccia iterable 1 ok, 0 non esistono pių elementi + int moveToFirst() { + + if (start != 0) { + + position = start; + + return 1; + + } else { + + return 0; + + } + + } + + int moveToLast() { + + if (finish != 0) { + + position = finish; + + return 1; + + } else { + + return 0; + + } + + } + + + int moveToNext() { + + if (position->getNext() != 0) { + + position = position->getNext(); + + return 1; + + } else { + + return 0; + + } + + } + + int moveToPrev() { + + if (position->getPrevius() != 0) { + + position = position->getPrevius(); + + return 1; + + } else { + + return 0; + + } + + } + + + map getValue() { //get di un elemento + + if (position != 0) { + + return position->getHashType()->getValue(); + + } + + } + + hash getKey() { //get hash di un elemento + + if (position != 0) { + + return position->getHashType()->getHash(); + + } + + } + + void remove() { + + if (position != 0) { + + if (size == 1) { //1 ele 1 da rimuovere + + //Serial.println("1 solo: remove"); + + remove(position); + + position = 0; + + } else { + + if (position == start) { + + remove(position); + + position = start; + + } else { + + remove(position); + + position = position->getPrevius(); + + } + + } + + } + + } + + }; #endif -// HASHMAP_H diff --git a/framework/libraries/HashMap/examples/HelloHashMap/HelloHashMap.pde b/framework/libraries/HashMap/examples/HelloHashMap/HelloHashMap.pde deleted file mode 100644 index 7814732..0000000 --- a/framework/libraries/HashMap/examples/HelloHashMap/HelloHashMap.pde +++ /dev/null @@ -1,61 +0,0 @@ -/** - * HelloHashMap - * by BREVIG http://alexanderbrevig.com - * - * Demonstrate the usage of a HashMap - * This HashMap will pair a char* string to an integer and it has the capacity to hold three pairs - */ - -#include - -CreateHashMap(hashMap, char*, int, 3); //create hashMap that pairs char* to int and can hold 3 pairs - -void setup() -{ - //add and store keys and values - hashMap["newKey"] = 12; - hashMap["otherKey"] = 13; - - //check if overflow (there should not be any danger yet) - Serial.print("Will the hashMap overflow now [after 2 assigns] ?: "); - Serial.println(hashMap.willOverflow()); - - hashMap["lastKey"] = 14; - - //check if overflow (this should be true, as we have added 3 of 3 pairs) - Serial.print("Will the hashMap overflow now [after 3 assigns] ?: "); - Serial.println(hashMap.willOverflow()); - - //it will overflow, but this won't affect the code. - hashMap["test"] = 15; - - //change the value of newKey - Serial.print("The old value of newKey: "); - Serial.println(hashMap["newKey"]); - - hashMap["newKey"]++; - - Serial.print("The new value of newKey (after hashMap['newKey']++): "); - Serial.println(hashMap["newKey"]); - - //remove a key from the hashMap - hashMap.remove("otherKey"); - - //this should work as there is now an availabel spot in the hashMap - hashMap["test"] = 15; - - printHashMap(); -} - -void loop() {} - -void printHashMap() -{ - for (int i=0; i