I believe this app uses 2.0 but I do have 3.5 installed, so not sure if it just uses the latest or what.
Here is some sample code, note that there is lot of OOP involved but this is basically the order it gets executed as. There are about 1mil total entries in the DB, ranging from 10 to about 80k strings. There are only maybe like 100 or so that are 80k+ then it drasticly goes down towards the 10ks then lower.
First block, load data and create item instances:
Code:
//load Mobiles:
Console.WriteLine("Loading Mobiles...");
if(!Core.SQLCON.Query("SELECT * FROM mobiles;"))
{
Console.WriteLine("Error loading mobiles! This is fatal and stuff. Terminating");
Console.ReadKey();
return;
}
m_Mobiles = new Dictionary<Serial, Mobile>();
while(Core.SQLCON.FetchRow())
{
int serial = Core.SQLCON.Reader.GetInt32(0);
string serialstr = serial.ToString();
int typeid = Core.SQLCON.Reader.GetInt32(1);
string typestr = Core.SQLCON.Reader.GetString(2);
string serializedata = Core.SQLCON.Reader.GetString(3);
//ensure it has not been flagged as a bad type:
bool badtype=false;
foreach(string comp in m_badtypes)
{
if(comp==typestr)
{
badtype=true;
break;
}
}
if(badtype)continue;
//get type:
Type t = ScriptCompiler.FindTypeByFullName( typestr );
if ( t == null )
{
FailLoadMsg(serialstr,typestr,"type not found");
m_badtypes.Add(typestr);
continue;
}
//check for serialization constructor:
ConstructorInfo ctor = t.GetConstructor( ctorTypes );
if ( ctor == null )
{
FailLoadMsg(serialstr,typestr,"No serialization constructor");
m_badtypes.Add(typestr);
}
//create object and add to world:
Mobile m = null;
try {
ctorArgs[0] = ( Serial ) serial;
m = ( Mobile ) ( ctor.Invoke( ctorArgs ) );
}
catch
{
FailLoadMsg(serialstr,typestr,"Could not construct object");
}
if ( m != null )
{
AddMobile( m );
}
PreLoadMobs.Add(new PreLoadMob(m,serializedata));
mobileCount++;
}
Second block: deserialization - take string, and populate the variables within the actual created item (the mobile in this case)
Code:
Console.WriteLine("Deserializing mobiles...");
foreach(PreLoadMob preload in PreLoadMobs)
{
preload.Deserialize();
}
This is how a preloadmob looks like:
Code:
private class PreLoadMob
{
Mobile Mob;
string Data;
public PreLoadMob(Mobile pmob,string pdata)
{
Mob=pmob;
Data=pdata;
}
public void Deserialize()
{
if(Core.DebugLoad)Console.WriteLine("------- Deserialize mobile {0} with data {1}...",Mob.Serial,Data);
SqlReader reader = new SqlReader(Data,(int)Mob.Serial);
Mob.Deserialize(reader);
}
}
One issue I did just realize here is that I'm actually storing ALL strings into memory at the same time but while that is a lot of data, it's still not enough to go over the amount of ram I have. Durring this stage the app is using about 400MB of ram.
It usually crashes during the 2nd stage where it deserializes the string. (this just loops through by position to get the data in chunks).
Now one way I suppose that would maybe help is if I did not hold unto the data of every single string, and just had another SELECT statement for deserialize. I may look into that, though I think the cause of the crash is the fact of putting tons of data in a single string, it really does not care about all the other strings at that point considering there's tons of ram still left.
There are actually 3 loops of each, I just simplified it here. The initial load loops must happen before the deserialize.