mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Add initial ThreadSafeCache class, also do Database.TableExists checks for zones/portals/messages.
This commit is contained in:
parent
b5b8197c04
commit
cb51be2d6a
@ -351,8 +351,7 @@ namespace MCGalaxy {
|
||||
try {
|
||||
Level level = LvlFile.Load(name, path);
|
||||
level.setPhysics(phys);
|
||||
level.backedup = true;
|
||||
LevelDB.LoadZones(level, name);
|
||||
level.backedup = true;
|
||||
|
||||
level.jailx = (ushort)(level.spawnx * 32);
|
||||
level.jaily = (ushort)(level.spawny * 32);
|
||||
@ -360,13 +359,7 @@ namespace MCGalaxy {
|
||||
level.jailrotx = level.rotx;
|
||||
level.jailroty = level.roty;
|
||||
level.StartPhysics();
|
||||
|
||||
try {
|
||||
LevelDB.LoadMetadata(level, name);
|
||||
} catch (Exception e) {
|
||||
Server.ErrorLog(e);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
string propsPath = LevelInfo.FindPropertiesFile(level.name);
|
||||
if (propsPath != null)
|
||||
@ -385,6 +378,12 @@ namespace MCGalaxy {
|
||||
level.CustomBlockDefs[i] = defs[i];
|
||||
}
|
||||
Bots.BotsFile.LoadBots(level);
|
||||
|
||||
object locker = ThreadSafeCache.DBCache.Get(name);
|
||||
lock (locker) {
|
||||
LevelDB.LoadZones(level, name);
|
||||
LevelDB.LoadMetadata(level, name);
|
||||
}
|
||||
|
||||
Server.s.Log(string.Format("Level \"{0}\" loaded.", level.name));
|
||||
if (LevelLoaded != null)
|
||||
|
@ -109,6 +109,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
internal static void LoadZones(Level level, string name) {
|
||||
if (!Database.TableExists("Zone" + name)) return;
|
||||
using (DataTable table = Database.Fill("SELECT * FROM `Zone" + name + "`")) {
|
||||
Level.Zone Zn;
|
||||
foreach (DataRow row in table.Rows) {
|
||||
@ -124,7 +125,8 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LoadMetadata(Level level, string name) {
|
||||
internal static void LoadPortals(Level level, string name) {
|
||||
if (!Database.TableExists("Portals" + name)) return;
|
||||
using (DataTable table = Database.Fill("SELECT * FROM `Portals" + name + "`")) {
|
||||
foreach (DataRow row in table.Rows) {
|
||||
byte tile = level.GetTile(ushort.Parse(row["EntryX"].ToString()),
|
||||
@ -136,7 +138,10 @@ namespace MCGalaxy {
|
||||
row["EntryX"], row["EntryY"], row["EntryZ"]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static void LoadMessages(Level level, string name) {
|
||||
if (!Database.TableExists("Messages" + name)) return;
|
||||
using (DataTable table = Database.Fill("SELECT * FROM `Messages" + name + "`")) {
|
||||
foreach (DataRow row in table.Rows) {
|
||||
byte tile = level.GetTile(ushort.Parse(row["X"].ToString()),
|
||||
@ -159,12 +164,12 @@ namespace MCGalaxy {
|
||||
|
||||
public static void CreateZone(string level, Level.Zone zn) {
|
||||
Database.Execute("INSERT INTO `Zone" + level + "` (Owner, SmallX, SmallY, " +
|
||||
"SmallZ, BigX, BigY, BigZ) VALUES (@0, @1, @2, @3, @4, @5, @6)",
|
||||
"SmallZ, BigX, BigY, BigZ) VALUES (@0, @1, @2, @3, @4, @5, @6)",
|
||||
zn.Owner, zn.smallX, zn.smallY, zn.smallZ, zn.bigX, zn.bigY, zn.bigZ);
|
||||
}
|
||||
|
||||
|
||||
const string createBlock =
|
||||
internal const string createBlock =
|
||||
@"CREATE TABLE if not exists `Block{0}` (
|
||||
Username CHAR(20),
|
||||
TimePerformed DATETIME,
|
||||
@ -174,7 +179,7 @@ Z SMALLINT UNSIGNED,
|
||||
Type TINYINT UNSIGNED,
|
||||
Deleted {1})";
|
||||
|
||||
const string createPortals =
|
||||
internal const string createPortals =
|
||||
@"CREATE TABLE if not exists `Portals{0}` (
|
||||
EntryX SMALLINT UNSIGNED,
|
||||
EntryY SMALLINT UNSIGNED,
|
||||
@ -184,14 +189,14 @@ ExitX SMALLINT UNSIGNED,
|
||||
ExitY SMALLINT UNSIGNED,
|
||||
ExitZ SMALLINT UNSIGNED)";
|
||||
|
||||
const string createMessages =
|
||||
internal const string createMessages =
|
||||
@"CREATE TABLE if not exists `Messages{0}` (
|
||||
X SMALLINT UNSIGNED,
|
||||
Y SMALLINT UNSIGNED,
|
||||
Z SMALLINT UNSIGNED,
|
||||
Message CHAR(255))";
|
||||
|
||||
const string createZones =
|
||||
internal const string createZones =
|
||||
@"CREATE TABLE if not exists `Zone{0}` (
|
||||
SmallX SMALLINT UNSIGNED,
|
||||
SmallY SMALLINT UNSIGNED,
|
||||
|
@ -580,6 +580,7 @@
|
||||
<Compile Include="Server\Server.Fields.cs" />
|
||||
<Compile Include="Server\Server.Init.cs" />
|
||||
<Compile Include="Server\Server.Tasks.cs" />
|
||||
<Compile Include="Server\ThreadSafeCache.cs" />
|
||||
<Compile Include="Server\Updater.cs" />
|
||||
<Compile Include="API\WebServer.cs" />
|
||||
<Compile Include="util\BufferedBlockSender.cs" />
|
||||
|
@ -115,11 +115,14 @@ namespace MCGalaxy {
|
||||
Mods.Clear();
|
||||
Background.QueueOnce(UpdateStaffListTask);
|
||||
|
||||
MainScheduler.QueueRepeat(TemprankExpiryTask, null, TimeSpan.FromSeconds(60));
|
||||
MainScheduler.QueueRepeat(TemprankExpiryTask, null,
|
||||
TimeSpan.FromMinutes(1));
|
||||
Background.QueueRepeat(AutoSaveTask, 1,
|
||||
TimeSpan.FromSeconds(Server.backupInterval));
|
||||
TimeSpan.FromSeconds(Server.backupInterval));
|
||||
Background.QueueRepeat(BlockUpdatesTask, null,
|
||||
TimeSpan.FromSeconds(Server.blockInterval));
|
||||
TimeSpan.FromSeconds(Server.blockInterval));
|
||||
Background.QueueRepeat(ThreadSafeCache.CleanupTask, null,
|
||||
TimeSpan.FromMinutes(5));
|
||||
}
|
||||
|
||||
void EnsureFilesExist() {
|
||||
|
81
Server/ThreadSafeCache.cs
Normal file
81
Server/ThreadSafeCache.cs
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MCGalaxy {
|
||||
public sealed class ThreadSafeCache {
|
||||
static readonly List<ThreadSafeCache> caches = new List<ThreadSafeCache>();
|
||||
static readonly object cachesLock = new object();
|
||||
|
||||
public static ThreadSafeCache DBCache = new ThreadSafeCache(() => new object());
|
||||
|
||||
readonly object locker = new object();
|
||||
readonly Dictionary<string, object> items = new Dictionary<string, object>();
|
||||
readonly Dictionary<string, DateTime> access = new Dictionary<string, DateTime>();
|
||||
readonly Func<object> constructor;
|
||||
|
||||
public ThreadSafeCache(Func<object> constructor) {
|
||||
this.constructor = constructor;
|
||||
lock (cachesLock)
|
||||
caches.Add(this);
|
||||
}
|
||||
|
||||
public object Get(string key) {
|
||||
lock (locker) {
|
||||
object value;
|
||||
if (!items.TryGetValue(key, out value)) {
|
||||
value = constructor();
|
||||
items[key] = value;
|
||||
}
|
||||
|
||||
access[key] = DateTime.UtcNow;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static void CleanupTask(SchedulerTask task) {
|
||||
lock (cachesLock) {
|
||||
foreach (ThreadSafeCache cache in caches)
|
||||
cache.CleanupOld();
|
||||
}
|
||||
}
|
||||
|
||||
void CleanupOld() {
|
||||
List<string> free = null;
|
||||
DateTime now = DateTime.UtcNow;
|
||||
|
||||
lock (locker) {
|
||||
foreach (var kvp in access) {
|
||||
// Has the cached item last been accessed in 5 minutes?
|
||||
if ((now - kvp.Value).TotalMinutes <= 5) continue;
|
||||
|
||||
if (free == null) free = new List<string>();
|
||||
free.Add(kvp.Key);
|
||||
}
|
||||
|
||||
if (free == null) return;
|
||||
foreach (string key in free) {
|
||||
items.Remove(key);
|
||||
access.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MCGalaxy.Util {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy team
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
|
Loading…
x
Reference in New Issue
Block a user