/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2016 JaamSim Software Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaamsim.basicsim;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicLong;

public class JaamSimModel {
	private final AtomicLong entityCount = new AtomicLong(0);
	private final ArrayList<Entity> allInstances = new ArrayList<>(100);
	final HashMap<String, Entity> namedEntities = new HashMap<>(100);

	public JaamSimModel() {
	}

	final long getNextEntityID() {
		return entityCount.incrementAndGet();
	}

	public final Entity getNamedEntity(String name) {
		synchronized (namedEntities) {
			return namedEntities.get(name);
		}
	}

	public final long getEntitySequence() {
		long seq = (long)allInstances.size() << 32;
		seq += entityCount.get();
		return seq;
	}

	public final Entity idToEntity(long id) {
		synchronized (allInstances) {
			for (Entity e : allInstances) {
				if (e.getEntityNumber() == id) {
					return e;
				}
			}
			return null;
		}
	}

	private static class EntityComparator implements Comparator<Entity> {
		@Override
        public int compare(Entity e1, Entity e2) {
			return Long.compare(e1.getEntityNumber(), e2.getEntityNumber());
        }
     }
	private static final EntityComparator entityComparator = new EntityComparator();

	public final ArrayList<? extends Entity> getEntities() {
		synchronized(allInstances) {
			return allInstances;
		}
	}

	void addInstance(Entity e) {
		synchronized(allInstances) {
			allInstances.add(e);
		}
	}

	void removeInstance(Entity e) {
		synchronized (allInstances) {
			int index = Collections.binarySearch(allInstances, e, entityComparator);
			if (index >= 0)
				allInstances.remove(index);
		}
	}
}

@@ -702,67 +702,8 @@
 st;%0A
-import java.util.Collections;%0Aimport java.util.Comparator;%0A
 impo
@@ -1368,37 +1368,34 @@
 %0A%0A%09p
-ublic
+rivate
  final 
-E
+i
 nt
-ity
  idTo
-Entity
+Index
 (lon
@@ -1408,460 +1408,589 @@
 %7B%0A%09%09
-synchronized (allInstances) %7B%0A%09%09%09for (Entity e : allInstances) %7B%0A%09%09%09%09if (e.getEntityNumber() == id) %7B%0A%09%09%09%09%09return e;%0A%09%09%09%09%7D
+int lowIdx = 0;%0A%09%09int highIdx = allInstances.size() - 1;%0A%0A%09%09while (lowIdx %3C= highIdx) %7B%0A%09%09%09int testIdx = (lowIdx + highIdx) %3E%3E%3E 1; // Avoid sign extension%0A%09%09%09long testNum = allInstances.get(testIdx).getEntityNumber();%0A%0A%09%09%09if (testNum %3C id) %7B%0A%09%09%09%09lowIdx = testIdx + 1;%0A%09%09%09%09continue;
 %0A%09%09%09%7D%0A
+%0A
 %09%09%09
-return null;%0A%09%09%7D%0A%09%7D%0A%0A%09priva
+if (testNum %3E id) %7B%0A%09%09%09%09highIdx = 
 te
- 
 st
-atic class EntityComparator implements Comparator%3CEntity%3E %7B%0A%09%09@Override%0A        
+Idx - 1;%0A%09%09%09%09continue;%0A%09%09%09%7D%0A%0A%09%09%09return testIdx;%0A%09%09%7D%0A%09%09return -1;%0A%09%7D%0A%0A%09
 public 
+f
 in
-t compare(
+al 
 Entity 
-e1, 
+idTo
 Entity
- e2) %7B%0A%09%09%09return Long.compare(e1.getEntityNumber(), e2.getEntityNumber());%0A        %7D%0A     %7D%0A%09private static final EntityComparator entityComparator = new EntityComparator();
+(long id) %7B%0A%09%09synchronized (allInstances) %7B%0A%09%09%09int idx = this.idToIndex(id);%0A%09%09%09if (idx == -1)%0A%09%09%09%09return null;%0A%0A%09%09%09return allInstances.get(idx);%0A%09%09%7D%0A%09%7D
 %0A%0A%09p
@@ -2105,24 +2105,30 @@
 s;%0A%09%09%7D%0A%09%7D%0A%0A%09
+final 
 void addInst
@@ -2208,16 +2208,22 @@
 %09%7D%0A%09%7D%0A%0A%09
+final 
 void rem
@@ -2297,66 +2297,37 @@
 x = 
-Collections.binarySearch(allInstances, e, entityComparator
+idToIndex(e.getEntityNumber()
 );%0A%09
@@ -2348,16 +2348,25 @@
  0)%0A%09%09%09%09
+if (e != 
 allInsta
@@ -2383,16 +2383,91 @@
 e(index)
+)%0A%09%09%09%09%09throw new ErrorException(%22Internal Consistency Error - Entity List%22)
 ;%0A%09%09%7D%0A%09%7D

add an opencoded binary search implementation to speed entity picking