Skip to content

Commit 3725408

Browse files
committed
Improve function caching
1 parent 9c5d802 commit 3725408

File tree

8 files changed

+67
-125
lines changed

8 files changed

+67
-125
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.snapscript.common;
2+
3+
public class CopyOnWriteSparseArray<T> extends SparseArray<T> {
4+
5+
public CopyOnWriteSparseArray(int length) {
6+
super(length);
7+
}
8+
9+
public CopyOnWriteSparseArray(int length, int block) {
10+
super(length, block);
11+
}
12+
13+
@Override
14+
protected synchronized Object[] segment(int index) {
15+
return super.segment(index);
16+
}
17+
}

snap-common/src/test/java/org/snapscript/common/SparseArrayTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ public void testSparseArray(){
1717
}
1818
}
1919

20+
public void testSparseArrayGrowth() {
21+
SparseArray sparseArray = new SparseArray(VALUES);
22+
for(int i = 0; i <100; i++) {
23+
int step = i*100;
24+
sparseArray.set(VALUES +step, String.valueOf(i));
25+
}
26+
for(int i = 0; i <100; i++) {
27+
int step = i*100;
28+
assertEquals(sparseArray.get(VALUES +step), String.valueOf(i));
29+
}
30+
}
31+
2032
private static void compareWithBlock(int block){
2133
SparseArray sparseArray = new SparseArray(VALUES, block);
2234
Map hashMap = new HashMap(VALUES);

snap-core/src/main/java/org/snapscript/core/TypeCache.java

Lines changed: 10 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,21 @@
22

33
import org.snapscript.common.Cache;
44
import org.snapscript.common.CopyOnWriteCache;
5+
import org.snapscript.common.CopyOnWriteSparseArray;
6+
import org.snapscript.common.SparseArray;
57

68
public class TypeCache<V> {
79

8-
private volatile TypeCacheArray<V> array;
9-
private volatile Cache<Type, V> cache;
10-
private volatile CacheUpdater updater;
10+
private final SparseArray<V> array;
11+
private final Cache<Type, V> cache;
1112

1213
public TypeCache() {
1314
this(1000);
1415
}
1516

1617
public TypeCache(int capacity) {
17-
this(capacity, 1000);
18-
}
19-
20-
public TypeCache(int capacity, int expand) {
21-
this.array = new TypeCacheArray<V>(capacity, expand);
22-
this.cache = new CopyOnWriteCache<Type, V>();
23-
this.updater = new CacheUpdater(capacity);
18+
this.array = new CopyOnWriteSparseArray<V>(capacity); // for order > 0
19+
this.cache = new CopyOnWriteCache<Type, V>(); // for order = 0
2420
}
2521

2622
public V take(Type type) {
@@ -29,12 +25,7 @@ public V take(Type type) {
2925
if(order == 0) {
3026
return cache.take(type);
3127
}
32-
int length = array.length();
33-
34-
if(length > order) {
35-
return updater.take(order);
36-
}
37-
return null;
28+
return array.remove(order);
3829
}
3930

4031
public V fetch(Type type) {
@@ -43,12 +34,7 @@ public V fetch(Type type) {
4334
if(order == 0) {
4435
return cache.fetch(type);
4536
}
46-
int length = array.length();
47-
48-
if(length > order) {
49-
return array.get(order);
50-
}
51-
return null;
37+
return array.get(order);
5238
}
5339

5440
public boolean contains(Type type) {
@@ -57,12 +43,7 @@ public boolean contains(Type type) {
5743
if(order == 0) {
5844
return cache.contains(type);
5945
}
60-
int length = array.length();
61-
62-
if(length > order) {
63-
return array.get(order) != null;
64-
}
65-
return false;
46+
return array.get(order) != null;
6647
}
6748

6849
public void cache(Type type, V value) {
@@ -71,41 +52,6 @@ public void cache(Type type, V value) {
7152
if(order == 0) {
7253
cache.cache(type, value);
7354
}
74-
int length = array.length();
75-
76-
if(length > order) {
77-
array.set(order, value);
78-
} else {
79-
updater.cache(order, value);
80-
}
81-
}
82-
83-
private class CacheUpdater {
84-
85-
private final int expand;
86-
87-
public CacheUpdater(int expand) {
88-
this.expand = expand;
89-
}
90-
91-
public synchronized void cache(int order, V value) {
92-
int length = array.length();
93-
94-
if(order >= length) {
95-
TypeCacheArray<V> copy = array.copy(order + expand);
96-
97-
copy.set(order, value);
98-
array = copy;
99-
}
100-
}
101-
102-
public synchronized V take(int order) {
103-
int length = array.length();
104-
105-
if(length > order) {
106-
return array.set(order, null);
107-
}
108-
return null;
109-
}
55+
array.set(order, value);
11056
}
11157
}

snap-core/src/main/java/org/snapscript/core/TypeCacheArray.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

snap-core/src/main/java/org/snapscript/core/bind/FunctionKey.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.snapscript.core.bind;
22

3+
import org.snapscript.core.Type;
4+
35
public class FunctionKey {
46

5-
private final Object[] types;
6-
private final String function;
7+
private Type[] types;
8+
private String function;
9+
private int hash;
710

8-
public FunctionKey(String function, Object[] types) {
11+
public FunctionKey(String function, Type[] types) {
912
this.function = function;
1013
this.types = types;
1114
}
@@ -32,10 +35,19 @@ public boolean equals(FunctionKey key) {
3235

3336
@Override
3437
public int hashCode() {
35-
int hash = function.hashCode();
36-
37-
hash = hash *31 + types.length;
38-
38+
if(hash == 0) {
39+
int value = function.hashCode();
40+
41+
for(Type type : types) {
42+
int order = 1;
43+
44+
if(type != null) {
45+
order = type.getOrder();
46+
}
47+
value = value *31 + order;
48+
}
49+
hash = value;
50+
}
3951
return hash;
4052
}
4153
}

snap-core/src/main/java/org/snapscript/core/bind/FunctionKeyBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.snapscript.core.bind;
22

3+
import org.snapscript.core.Type;
34
import org.snapscript.core.TypeExtractor;
45

56
public class FunctionKeyBuilder {
@@ -12,7 +13,7 @@ public FunctionKeyBuilder(TypeExtractor extractor) {
1213

1314
public Object create(String function, Object... list) throws Exception {
1415
if(list.length > 0) {
15-
Object[] types = new Object[list.length];
16+
Type[] types = new Type[list.length];
1617

1718
for(int i = 0; i < list.length; i++) {
1819
Object value = list[i];

snap-tree/src/main/java/org/snapscript/tree/Modifier.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55

66
public class Modifier {
77

8-
private final StringToken token;
9-
8+
private ModifierType type;
9+
private StringToken token;
10+
1011
public Modifier(StringToken token) {
1112
this.token = token;
1213
}
1314

1415
public ModifierType getType() {
1516
String name = token.getValue();
1617

17-
if(name != null) {
18-
return ModifierType.resolveModifier(name);
18+
if(type == null) {
19+
type = ModifierType.resolveModifier(name);
1920
}
20-
return null;
21-
}
21+
return type;
22+
}
2223

2324
}

snap-tree/src/main/java/org/snapscript/tree/define/TraitConstant.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ public Initializer compile(Initializer initializer, Type type) throws Exception
5555
String name = value.getString();
5656

5757
if(!checker.isConstant()) {
58-
throw new InternalStateException("Variable '" + name + "' for '" + type + "; must be constant");
5958
}
6059
Accessor accessor = new StaticAccessor(initializer, scope, type, name);
6160
Property property = new AccessorProperty(name, type, constraint, accessor, ModifierType.STATIC.mask | ModifierType.CONSTANT.mask);

0 commit comments

Comments
 (0)