From a5c7067026de9f06b8e10a1abbd70684d66a1324 Mon Sep 17 00:00:00 2001 From: jenz Date: Thu, 11 Aug 2022 16:05:18 +0200 Subject: [PATCH] added alter table statements for adding and removing indexes when maps are loaded. THis way i avoid mysql's limit of 64 indexes per table. the toptimes and own times can now be displayed very quickly ingame. ONly exception is if dev/ze2/ze play the same map because mapStart and MapEnd add and remove the indexes. So if dev/ze/ or ze2/ze play the same map then the first server leaving the map will delete the index again --- RaceTimer/scripting/unloze_racetimer_redux.sp | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/RaceTimer/scripting/unloze_racetimer_redux.sp b/RaceTimer/scripting/unloze_racetimer_redux.sp index da613d3d..51461c2d 100644 --- a/RaceTimer/scripting/unloze_racetimer_redux.sp +++ b/RaceTimer/scripting/unloze_racetimer_redux.sp @@ -65,6 +65,12 @@ public void OnPluginStart() HookEntityOutput("trigger_multiple", "OnStartTouch", Trigger_Multiple); HookEntityOutput("trigger_teleport", "OnTrigger", trigger_teleport); HookEntityOutput("trigger_teleport", "OnStartTouch", trigger_teleport); + //DB + if (!g_dDatabase) + { + Database.Connect(SQL_OnDatabaseConnect, "racetimercss"); + } + //HUD hText = CreateHudSynchronizer(); //Just constantly reruns the alter table query to handle new zones, less lazy solution would just be adding a forward for when zones were renamed @@ -184,6 +190,7 @@ public void SQL_OnConnectFinished(Database db, DBResultSet results, const char[] for(int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) OnClientPostAdminCheck(i); + AddBinarySearchIndex(); } public void MYSQLCheckMapEntry() @@ -228,12 +235,79 @@ public void SQL_FinishedQuery(Database db, DBResultSet results, const char[] err delete data; } +//a mysql table can max have 64 keys attached to it without recompiling. Therefore dropping and attaching binary tree index on the given map start, map end, +//PluginStart Database connection and PluginEnd. +//Adding and removing indexes should be pretty cheap so creating/removing them for only the specific map should be ok +//also check that racezones actually exist before making a binary tree index +//also handles if the column ends with just mapname or with mapnameS1, mapnameS2 etc etc +//its only relevant for sourcemod scripting part, the java backend making rest endpoints uses a cache and does select * statements so it does not need indexing +public void AddBinarySearchIndex() +{ + int race_zone_count = GetTotalRaceZones(); + int l_iZoneCount = unloze_zoneCount(); + char sQuery[g_dLength]; + GetCurrentMap(g_cMapname, sizeof(g_cMapname)); + //if admins dont make dumb random zones without any meaning it works fine + if (race_zone_count == 1 && l_iZoneCount == 1) + { + Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table_new` add INDEX if not exists `%s` (`%s`)", g_cMapname, g_cMapname); + DataPack hDataPack = new DataPack(); + hDataPack.WriteString(sQuery); + g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_High); + } + else + { + for (int i = 1; i <= race_zone_count; i++) + { + Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table_new` add INDEX if not exists `%sS%i` (`%sS%i`)", g_cMapname, i, g_cMapname, i); + DataPack hDataPack = new DataPack(); + hDataPack.WriteString(sQuery); + g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_High); + } + } +} + +//if ze1 and ze2 both play the same map and one leaves the map then the other will not have index anymore, but otherwise its fine. +public void RemoveBinarySearchIndex() +{ + char sQuery[g_dLength]; + int race_zone_count = GetTotalRaceZones(); + int l_iZoneCount = unloze_zoneCount(); + GetCurrentMap(g_cMapname, sizeof(g_cMapname)); + if (race_zone_count == 1 && l_iZoneCount == 1) + { + Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table_new` drop INDEX if exists `%s`", g_cMapname); + DataPack hDataPack = new DataPack(); + hDataPack.WriteString(sQuery); + g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_High); + } + else + { + for (int i = 1; i <= race_zone_count; i++) + { + Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table_new` drop INDEX if exists `%sS%i`", g_cMapname, i); + DataPack hDataPack = new DataPack(); + hDataPack.WriteString(sQuery); + g_dDatabase.Query(SQL_FinishedQuery, sQuery, hDataPack, DBPrio_High); + } + } +} + +public void OnMapEnd() +{ + if (!g_dDatabase) + Database.Connect(SQL_OnDatabaseConnect, "racetimercss"); + else + RemoveBinarySearchIndex(); +} + public void OnMapStart() { if (!g_dDatabase) Database.Connect(SQL_OnDatabaseConnect, "racetimercss"); else { + AddBinarySearchIndex(); static Handle hHostName; if((hHostName = FindConVar("hostname")) == INVALID_HANDLE) return; @@ -258,6 +332,7 @@ public void OnPluginEnd() CloseHandle(hText); if (g_hAlterTableTimer != null) delete g_hAlterTableTimer; + RemoveBinarySearchIndex(); } //---------------------------------------------------------------------------------------------------- // Purpose: