package lux;

import java.util.concurrent.ConcurrentHashMap;

import net.sf.saxon.tree.util.DocumentNumberAllocator;

/**
 * We guarantee that lux:search returns result in document order, which to Saxon means that
 * the ids of the documents it returns must be in increasing order.  lux:search gathers
 * docIDs in increasing order and calls setNextDocID(int) in order to maintain the same numbering 
 * scheme in Saxon.  Internally-generated documents are allocated ids starting at Integer.MAX_VALUE+1 -
 * Lucene ids are always ints.
 *
 */
public class DocIDNumberAllocator extends DocumentNumberAllocator {
    
    private long nextInternalID = Integer.MAX_VALUE+1;
    
    private ConcurrentHashMap<Long,Integer> nextThreadDocId = new ConcurrentHashMap<Long, Integer>();
  
    /**
     * It is the caller's responsibility to ensure that the same id is not assigned to multiple different documents, 
     * IDs must be assigned to documents in such a way that a consistent document ordering is maintained.
     * In order to ensure thread safety, a separate id is maintained for each calling thread.  
     * @param id the next id to allocate for the calling thread, or null if the next id to allocate should be an internal id.
     */
    public void setNextDocID (Integer id) {
        long threadId = Thread.currentThread().getId();
        nextThreadDocId.put(threadId, id);
    }
    
    @Override
    public long allocateDocumentNumber() {
        long id;
        long threadId = Thread.currentThread().getId();
        Integer nextDocID = nextThreadDocId.get(threadId);
        if (nextDocID != null) {
            id = nextDocID;
            nextThreadDocId.remove(threadId);
        } else {
            id = nextInternalID++;
        }
        return id;
    }
}

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

@@ -11,56 +11,8 @@
 x;%0A%0A
-import java.util.concurrent.ConcurrentHashMap;%0A%0A
 impo
@@ -633,39 +633,28 @@
 private 
-ConcurrentHashMap%3CLong,
+ThreadLocal%3C
 Integer%3E
@@ -680,32 +680,20 @@
 new 
-ConcurrentHashMap%3CLong, 
+ThreadLocal%3C
 Inte
@@ -1213,64 +1213,8 @@
 ) %7B%0A
-        long threadId = Thread.currentThread().getId();%0A
     
@@ -1237,22 +1237,13 @@
 cId.
-put(threadId, 
+set (
 id);
@@ -1332,64 +1332,8 @@
 id;%0A
-        long threadId = Thread.currentThread().getId();%0A
     
@@ -1376,24 +1376,16 @@
 cId.get(
-threadId
 );%0A     
@@ -1472,23 +1472,16 @@
 cId.
-remove(threadId
+set(null
 );%0A 

use ThreadLocal<Integer> instead of ConcurrentHashMap keyed on thread id - should be cleaner