/** * @return Null, if attribute is a duplicate (to indicate error); map itself, or resized version, * otherwise. */ private int[] spillAttr( String name, int[] map, int currIndex, int spillIndex, int attrCount, int hash, int hashCount) { // Do we have a dup with primary entry? /* Can do equality comp for local name, as they * are always canonicalized: */ if (mAttrNames.getString(currIndex) == name) { return null; } /* Is there room to spill into? (need to have 2 int spaces; one for * hash, the other for index) */ if ((spillIndex + 1) >= map.length) { // Let's just add room for 4 spills... map = DataUtil.growArrayBy(map, 8); } // Let's first ensure we aren't adding a dup: for (int j = hashCount; j < spillIndex; j += 2) { if (map[j] == hash) { currIndex = map[j + 1]; if (mAttrNames.getString(currIndex) == name) { return null; } } } map[spillIndex] = hash; return map; }
/** * Method called by validator to insert an attribute that has a default value and wasn't yet * included in collector's attribute set. * * @return Index of the newly added attribute, if added; -1 to indicate this was a duplicate */ public int addDefaultAttribute(String localName, String value) { int attrIndex = mAttrCount; if (attrIndex < 1) { /* had no explicit attributes... better initialize now, then. * Let's just use hash area of 4, and */ initHashArea(); } /* Ok, first, since we do want to verify that we can not accidentally * add duplicates, let's first try to add entry to Map, since that * will catch dups. */ int hash = localName.hashCode(); int index = hash & (mAttrHashSize - 1); int[] map = mAttrMap; if (map[index] == 0) { // whoa, have room... map[index] = attrIndex + 1; // add 1 to get 1-based index (0 is empty marker) } else { // nah, collision... int currIndex = map[index] - 1; // Index of primary collision entry int spillIndex = mAttrSpillEnd; map = spillAttr(localName, map, currIndex, spillIndex, attrIndex, hash, mAttrHashSize); if (map == null) { // dup! return -1; // could return negation (-(index+1)) of the prev index? } map[++spillIndex] = attrIndex; // no need to specifically avoid 0 mAttrMap = map; mAttrSpillEnd = ++spillIndex; } // And then, finally, let's add the entry to Lists: mAttrNames.addString(localName); // First, the name if (mAttrValues == null) { mAttrValues = new String[attrIndex + 8]; } else if (attrIndex >= mAttrValues.length) { mAttrValues = DataUtil.growArrayBy(mAttrValues, 8); } mAttrValues[attrIndex] = value; return mAttrCount++; }