Changed DOIds to be safer, added reusableIds

DOIds are still 100% needed for instances.

ReusableIds will be ideal for staticService and many other locations
where you know the object is only temporary to that session.
This commit is contained in:
Treeku
2014-08-25 21:24:23 +01:00
parent 326963f96e
commit 1dd7d712a3
3 changed files with 109 additions and 6 deletions
+7
View File
@@ -226,6 +226,7 @@ public class NGECore {
private ObjectDatabase guildODB;
private ObjectDatabase objectIdODB;
private ObjectDatabase duplicateIdODB;
private ObjectDatabase reusableIdODB;
private ObjectDatabase chatRoomODB;
private BusConfiguration eventBusConfig = BusConfiguration.Default(1, new ThreadPoolExecutor(1, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()));
@@ -321,6 +322,7 @@ public class NGECore {
guildODB = new ObjectDatabase("guild", true, true, true, GuildObject.class);
objectIdODB = new ObjectDatabase("oids", true, true, true, ObjectId.class);
duplicateIdODB = new ObjectDatabase("doids", true, true, true, DuplicateId.class);
reusableIdODB = new ObjectDatabase("reusableIds", true, true, true, ObjectId.class);
chatRoomODB = new ObjectDatabase("chatRooms", true, true, true, ChatRoom.class);
resourceHistoryODB = new ObjectDatabase("resourcehistory", true, true, true, GalacticResource.class);
auctionODB = new ObjectDatabase("auction", true, true, true, AuctionItem.class);
@@ -716,6 +718,10 @@ public class NGECore {
return duplicateIdODB;
}
public ObjectDatabase getReusableIdODB() {
return reusableIdODB;
}
public ObjectDatabase getChatRoomODB() {
return chatRoomODB;
}
@@ -858,6 +864,7 @@ public class NGECore {
resourceHistoryODB.close();
objectIdODB.close();
duplicateIdODB.close();
reusableIdODB.close();
auctionODB.close();
cityODB.close();
}
+2 -1
View File
@@ -140,7 +140,8 @@ public class StaticService implements INetworkDispatch {
}
//long objectId = core.objectService.getDOId(planetName, template, 0, buildingId, cellNumber, x, y, z);
long objectId = 0;
long objectId = core.objectService.getReusableId();
//long objectId = 0;
SWGObject object = null;
MobileTemplate mobileTemplate = core.spawnService.getMobileTemplate(template);
+100 -5
View File
@@ -36,6 +36,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
@@ -152,6 +153,8 @@ public class ObjectService implements INetworkDispatch {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
protected final Object objectMutex = new Object();
private List<Runnable> loadServerTemplateTasks = Collections.synchronizedList(new ArrayList<Runnable>());
private int iteratedReusedIds = 0;
private List<Long> reusableIds = Collections.synchronizedList(new ArrayList<Long>());
public ObjectService(final NGECore core) {
this.core = core;
@@ -202,6 +205,12 @@ public class ObjectService implements INetworkDispatch {
objectList.put(object.getObjectID(), object);
}
cursor = core.getReusableIdODB().getCursor();
while (cursor.hasNext()) {
reusableIds.add(((ObjectId) cursor.next()).objectId);
}
loadBuildings();
System.out.println("Finished loading objects.");
}
@@ -788,16 +797,98 @@ public class ObjectService implements INetworkDispatch {
long objectId = 0;
if (core.getDuplicateIdODB().contains(key)) {
objectId = ((DuplicateId) core.getDuplicateIdODB().get(key)).getObjectId();
boolean containsKey;
synchronized(objectMutex) {
containsKey = core.getDuplicateIdODB().contains(key);
}
if (containsKey) {
synchronized(objectMutex) {
objectId = ((DuplicateId) core.getDuplicateIdODB().get(key)).getObjectId();
}
if (objectList.containsKey(objectId)) {
System.err.println("Warning: DOId already in use. Using one from reusableId pool instead.");
return getReusableId();
}
} else {
objectId = generateObjectID();
core.getDuplicateIdODB().put(key, new DuplicateId(key, objectId));
while (true) {
objectId = generateObjectID();
synchronized(objectMutex) {
if (!core.getObjectIdODB().contains(objectId)) {
core.getObjectIdODB().put(objectId, new ObjectId(objectId));
} else {
System.err.println("Error: Generated objectId is already in objectIdODB?");
System.err.println("Trying again...");
continue;
}
if (objectList.containsKey(objectId)) {
System.err.println("Error: Generated objectId is already in objectList?");
System.err.println("Trying again...");
continue;
}
}
break;
}
synchronized(objectMutex) {
core.getDuplicateIdODB().put(key, new DuplicateId(key, objectId));
}
}
return objectId;
}
public long getReusableId() {
long objectId = 0;
synchronized(objectMutex) {
objectId = reusableIds.iterator().next();
while (objectList.containsKey(objectId) && iteratedReusedIds++ < reusableIds.size()) {
objectId = reusableIds.get(iteratedReusedIds);
}
if (objectList.containsKey(objectId)) {
objectId = 0;
}
}
if (objectId == 0) {
while (true) {
objectId = generateObjectID();
synchronized(objectMutex) {
if (!core.getObjectIdODB().contains(objectId)) {
core.getObjectIdODB().put(objectId, new ObjectId(objectId));
} else {
System.err.println("Error: Generated objectId is already in objectIdODB?");
System.err.println("Trying again...");
continue;
}
if (objectList.containsKey(objectId)) {
System.err.println("Error: Generated objectId is already in objectList?");
System.err.println("Trying again...");
continue;
}
core.getReusableIdODB().put(objectId, new ObjectId(objectId));
reusableIds.add(objectId);
iteratedReusedIds++;
break;
}
}
}
return objectId;
}
public Vector<SWGObject> getItemsInContainerByStfName(CreatureObject creature, long containerId, String stfName) {
Vector<SWGObject> itemList = new Vector<SWGObject>();
SWGObject container = getObject(containerId);
@@ -1080,6 +1171,10 @@ public class ObjectService implements INetworkDispatch {
}
}
creature.setIntendedTarget(0);
creature.setLookAtTarget(0);
PlayerObject ghost = (PlayerObject) creature.getSlottedObject("ghost");
if (ghost == null) {