-
Bug
-
Resolution: Fixed
-
P2
-
1.0.2
-
1.1
-
generic
-
solaris_2.4
-
Not verified
[prasadw, pavani 960514 - later on that night :) ]
The problem was in the following statement in hasMoreElements:
while (--index >= 0 && (entry = table[index]) != null) ;
The "!= null" should be "== null" since the objective is to skip over the null
elements.
[prasadw, pavani 960514]
Here is a test program:
$ more T.java
import java.util.*;
import sun.misc.Cache;
class T {
public static void main(String argv[]) {
Cache numbers = new Cache();
Enumeration enumElements;
Enumeration enumKeys;
Object object;
numbers.put("one", new Integer(1));
numbers.put("two", new Integer(1));
numbers.put("three", new Integer(1));
System.out.println("size = " + numbers.size());
enumElements = numbers.elements();
System.out.println("enumElements.hasMoreElements() = " +
enumElements.hasMoreElements());
enumKeys = numbers.keys();
System.out.println("enumKeys.hasMoreElements() = " +
enumKeys.hasMoreElements());
}
}
$ javac T.java
$ java T
size = 3
enumElements.hasMoreElements() = false
enumKeys.hasMoreElements() = false
The problem is that when the hasMoreElements function in CacheEnumerator
is entered entry is not initialized.
/**
* A Cache enumerator class. This class should remain opaque
* to the client. It will use the Enumeration interface.
*/
class CacheEnumerator implements Enumeration {
boolean keys;
int index;
CacheEntry table[];
CacheEntry entry;
CacheEnumerator (CacheEntry table[], boolean keys) {
this.table = table;
this.keys = keys;
this.index = table.length;
}
public boolean hasMoreElements() {
while (index >= 0) {
while (entry != null)
if (entry.check() != null)
return true;
else
entry = entry.next;
while (--index >= 0 && (entry = table[index]) != null) ;
}
return false;
}
public Object nextElement() {
while (index >= 0) {
if (entry == null)
while (--index >= 0 && (entry = table[index]) == null) ;
if (entry != null) {
CacheEntry e = entry;
entry = e.next;
if (e.check() != null)
return keys ? e.key : e.check();
}
}
throw new NoSuchElementException("CacheEnumerator");
}
}
Changing the constructor as follows seems to fix the problem, though we
haven't tested it thoroughly. Also it would be helpful to comment on the
logic.
CacheEnumerator (CacheEntry table[], boolean keys) {
System.out.println("table.length = " + table.length);
this.table = table;
this.keys = keys;
this.index = table.length - 1;
this.entry = table[index];
}
The problem was in the following statement in hasMoreElements:
while (--index >= 0 && (entry = table[index]) != null) ;
The "!= null" should be "== null" since the objective is to skip over the null
elements.
[prasadw, pavani 960514]
Here is a test program:
$ more T.java
import java.util.*;
import sun.misc.Cache;
class T {
public static void main(String argv[]) {
Cache numbers = new Cache();
Enumeration enumElements;
Enumeration enumKeys;
Object object;
numbers.put("one", new Integer(1));
numbers.put("two", new Integer(1));
numbers.put("three", new Integer(1));
System.out.println("size = " + numbers.size());
enumElements = numbers.elements();
System.out.println("enumElements.hasMoreElements() = " +
enumElements.hasMoreElements());
enumKeys = numbers.keys();
System.out.println("enumKeys.hasMoreElements() = " +
enumKeys.hasMoreElements());
}
}
$ javac T.java
$ java T
size = 3
enumElements.hasMoreElements() = false
enumKeys.hasMoreElements() = false
The problem is that when the hasMoreElements function in CacheEnumerator
is entered entry is not initialized.
/**
* A Cache enumerator class. This class should remain opaque
* to the client. It will use the Enumeration interface.
*/
class CacheEnumerator implements Enumeration {
boolean keys;
int index;
CacheEntry table[];
CacheEntry entry;
CacheEnumerator (CacheEntry table[], boolean keys) {
this.table = table;
this.keys = keys;
this.index = table.length;
}
public boolean hasMoreElements() {
while (index >= 0) {
while (entry != null)
if (entry.check() != null)
return true;
else
entry = entry.next;
while (--index >= 0 && (entry = table[index]) != null) ;
}
return false;
}
public Object nextElement() {
while (index >= 0) {
if (entry == null)
while (--index >= 0 && (entry = table[index]) == null) ;
if (entry != null) {
CacheEntry e = entry;
entry = e.next;
if (e.check() != null)
return keys ? e.key : e.check();
}
}
throw new NoSuchElementException("CacheEnumerator");
}
}
Changing the constructor as follows seems to fix the problem, though we
haven't tested it thoroughly. Also it would be helpful to comment on the
logic.
CacheEnumerator (CacheEntry table[], boolean keys) {
System.out.println("table.length = " + table.length);
this.table = table;
this.keys = keys;
this.index = table.length - 1;
this.entry = table[index];
}