--- Old/MemValueIndexer.java Tue Mar 07 12:40:45 2006 +++ New/MemValueIndexer.java Tue Mar 07 12:48:09 2006 @@ -87,7 +87,7 @@ private static final String CHAR_VAL = "char"; private static final String BOOLEAN_VAL = "boolean"; - private static final IndexMatch[] EMPTY_INDEX_MATCH_ARRAY = new IndexMatch[0]; + private final static IndexMatch[] EMPTY_INDEX_MATCH_ARRAY = new IndexMatch[0]; // // Instance variables @@ -410,17 +410,13 @@ // always compare against the String form of the comparator // to ensure that comparisons happen as Strings as specified by XPath // for starts-with - aLowEndpoint = aQueryValueList[0]; - if (itsValueType == TRIMMED) { - aLowEndpoint = QueryEngine.normalizeString((String) aLowEndpoint); - } else { - if (itsValueType != STRING) { - aLowEndpoint = ((String) aLowEndpoint).trim(); - } + if(! (aLowEndpoint instanceof String) ) + { + aLowEndpoint = aLowEndpoint.toString(); } // get the matching submap forcing String comparisons to be used regardless of stored type - aResult = getIndexMatchArray(getBWSubmap(aLowEndpoint, aLowEndpoint)); + aResult = getIndexMatchArray(getSWSubmap((String)aLowEndpoint)); break; case IndexQuery.IN: // In the (presumed sorted) set of specified query values @@ -447,13 +443,9 @@ // implement as LT or GT forcing String comparisons // we get the raw String match value and use that instead of the typed value // to force String comparisons (as required for starts-with) - aLowEndpoint = aQueryValueList[0]; - if (itsValueType == TRIMMED) { - aLowEndpoint = QueryEngine.normalizeString((String) aLowEndpoint); - } else { - if (itsValueType != STRING) { - aLowEndpoint = ((String) aLowEndpoint).trim(); - } + if(! (aLowEndpoint instanceof String) ) + { + aLowEndpoint = aLowEndpoint.toString(); } // get all matches below starts-with range and above starts-with range @@ -495,6 +487,32 @@ } /** + * Provides the submap containing the half-open range (inclusive of Low Endpoint but not High Endpoint) + * between the theLowEndpoint and getNextValueOf(theLowEndpoint, STRING). + * + * @param theLowEndpoint low endpoint to use + * @return a SortedMap containing the matches or null if no matches + */ + private SortedMap getSWSubmap(String theLowEndpoint) { + SortedMap aSubmap = null; + TreeSet aLocatorSet; + + // force computation of next value as STRING if key is String + // otherwise, next value will be of same type as stored values + String aHighEndpoint = (String)getNextValueOf(theLowEndpoint, STRING); + + if (aHighEndpoint == null) { + // return locators in tail map from low endpoint + aSubmap = itsValues.tailMap(theLowEndpoint); + } else { + // return locators in sub map inclusive of endpoints + aSubmap = itsValues.subMap(theLowEndpoint, aHighEndpoint); + } + + return aSubmap == null || aSubmap.size() == 0 ? null : aSubmap; + } + + /** * Provides the submap containing the closed range (inclusive of both endpoints) * between the specified endpoints. * @@ -1036,7 +1054,9 @@ return theValue + "\0"; } // return a string of the same length with the final character incremented by 1 - aReturn = ((String) theValue).substring(0, aLength - 1) + String.valueOf(aLastChar + 1); + // be sure to avoid upcasting to int which would happen if you do "a" + (aLastChar + 1) + aLastChar += 1; + aReturn = ((String) theValue).substring(0, aLength - 1) + aLastChar; break; case SHORT: { @@ -1477,4 +1497,4 @@ */ private final short itsAttributeID; } -} +} \ No newline at end of file