Revision: 3358
          http://vexi.svn.sourceforge.net/vexi/?rev=3358&view=rev
Author:   clrg
Date:     2009-01-14 21:19:18 +0000 (Wed, 14 Jan 2009)

Log Message:
-----------
More efficiency work for arrays and hashmaps
- Use arraycopy for splice/slice in JSArray
- Reduce Hash to little more than a HashMap (removes indirection, saves memory)

Modified Paths:
--------------
    trunk/core/org.ibex.js/src/org/ibex/js/JSArray.jpp
    trunk/core/org.ibex.js/src/org/ibex/js/JSArrayLike.java
    trunk/core/org.ibex.js/src_junit/test/js/exec/array/testsplice.js
    trunk/core/org.ibex.util/src/org/ibex/util/Basket.java
    trunk/core/org.ibex.util/src/org/ibex/util/Cache.java

Modified: trunk/core/org.ibex.js/src/org/ibex/js/JSArray.jpp
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/JSArray.jpp  2009-01-14 02:44:57 UTC 
(rev 3357)
+++ trunk/core/org.ibex.js/src/org/ibex/js/JSArray.jpp  2009-01-14 21:19:18 UTC 
(rev 3358)
@@ -6,7 +6,7 @@
 
 import org.ibex.util.*; 
 
-/** A JavaScript JSArray */
+/** A JavaScript array implementation */
 public class JSArray extends Basket.Array implements Basket.CompareFunc, 
Constants, JSArrayLike {
 
     public JSArray() { }
@@ -14,7 +14,7 @@
     public JSArray(JS[] args) { super(args.length); addAll(args); }
     public JSArray(JS arg) { super(1); add(arg); }
 
-    public JS type(){ return SC_array; }
+    public JS type() { return SC_array; }
     public JS unclone() { return this; }
     public JS.Keys keys() throws JSExn { return new JSArrayLike.Keys(this); }
     
@@ -45,20 +45,19 @@
         } catch (IndexOutOfBoundsException e) { return null; }
     }
     public void put(JS key, JS val) throws JSExn {
-        if (JSU.toString(key).equals("length")) { setSize(JSU.toInt(val)); }
+        if (JSU.toString(key).equals("length")) { size(JSU.toInt(val)); }
 
-        if (key == null || !(JSU.isInt(key)))//
+        if (key == null || !(JSU.isInt(key)))
             throw new JSExn("Arrays only support positive integer keys, can 
not use: "+JSU.toString(key));
         int i = JSU.toInt(key);
         if (i < 0) throw new JSExn("Attempt to put to negative key '"+i+" on 
an array");
         if (size() < i+1) size(i + 1);
-        //while (size() < i) add(null);
         set(i, val);
     }
 
     public String[] getFormalArgs() { return EMPTY_STRING_ARRAY; }
     public int callType(){ return CALLTYPE_METHOD; }
-    public String coerceToString(){ return "array$" + 
Integer.toHexString(hashCode());}
+    public String coerceToString() { return "array$" + 
Integer.toHexString(hashCode()); }
 
     public JS call(JS method, JS[] args) throws JSExn {
         //#switch(JSU.toString(method))
@@ -93,70 +92,63 @@
     /** FEATURE: move to specialised ArrayStore superclass. */
     public void addAll(JS[] entries) { for (int i=0; i < entries.length; i++) 
add(entries[i]); }
 
-    public void setSize(int newSize) {
-        size(newSize);
-        for (int i=size(); i < newSize; i++) add(null);
-        for (int i=size() - 1; i >= newSize; i--) remove(i);
-    }
 
-
     // ECMA Implementation ////////////////////////////////////////////////////
 
+    /** joins tegether array contents into a string */
     private JS join(String sep) throws JSExn {
         int length = size();
-        if(length == 0) return SC_;
+        if (length == 0) return SC_;
         StringBuffer sb = new StringBuffer(64);
         int i=0;
-        while(true) {
+        while (true) {
             JS o = (JS)get(i);
-            if(o != null) sb.append(JSU.toString(o));
-            if(++i == length) break;
+            if (o != null) sb.append(JSU.toString(o));
+            if (++i == length) break;
             sb.append(sep);
         }
         return JSU.S(sb.toString());
     }
- 
+
+    /** create a copy of an array between indice start and end */
     private JS slice(int start, int end) {
         int length = size();
-        if(start < 0) start = length+start;
-        if(end < 0) end = length+end;
-        if(start < 0) start = 0;
-        if(end < 0) end = 0;
-        if(start > length) start = length;
-        if(end > length) end = length;
-        JSArray a = new JSArray(end-start);
-        for(int i=0;i<end-start;i++) // FEATURE: with ArrayStore do 
System.arraycopy()
-            a.set(i, get(start+i));
-        return a;
+        if (start < 0) start = length+start;
+        if (end < 0) end = length+end;
+        if (start < 0) start = 0;
+        if (end < 0) end = 0;
+        if (start > length) start = length;
+        if (end > length) end = length;
+        JSArray ret = new JSArray(end-start);
+        Array.arraycopy(this, start, ret, 0, end-start);
+        return ret;
     }
 
+    /** remove and return the portion of an array between the specified indice 
*/
     private JS splice(JS[] args) throws JSExn {
         int oldLength = size();
         int start = JSU.toInt(args.length < 1 ? null : args[0]);
         int deleteCount = JSU.toInt(args.length < 2 ? null : args[1]);
         int newCount = args.length - 2;
-        if(newCount < 0) newCount = 0;
-        if(start < 0) start = oldLength+start;
-        if(start < 0) start = 0;
-        if(start > oldLength) start = oldLength;
-        if(deleteCount < 0) deleteCount = 0;
-        if(deleteCount > oldLength-start) deleteCount = oldLength-start;
+        if (newCount < 0) newCount = 0;
+        if (start < 0) start = oldLength+start;
+        if (start < 0) start = 0;
+        if (start > oldLength) start = oldLength;
+        if (deleteCount < 0) deleteCount = 0;
+        if (deleteCount > oldLength-start) deleteCount = oldLength-start;
         int newLength = oldLength - deleteCount + newCount;
-        int lengthChange = newLength - oldLength;
         JSArray ret = new JSArray(deleteCount);
-        for(int i=0;i<deleteCount;i++) // FEATURE: ArrayStore 
System.arraycopy()
-            ret.set(i, get(start+i));
-        if(lengthChange > 0) {
-            setSize(newLength);
-            for(int i=newLength-1;i>=start+newCount;i--)
-                set(i, get(i-lengthChange));
-        } else if(lengthChange < 0) {
-            for(int i=start+newCount;i<newLength;i++)
-                set(i, get(i-lengthChange));
-            setSize(newLength);
-        }
-        for(int i=0;i<newCount;i++)
-            set(start+i, args[i+2]);
+        ret.size(deleteCount);
+        // first copy the specified indice into the return array
+        Array.arraycopy(this, start, ret, 0, deleteCount);
+        // if array grows, must grow it before shuffling remaining contents
+        if (newLength > oldLength) size(newLength);
+        // copy the remaining array contents to new position
+        Array.arraycopy(this, start+deleteCount, this, start+newCount, 
oldLength-deleteCount-start);
+        // copy in the additionally specified elements required
+        if (newCount > 0) Array.arraycopy(new Array(args, 2, args.length-2), 
0, this, start, newCount);
+        // hide remaining contents
+        if (oldLength > newLength) size(newLength);
         return ret;
     }
 

Modified: trunk/core/org.ibex.js/src/org/ibex/js/JSArrayLike.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/JSArrayLike.java     2009-01-14 
02:44:57 UTC (rev 3357)
+++ trunk/core/org.ibex.js/src/org/ibex/js/JSArrayLike.java     2009-01-14 
21:19:18 UTC (rev 3358)
@@ -1,11 +1,11 @@
 package org.ibex.js;
 
-public interface JSArrayLike extends JS{
+public interface JSArrayLike extends JS {
        public JS[] toArray() throws JSExn;
        public int length() throws JSExn;
-    static public class Keys extends JS.Keys{
+    static public class Keys extends JS.Keys {
        JSArrayLike keysof;
-       public Keys(JSArrayLike obj){
+       public Keys(JSArrayLike obj) {
                super(obj);
                this.keysof = obj;
        }
@@ -19,6 +19,6 @@
                        public JS _next() { return JSU.N(n++); }
                    };
                }
-               protected JS size() throws JSExn {return 
JSU.N(keysof.length());}
+               protected JS size() throws JSExn { return 
JSU.N(keysof.length()); }
     }
 }

Modified: trunk/core/org.ibex.js/src_junit/test/js/exec/array/testsplice.js
===================================================================
--- trunk/core/org.ibex.js/src_junit/test/js/exec/array/testsplice.js   
2009-01-14 02:44:57 UTC (rev 3357)
+++ trunk/core/org.ibex.js/src_junit/test/js/exec/array/testsplice.js   
2009-01-14 21:19:18 UTC (rev 3358)
@@ -1,8 +1,11 @@
 
 var x = ["a","b","c","x","y","z"];
 var y = x.splice(2,2);
+assert(x.length==4);
+assert(y.length==2);
 assert(x.join(",")=="a,b,y,z");
-assert(y.join(","),"a,b,y,z");
+assert(y.join(",")=="c,x");
 var z = x.splice(2,0,"m","n");
 assert(z.length==0);
+assert(x.length==6);
 assert(x.join(","),"a,b,m,n,y,z");

Modified: trunk/core/org.ibex.util/src/org/ibex/util/Basket.java
===================================================================
--- trunk/core/org.ibex.util/src/org/ibex/util/Basket.java      2009-01-14 
02:44:57 UTC (rev 3357)
+++ trunk/core/org.ibex.util/src/org/ibex/util/Basket.java      2009-01-14 
21:19:18 UTC (rev 3358)
@@ -11,7 +11,7 @@
     public boolean containsValue(Object object);
     public void clear();
     public int size();
-    public void remove(Object object);
+    public Object remove(Object object);
 
     public interface List extends Basket {
         public void add(Object object);
@@ -59,8 +59,12 @@
         public Array() { this(10); }
         public Array(int initialCapacity) { o = new Object[initialCapacity]; }
         public Array(Object entry) { this(1); add(entry); }
+        public Array(Object[] src, int start, int num) {
+            this(num);
+            System.arraycopy(src, start, o, 0, num);
+        }
 
-        public void   enqueue(Object o) { add(o); }
+        public void enqueue(Object o) { add(o); }
 
         // FEATURE: make this more efficient with general wraparound
         public Object dequeue() {
@@ -70,16 +74,16 @@
 
         public void add(Object obj) { add(size, obj); }
         public void add(int i, Object obj) {
-            size(size + 1);
-            if (size - 1 > i) System.arraycopy(o, i, o, i + 1, size - i);
-            o[i] = obj; size++;
+            size(size+1);
+            if (size-1 > i) System.arraycopy(o, i, o, i+1, size-i);
+            o[i] = obj;
         }
         public Object set(int i, Object obj) {
             if (i >= o.length) throw new IndexOutOfBoundsException(
                 "index "+i+" is beyond list boundary "+size);
             Object old = o[i]; o[i] = obj;
-           size = Math.max(i+1, size);
-           return old;
+            size = Math.max(i+1, size);
+            return old;
         }
         public Object get(int i) {
             if (i >= size) throw new IndexOutOfBoundsException(
@@ -89,11 +93,13 @@
         public Object remove(int i) {
             if (i >= size || i < 0) throw new IndexOutOfBoundsException(
                 "index "+i+" is beyond list boundary "+size);
-            Object old = o[i]; o[i] = null;
-            if (size - 1 > i) System.arraycopy(o, i + 1, o, i, size - i - 1);
-            size--; return old;
+            Object old = o[i];
+            o[i] = null;
+            if (size-1 > i) System.arraycopy(o, i+1, o, i, size-i-1);
+            size--;
+            return old;
         }
-        public void remove(Object obj) { remove(indexOf(obj)); }
+        public Object remove(Object obj) { return remove(indexOf(obj)); }
 
         public int indexOf(Object obj) {
             for (int i=0; i < size; i++)
@@ -109,35 +115,43 @@
         public void clear() { for (int i=0; i < size; i++) o[i] = null; size = 
0; }
         public int size() { return size; }
         public void size(int s) {
-            if (o.length >= s) return;
+            if (o.length >= s) {
+                // housekeeping
+                if (size > s) java.util.Arrays.fill(o, s, size-1, null);
+                size = s;
+                return;
+            }
             Object[] newo = new Object[s];
             System.arraycopy(o, 0, newo, 0, size);
             o = newo;
+            size = s;
         }
 
         public void reverse() {
             Object tmp;
-            if(size==1) return;
+            if (size==1) return;
             int last = size - 1;
-            for (int i=0; i < (size/2); i++) { 
-               tmp = o[i]; 
-               o[i] = o[last - i]; 
-               o[last - i] = tmp; }
+            int half = (size/2);
+            for (int i=0; i < half; i++) { 
+                tmp = o[i]; 
+                o[i] = o[last - i]; 
+                o[last - i] = tmp;
+            }
         }
 
         public void sort(CompareFunc c) { sort(this, null, c, 0, size-1); }
 
         public static void sort(Array a, Array b, CompareFunc c, int start, 
int end) {
             Object tmpa, tmpb = null;
-            if(start >= end) return;
+            if (start >= end) return;
             //if(end-start==1)return;
-            if(end-start <= 6) {
-                for(int i=start+1;i<=end;i++) {
+            if (end-start <= 6) {
+                for (int i=start+1; i<=end; i++) {
                     tmpa = a.o[i];
                     if (b != null) tmpb = b.o[i];
                     int j;
-                    for(j=i-1;j>=start;j--) {
-                        if(c.compare(a.o[j],tmpa) <= 0) break;
+                    for (j=i-1; j>=start; j--) {
+                        if (c.compare(a.o[j],tmpa) <= 0) break;
                         a.o[j+1] = a.o[j];
                         if (b != null) b.o[j+1] = b.o[j];
                     }
@@ -150,8 +164,8 @@
             int lo = start - 1;
             int hi = end;
             do {
-                while(c.compare(a.o[++lo],pivot) < 0) { }
-                while((hi > lo) && c.compare(a.o[--hi],pivot) > 0) { }
+                while (c.compare(a.o[++lo],pivot) < 0) { }
+                while ((hi > lo) && c.compare(a.o[--hi],pivot) > 0) { }
                 swap(a, lo,hi);
                 if (b != null) swap(b, lo,hi);
             } while(lo < hi);
@@ -161,9 +175,14 @@
             sort(a, b, c, start, lo-1);
             sort(a, b, c, lo+1, end);
         }
+        
+        /** proxy for System.arraycopy */
+        public static void arraycopy(Array src, int srcPos, Array dest, int 
destPos, int length) {
+            System.arraycopy(src.o, srcPos, dest.o, destPos, length);
+        }
 
         private static final void swap(Array vec, int a, int b) {
-            if(a != b) {
+            if (a != b) {
                 Object tmp = vec.o[a];
                 vec.o[a] = vec.o[b];
                 vec.o[b] = tmp;
@@ -184,45 +203,39 @@
      * 
      * @author Charles Goodwin <char...@webenableit.co.uk>
      */
-    public class Hash implements Basket, Map {
-        private int indexMultiple;
-        private int initialCapacity;
-        private float loadFactor;
-        public HashMap[] maps;
+    public class HashInternal implements Basket, Map {
+        private static final int initialCapacity = 16;
+        private static final float loadFactor = 0.75f;
+        public HashMap map;
         
-        public Hash() { this(16, 0.75F); }
-        public Hash(int initialCapacity, float loadFactor) { this(1, 16, 
0.75F); }
-        public Hash(int indexMultiple, int initialCapacity, float loadFactor) {
-            this.indexMultiple = indexMultiple;
-            this.initialCapacity = initialCapacity;
-            this.loadFactor = loadFactor;
-            clear();
-        }
+        public HashInternal() { clear(); }
+        public HashInternal(int initialCapacity, float loadFactor) { clear(); }
+        public HashInternal(int indexMultiple, int initialCapacity, float 
loadFactor) { clear(); }
         
-        public void clear() {
-            maps = new HashMap[indexMultiple];
-            for (int i=0; indexMultiple>i; i++)
-                maps[i] = new HashMap(initialCapacity, loadFactor);
-        }
-        public boolean containsKey(Object key) {
-            for(int i=0; indexMultiple>i; i++)
-                if (maps[i].containsKey(key)) return true;
-            return false;
-        }
-        public boolean containsValue(Object value) {
-            for(int i=0; indexMultiple>i; i++)
-                if (maps[i].containsValue(value)) return true;
-            return false;
-        }
-        public Object[] dumpkeys() { return maps[0].keySet().toArray(); }
-        public Object get(Object key) { return get(key, 0); }
-        public Object get(Object key, int whichval) { return 
maps[whichval].get(key); }
-        public Object put(Object key, Object val) { return put(key, val, 0); }
-        public Object put(Object key, Object val, int whichval) { 
maps[whichval].put(key, val); return null; }
-        public void remove(Object key) { for(int i=0; indexMultiple>i; i++) 
maps[i].remove(key); }
-        public void remove(Object key, int i) { maps[0].remove(key);}
-        public int size() { return maps[0].size(); }
+        public void clear() { map = new HashMap(initialCapacity, loadFactor); }
+        public boolean containsKey(Object key) { return map.containsKey(key); }
+        public boolean containsValue(Object value) { return 
map.containsValue(value); }
+        public Object[] dumpkeys() { return map.keySet().toArray(); }
+        public Object get(Object key) { return map.get(key); }
+        public Object put(Object key, Object val) { return map.put(key, val); }
+        public Object remove(Object key) { return map.remove(key); }
+        public void remove(Object key, int i) { map.remove(key);}
+        public int size() { return map.size(); }
     }
+    
+    /** Utterly minimalistic implementation directly extending HashMap
+     * 
+     * @author Charles Goodwin <char...@webenableit.co.uk>
+     */
+    public class Hash extends HashMap implements Basket, Map {
+        public Hash() { super(); }
+        public Hash(int initialCapacity) { super(initialCapacity); }
+        //public Hash(int initialCapacity, float loadFactor) { 
super(initialCapacity, loadFactor); }
+        //public Hash(int indexMultiple, int initialCapacity, float 
loadFactor) {
+        //    super(initialCapacity, loadFactor);
+        //}
+        public Object[] dumpkeys() { return keySet().toArray(); }
+    }
 
     /** Implementation of a hash table using Radke's quadratic residue
      *  linear probing. Uses a single array to store all entries.

Modified: trunk/core/org.ibex.util/src/org/ibex/util/Cache.java
===================================================================
--- trunk/core/org.ibex.util/src/org/ibex/util/Cache.java       2009-01-14 
02:44:57 UTC (rev 3357)
+++ trunk/core/org.ibex.util/src/org/ibex/util/Cache.java       2009-01-14 
21:19:18 UTC (rev 3358)
@@ -11,10 +11,11 @@
  *  @author craws...@ibex.org
  */
 public class Cache extends Basket.Hash {
-    public Cache(int maxSize){//, boolean accessOrder) {
+    public Cache(int maxSize) { super(maxSize * 2); }
+    /*
+    public Cache(int maxSize, boolean accessOrder) {
         super(maxSize * 2, 0.75F);
     }
-    /*
     private static final long serialVersionUID = 23498092L;
 
     private final int maxSize;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to