Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1351671) +++ lucene/CHANGES.txt (working copy) @@ -985,6 +985,9 @@ * LUCENE-4098: Add bulk get/set methods to PackedInts (Adrien Grand via Mike McCandless) + +* LUCENE-4156: DirectoryTaxonomyWriter.getSize is no longer synchronized. + (Shai Erera, Sivan Yogev) Bug fixes Index: lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java =================================================================== --- lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java (revision 1351672) +++ lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java (working copy) @@ -103,7 +103,6 @@ /** Records the taxonomy index creation time, updated on replaceTaxonomy as well. */ private String createTime; - private int nextID; private char delimiter = Consts.DEFAULT_DELIMITER; private SinglePositionTokenStream parentStream = new SinglePositionTokenStream(Consts.PAYLOAD_PARENT); private Field parentStreamField; @@ -126,6 +125,7 @@ private volatile boolean shouldRefreshReaderManager; private volatile boolean isClosed = false; private volatile ParentArray parentArray; + private volatile int nextID; /** Reads the commit data from a Directory. */ private static Map readCommitData(Directory dir) throws IOException { @@ -135,16 +135,16 @@ } /** - * setDelimiter changes the character that the taxonomy uses in its internal - * storage as a delimiter between category components. Do not use this - * method unless you really know what you are doing. It has nothing to do - * with whatever character the application may be using to represent - * categories for its own use. - *

+ * Changes the character that the taxonomy uses in its internal storage as a + * delimiter between category components. Do not use this method unless you + * really know what you are doing. It has nothing to do with whatever + * character the application may be using to represent categories for its own + * use. + *

* If you do use this method, make sure you call it before any other methods - * that actually queries the taxonomy. Moreover, make sure you always pass - * the same delimiter for all LuceneTaxonomyWriter and LuceneTaxonomyReader - * objects you create for the same directory. + * that actually queries the taxonomy. Moreover, make sure you always pass the + * same delimiter for all taxonomy writer and reader instances you create for + * the same directory. */ public void setDelimiter(char delimiter) { ensureOpen(); @@ -226,7 +226,7 @@ parentStreamField = new Field(Consts.FIELD_PAYLOADS, parentStream, ft); fullPathField = new StringField(Consts.FULL, "", Field.Store.YES); - this.nextID = indexWriter.maxDoc(); + nextID = indexWriter.maxDoc(); if (cache == null) { cache = defaultTaxonomyWriterCache(); @@ -706,43 +706,28 @@ indexWriter.prepareCommit(combinedCommitData(commitUserData)); } - /** - * getSize() returns the number of categories in the taxonomy. - *

- * Because categories are numbered consecutively starting with 0, it means - * the taxonomy contains ordinals 0 through getSize()-1. - *

- * Note that the number returned by getSize() is often slightly higher than - * the number of categories inserted into the taxonomy; This is because when - * a category is added to the taxonomy, its ancestors are also added - * automatically (including the root, which always get ordinal 0). - */ @Override - synchronized public int getSize() { + public int getSize() { ensureOpen(); - return indexWriter.maxDoc(); + return nextID; } - + /** - * Set the number of cache misses before an attempt is made to read the - * entire taxonomy into the in-memory cache. - *

- * LuceneTaxonomyWriter holds an in-memory cache of recently seen - * categories to speed up operation. On each cache-miss, the on-disk index - * needs to be consulted. When an existing taxonomy is opened, a lot of - * slow disk reads like that are needed until the cache is filled, so it - * is more efficient to read the entire taxonomy into memory at once. - * We do this complete read after a certain number (defined by this method) - * of cache misses. - *

- * If the number is set to 0, the entire taxonomy is read - * into the cache on first use, without fetching individual categories - * first. - *

- * Note that if the memory cache of choice is limited in size, and cannot - * hold the entire content of the on-disk taxonomy, then it is never - * read in its entirety into the cache, regardless of the setting of this - * method. + * Set the number of cache misses before an attempt is made to read the entire + * taxonomy into the in-memory cache. + *

+ * This taxonomy writer holds an in-memory cache of recently seen categories + * to speed up operation. On each cache-miss, the on-disk index needs to be + * consulted. When an existing taxonomy is opened, a lot of slow disk reads + * like that are needed until the cache is filled, so it is more efficient to + * read the entire taxonomy into memory at once. We do this complete read + * after a certain number (defined by this method) of cache misses. + *

+ * If the number is set to {@code 0}, the entire taxonomy is read into the + * cache on first use, without fetching individual categories first. + *

+ * NOTE: it is assumed that this method is called immediately after the + * taxonomy writer has been created. */ public void setCacheMissesUntilFill(int i) { ensureOpen(); @@ -842,7 +827,7 @@ // for the parent of a nonexistant category - even if the parent array // was allocated bigger than it really needs to be. if (ordinal >= getSize()) { - throw new ArrayIndexOutOfBoundsException(); + throw new ArrayIndexOutOfBoundsException("requested ordinal is bigger than the largest ordinal in the taxonomy"); } return getParentArray().getArray()[ordinal]; }