PDA

View Full Version : Hashtable Extension



mabello
20 Feb 2008, 4:42 PM
Some years ago, when the spectacular framework ExtJS was maybe a thought in the mind of Jack and all the great people following him in the development of the framework,
I was looking for an Hastable in javascript, and I found one thanks to Michael Synovic.

I have to say that the original code was buggy (actually I don't remember where exactly),
so I fixed this simple javascript code with my friend Stefano; I have to say that
I have used this Hastable in different projects and finding it very useful, I decided to issue this small class.



/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java Hashtable object,
revisioned by Marco Bellocchi and Stefano Sambi

Contructor(s):
Ext.Hashtable
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/
/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java Hashtable object.

Contructor(s):
Ext.ux.Hashtable()
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/
//Get rid of these 2 line when using with Ext
//******
Ext = {};
Ext.ux = {};
//******
Ext.ux.Hashtable = function()
{
this.clear = hashtable_clear;
this.containsKey = hashtable_containsKey;
this.containsValue = hashtable_containsValue;
this.get = hashtable_get;
this.isEmpty = hashtable_isEmpty;
this.keys = hashtable_keys;
this.put = hashtable_put;
this.remove = hashtable_remove;
this.size = hashtable_size;
this.toString = hashtable_toString;
this.values = hashtable_values;

var items = {};
var count = 0;
// serve per confrontare che non sia una proprieta nativa
var testObject = {};


/*=======Private methods for internal use only========*/

function hashtable_clear(){
items = {};
count = 0;
}

function hashtable_containsKey(key){
if (testObject[key]) {
return false;
}
return (items[key] != null);
}

function hashtable_containsValue(value){
var a = getValueArray();
for (var htIndex = 0; htIndex < a.length; htIndex++) {
if (a[htIndex] == value) {
return true;
}
}
return false;
}

function hashtable_get(key){
if(key in items){
return items[key]; // object
}
return undefined;
}

function hashtable_isEmpty(){
return (count == 0);
}

function hashtable_keys(){
return getKeyArray();
}

function hashtable_put(key, value){
if (key == null || value == null) {
throw "NullPointerException {" + key + "},{" + value + "}";
}else{
var alreadyExists = (key in items);
items[key] = value;
if(!alreadyExists){
count++;
}
}
}

function hashtable_remove(key){
if(key in items && !testObject[key]){
delete items[key];
count--;
return true;
}
return false;
}

function hashtable_size(){
return count;
}

function hashtable_toString(){
var result = '';
var arrKeys = getKeyArray();
for (var i = 0; i < arrKeys.length; i++)
{
if (TI.Util.isNullOrUndefined(items[arrKeys[i]]))
result += "{" + arrKeys[i] + "},{" + items[arrKeys[i]] + "}\n";
}
return result;
}

function hashtable_values(){
return getValueArray();
}

function getValueArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(items[p]);
}
}
return a;
}
function getKeyArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(p);
}
}
return a;
}
}

//TEST
function testHashtableCreation() {
var ht = new Ext.ux.Hashtable();
assertNotNull("the new Hashtable instance is not null", ht);
}
function testClear() {
var ht = new Ext.ux.Hashtable();
ht.put("a", "a");
assertFalse("Hashtable is not empty", ht.isEmpty());
ht.clear();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testContainsKey() {
var ht = new Ext.ux.Hashtable();
assertFalse("Hashtable not contains key 'theKey'", ht.containsKey("theKey"));
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains key 1'theKey'", ht.containsKey("theKey"));
assertTrue("Hashtable contains key 2'theKey'", ht.containsKey(key));
}
function testContainsValue() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsValue({}));
}
function testGet() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key , b);
var obj = ht.get(key);
assertNotNull("the obj is not null", obj);
assertEquals("key and returned key are the same reference", obj, b);
}
function testIsEmpty() {
var ht = new Ext.ux.Hashtable();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testPut() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
}
function testRemove() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
ht.remove(key);
assertFalse("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsKey(key));
}
function testSize() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertEquals("Hashtable size is 1", ht.size(), 1);
}
function testKeys() {
var ht = new Ext.ux.Hashtable();
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayKey = ht.keys();
assertNotNull("the keys are not null", arrayKey);
assertEquals("the keys array contains one element", arrayKey.length, 1);
}

function testValues() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayValue = ht.values();
assertNotNull("the values are not null", arrayValue);
assertEquals("the values array contains one element", arrayValue.length, 1);
}

</script>

Then if someone is curious, I have made some simple test using JSUnit, but you need to download JSUnit to work with it.
Anyway, this is the test page using JSUnit:



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Hashtable</title>
<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
<script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
<script language="javascript">
/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java Hashtable object,
revisioned by Marco Bellocchi and Stefano Sambi

Contructor(s):
Ext.Hashtable
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/
/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java TI.Core.Hashtable object.

Contructor(s):
TI.Core.Hashtable()
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/
Ext = {};
Ext.ux = {};
Ext.ux.Hashtable = function()
{
this.clear = hashtable_clear;
this.containsKey = hashtable_containsKey;
this.containsValue = hashtable_containsValue;
this.get = hashtable_get;
this.isEmpty = hashtable_isEmpty;
this.keys = hashtable_keys;
this.put = hashtable_put;
this.remove = hashtable_remove;
this.size = hashtable_size;
this.toString = hashtable_toString;
this.values = hashtable_values;

var items = {};
var count = 0;
// serve per confrontare che non sia una proprieta nativa
var testObject = {};


/*=======Private methods for internal use only========*/

function hashtable_clear(){
items = {};
count = 0;
}

function hashtable_containsKey(key){
if (testObject[key]) {
return false;
}
return (items[key] != null);
}

function hashtable_containsValue(value){
var a = getValueArray();
for (var htIndex = 0; htIndex < a.length; htIndex++) {
if (a[htIndex] == value) {
return true;
}
}
return false;
}

function hashtable_get(key){
if(key in items){
return items[key]; // object
}
return undefined;
}

function hashtable_isEmpty(){
return (count == 0);
}

function hashtable_keys(){
return getKeyArray();
}

function hashtable_put(key, value){
if (key == null || value == null) {
throw "NullPointerException {" + key + "},{" + value + "}";
}else{
var alreadyExists = (key in items);
items[key] = value;
if(!alreadyExists){
count++;
}
}
}

function hashtable_remove(key){
if(key in items && !testObject[key]){
delete items[key];
count--;
return true;
}
return false;
}

function hashtable_size(){
return count;
}

function hashtable_toString(){
var result = '';
var arrKeys = getKeyArray();
for (var i = 0; i < arrKeys.length; i++)
{
if (TI.Util.isNullOrUndefined(items[arrKeys[i]]))
result += "{" + arrKeys[i] + "},{" + items[arrKeys[i]] + "}\n";
}
return result;
}

function hashtable_values(){
return getValueArray();
}

function getValueArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(items[p]);
}
}
return a;
}
function getKeyArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(p);
}
}
return a;
}
}

//TEST
function testHashtableCreation() {
var ht = new Ext.ux.Hashtable();
assertNotNull("the new Hashtable instance is not null", ht);
}
function testClear() {
var ht = new Ext.ux.Hashtable();
ht.put("a", "a");
assertFalse("Hashtable is not empty", ht.isEmpty());
ht.clear();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testContainsKey() {
var ht = new Ext.ux.Hashtable();
assertFalse("Hashtable not contains key 'theKey'", ht.containsKey("theKey"));
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains key 1'theKey'", ht.containsKey("theKey"));
assertTrue("Hashtable contains key 2'theKey'", ht.containsKey(key));
}
function testContainsValue() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsValue({}));
}
function testGet() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key , b);
var obj = ht.get(key);
assertNotNull("the obj is not null", obj);
assertEquals("key and returned key are the same reference", obj, b);
}
function testIsEmpty() {
var ht = new Ext.ux.Hashtable();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testPut() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
}
function testRemove() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
ht.remove(key);
assertFalse("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsKey(key));
}
function testSize() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertEquals("Hashtable size is 1", ht.size(), 1);
}
function testKeys() {
var ht = new Ext.ux.Hashtable();
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayKey = ht.keys();
assertNotNull("the keys are not null", arrayKey);
assertEquals("the keys array contains one element", arrayKey.length, 1);
}

function testValues() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayValue = ht.values();
assertNotNull("the values are not null", arrayValue);
assertEquals("the values array contains one element", arrayValue.length, 1);
}

</script>

</head>
<body>
<h1>Hastable test</h1>
<p>This page contains tests for the Hashtable.</p>
</body>
</html>


Keep up the great work!!

Marco

MaximGB
20 Feb 2008, 5:29 PM
Did you bench it agains Ext.util.MixedCollection?

mabello
21 Feb 2008, 1:08 AM
Actually not yet, but MixedCollection code seems really better, from a coding point of view :">.
I will get a try anyway...
Thanks!

mabello
21 Feb 2008, 1:42 AM
Hi, this is the page for benchmark, I added 2 test methods.

So I put 200000 elements in the Hashtable and MixedCollection and I retrive one of the inserted element by key



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Hashtable</title>
<link rel="stylesheet" type="text/css" href="../css/jsUnitStyle.css">
<script language="JavaScript" type="text/javascript" src="../app/jsUnitCore.js"></script>
<script language="JavaScript" type="text/javascript" src="ext-base.js"></script>
<script language="JavaScript" type="text/javascript" src="ext-all-debug.js"></script>
<script language="javascript">
/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java Hashtable object,
revisioned by Marco Bellocchi and Stefano Sambi

Contructor(s):
Ext.Hashtable
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/
/**
Created by: Michael Synovic
on: 01/12/2003

This is a Javascript implementation of the Java TI.Core.Hashtable object.

Contructor(s):
TI.Core.Hashtable()
Creates a new, empty hashtable

Method(s):
void clear()
Clears this hashtable so that it contains no keys.
boolean containsKey(String key)
Tests if the specified object is a key in this hashtable.
boolean containsValue(Object value)
Returns true if this TI.Core.Hashtable maps one or more keys to this value.
Object get(String key)
Returns the value to which the specified key is mapped in this hashtable.
boolean isEmpty()
Tests if this hashtable maps no keys to values.
Array keys()
Returns an array of the keys in this hashtable.
void put(String key, Object value)
Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
Object remove(String key)
Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
int size()
Returns the number of keys in this hashtable.
String toString()
Returns a string representation of this TI.Core.Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space).
Array values()
Returns a array view of the values contained in this TI.Core.Hashtable.

*/

Ext.ux.Hashtable = function()
{
this.clear = hashtable_clear;
this.containsKey = hashtable_containsKey;
this.containsValue = hashtable_containsValue;
this.get = hashtable_get;
this.isEmpty = hashtable_isEmpty;
this.keys = hashtable_keys;
this.put = hashtable_put;
this.remove = hashtable_remove;
this.size = hashtable_size;
this.toString = hashtable_toString;
this.values = hashtable_values;

var items = {};
var count = 0;
// serve per confrontare che non sia una proprieta nativa
var testObject = {};


/*=======Private methods for internal use only========*/

function hashtable_clear(){
items = {};
count = 0;
}

function hashtable_containsKey(key){
if (testObject[key]) {
return false;
}
return (items[key] != null);
}

function hashtable_containsValue(value){
var a = getValueArray();
for (var htIndex = 0; htIndex < a.length; htIndex++) {
if (a[htIndex] == value) {
return true;
}
}
return false;
}

function hashtable_get(key){
if(key in items){
return items[key]; // object
}
return undefined;
}

function hashtable_isEmpty(){
return (count == 0);
}

function hashtable_keys(){
return getKeyArray();
}

function hashtable_put(key, value){
if (key == null || value == null) {
throw "NullPointerException {" + key + "},{" + value + "}";
}else{
var alreadyExists = (key in items);
items[key] = value;
if(!alreadyExists){
count++;
}
}
}

function hashtable_remove(key){
if(key in items && !testObject[key]){
delete items[key];
count--;
return true;
}
return false;
}

function hashtable_size(){
return count;
}

function hashtable_toString(){
var result = '';
var arrKeys = getKeyArray();
for (var i = 0; i < arrKeys.length; i++)
{
if (TI.Util.isNullOrUndefined(items[arrKeys[i]]))
result += "{" + arrKeys[i] + "},{" + items[arrKeys[i]] + "}\n";
}
return result;
}

function hashtable_values(){
return getValueArray();
}

function getValueArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(items[p]);
}
}
return a;
}
function getKeyArray() {
var a = [];
for(var p in items){
if(!testObject[p]){
a.push(p);
}
}
return a;
}
}

//TEST
function testHashtableCreation() {
var ht = new Ext.ux.Hashtable();
assertNotNull("the new Hashtable instance is not null", ht);
}
function testClear() {
var ht = new Ext.ux.Hashtable();
ht.put("a", "a");
assertFalse("Hashtable is not empty", ht.isEmpty());
ht.clear();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testContainsKey() {
var ht = new Ext.ux.Hashtable();
assertFalse("Hashtable not contains key 'theKey'", ht.containsKey("theKey"));
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains key 1'theKey'", ht.containsKey("theKey"));
assertTrue("Hashtable contains key 2'theKey'", ht.containsKey(key));
}
function testContainsValue() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsValue({}));
}
function testGet() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key , b);
var obj = ht.get(key);
assertNotNull("the obj is not null", obj);
assertEquals("key and returned key are the same reference", obj, b);
}
function testIsEmpty() {
var ht = new Ext.ux.Hashtable();
assertTrue("Hashtable is empty", ht.isEmpty());
}
function testPut() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
}
function testRemove() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertTrue("Hashtable contains value b", ht.containsValue(b));
assertTrue("Hashtable contains value b", ht.containsKey(key));
ht.remove(key);
assertFalse("Hashtable contains value b", ht.containsValue(b));
assertFalse("Hashtable contains value b", ht.containsKey(key));
}
function testSize() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
assertEquals("Hashtable size is 1", ht.size(), 1);
}
function testKeys() {
var ht = new Ext.ux.Hashtable();
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayKey = ht.keys();
assertNotNull("the keys are not null", arrayKey);
assertEquals("the keys array contains one element", arrayKey.length, 1);
}

function testValues() {
var ht = new Ext.ux.Hashtable();
var key = "theKey";
var b = {};
ht.put(key, b);
var arrayValue = ht.values();
assertNotNull("the values are not null", arrayValue);
assertEquals("the values array contains one element", arrayValue.length, 1);
}

function testBenchmark(){
var started = new Date();
var ht = new Ext.ux.Hashtable();
for(var i = 0; i < 200000; i++) {
ht.put(i, i);
}
var finded = ht.get(100);
assertNotNull("the value is not null", finded);
var end = new Date();
inform("Hashtable, Test duration in milliseconds, inserted 200000 elements", end - started);
}

function testBenchmarkExtMixedCollection(){
var started = new Date();
var mixedCollection = new Ext.util.MixedCollection();
for(var i = 0; i < 200000; i++) {
mixedCollection.add(i, i);
}
var finded = mixedCollection.item(100);
assertNotNull("the value is not null", finded);
var end = new Date();
inform("MixedCollection, Test duration in milliseconds, inserted 200000 elements", end - started);
}
</script>

</head>
<body>
<h1>Hastable test</h1>
<p>This page contains tests for the Hashtable.</p>
</body>
</html>


Results in FF 2.0.0.12 are the following:

MixedCollection, Test duration in milliseconds, inserted 200000 elements: 3703

Hashtable, Test duration in milliseconds, inserted 200000 elements: 515

In IE6:

Hashtable, Test duration in milliseconds, inserted 200000 elements: 3656

MixedCollection, Test duration in milliseconds, inserted 200000 elements: 37937

Wow IE6 is so fast!!!!!

I'm using a Pentiun 4 HT 3,6 GHz, 3.00 GB of RAM

mabello
21 Feb 2008, 2:57 PM
I have a small example in which I had to use the Hastable.
The game is to find 3 integer numbers, each of them > 0, lets say a, b, c so that:

a*b*c = 72;

Besides, you need to find only the unique permutations, I mean
(1,2,36) is the same of
(2,1,36) and
(36,1,2)

Check this out:


var a = 1;
var b = 1;
var c = 1;
var ht = new Ext.ux.Hashtable();

var result =[];
for(var i = 1; i < 73; i++)
for(var j = 1; j <73; j++)
for(var k = 1; k < 73; k++){
var res = i*j*k;
if(res == 72){
var res = [];
res.push(''+i+j+k);
res.push(''+i+k+j);
res.push(''+j+i+k);
res.push(''+j+k+i);
res.push(''+k+i+j);
res.push(''+k+j+i);
var toAdd = true;

for(var t = 0; t < res.length; t++)
if(ht.containsKey(res[t])){
toAdd = false;
}
if(toAdd)
ht.put(''+i+j+k, "Finded "+i+" "+j+" "+k+" ")
}
}
console.log(ht.toString());
//alert(ht.toString());

console.log("") work only with firefox with Firebug, you need to use alert instead for IE

Results:


{1172},{Finded 1 1 72 }
{1236},{Finded 1 2 36 }
{1324},{Finded 1 3 24 }
{1418},{Finded 1 4 18 }
{1612},{Finded 1 6 12 }
{189},{Finded 1 8 9 }
{2218},{Finded 2 2 18 }
{2312},{Finded 2 3 12 }
{249},{Finded 2 4 9 }
{266},{Finded 2 6 6 }
{338},{Finded 3 3 8 }
{346},{Finded 3 4 6 }

DigitalSkyline
21 Feb 2008, 7:42 PM
MixedCollection, Test duration in milliseconds, inserted 200000 elements: 37937

~38 seconds? impressive! :|

In any case, good luck with the competing ideas...

dantheman
22 Feb 2008, 9:57 AM
I wonder how much better Ext's MixedCollection would fare,
if, like HashTable, it didn't fire events when loading the data ... /:)

--dan

pjeutr
26 Mar 2009, 2:54 AM
Sorry for bumping this up.
But I really miss hash/hashtable kind of functionality in java
In ruby I use keys/values/join a lot, to pass data/config around.

I'm new to ext, so maybe I'm missing something.
But a lightweight alternative (without events) to Ext.util.MixedCollection with keys/values/join would be handy to have in Ext.util?

thanks mabello!

mschwartz
26 Mar 2009, 7:33 AM
I don't get it.

var hashtable = {};

All but a couple of the functionalities are built into the language - except containsValue() and toString().

It seems to me that adding a couple of prototypes to Object would suffice.

Also, I think the code in post 1 (hashtable_remove function) leaks memory if you remove items and never call the clear() function.

https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator



Deleting array elements

When you delete an array element, the array length is not affected. For example, if you delete a[3], a[4] is still a[4] and a[3] is undefined. This holds even if you delete the last element of the array (delete a[a.length-1]).

mschwartz
26 Mar 2009, 7:40 AM
var a = 1;
var b = 1;
var c = 1;
var ht = {};

var result =[];
for(var i = 1; i < 73; i++)
for(var j = 1; j <73; j++)
for(var k = 1; k < 73; k++){
var res = i*j*k;
if(res == 72){
var res = [];
res.push(''+i+j+k);
res.push(''+i+k+j);
res.push(''+j+i+k);
res.push(''+j+k+i);
res.push(''+k+i+j);
res.push(''+k+j+i);
var toAdd = true;

for(var t = 0; t < res.length; t++)
if(ht[res[t]] !== undefined){
toAdd = false;
}
if(toAdd)
ht[''+i+j+k] = "Finded "+i+" "+j+" "+k+" "
}
}
console.log(Ext.encode(ht));

//alert(ht.toString());

mabello
26 Mar 2009, 9:05 AM
@mschwartz

I won't add anything (or close to anything) to the prototype of Object; it should be avoided to add properties and methods to the prorotype of the built in javascript types as much as you can since it could bring to incompatibilities between different javascript libraries.

This class has the responsability to keep an internal status, like the number of elements (count variable), it checks preconditions, and it's a nice way of encapsulating the hastable functionalities in one class...do you really want to add all this type of things to the the prototype of the object? I wouldn't recommend it, just my opinion of course :)

About the leaking of remove, thanks for pointing out that, definitely the remove should be implemented using slice, the same way Ext iuses it:



remove : function(o){
var index = this.indexOf(o);
if(index != -1){
this.splice(index, 1);
}
return this;
}


Cheers

mschwartz
26 Mar 2009, 1:10 PM
try this:



var hashtable = {
a: 1,
b: 2,
c: 3
};

alert(hashtable.length);


It keeps track of how many items for you already...

/:)

You saw I eliminated use of your Hashtable class in your own code. It surely runs faster my way.

:D

pjeutr
8 Apr 2009, 12:22 PM
Just to make it complete, MixedCollection has keys/values properties, I saw in firebug.
Sorry for my ignorance, but to my defense it's not in the api docs (http://extjs.com/deploy/dev/docs/).
Talking about those, it would be great if the links to the js files would work http://extjs.com/deploy/dev/src/MixedCollection.js

hash = new Ext.util.MixedCollection();
hash.add('key1', 'value1');
hash.add('key2', 'value2');
alert("keys=" + hash.keys + " values=" + hash.items);
hash.eachKey(function(key, value) {alert(key +"="+ value)});