From bedafb8fae9898ef0c5fc6470236ee7244e616a9 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Fri, 27 Mar 2015 19:32:50 -0700
Subject: varregion: refactor use of 'double heightmap[,]' into references to
new class TerrainData and push the implementation from Scene into the
database readers and writers.
---
OpenSim/Data/MSSQL/MSSQLSimulationData.cs | 83 +++++++++++++++++------------
OpenSim/Data/MySQL/MySQLSimulationData.cs | 66 +++++++++++++----------
OpenSim/Data/Null/NullSimulationData.cs | 22 +++++++-
OpenSim/Data/PGSQL/PGSQLSimulationData.cs | 72 +++++++++++++++----------
OpenSim/Data/SQLite/SQLiteSimulationData.cs | 54 +++++++++++--------
5 files changed, 184 insertions(+), 113 deletions(-)
(limited to 'OpenSim/Data')
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index 0d09be6..145b9c0 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -530,43 +530,52 @@ ELSE
///
public double[,] LoadTerrain(UUID regionID)
{
- double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
- terrain.Initialize();
+ double[,] ret = null;
+ TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
+ if (terrData != null)
+ ret = terrData.GetDoubles();
+ return ret;
+ }
+
+ // Returns 'null' if region not found
+ public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
+ {
+ TerrainData terrData = null;
string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
using (SqlConnection conn = new SqlConnection(m_connectionString))
- using (SqlCommand cmd = new SqlCommand(sql, conn))
{
- // MySqlParameter param = new MySqlParameter();
- cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
- conn.Open();
- using (SqlDataReader reader = cmd.ExecuteReader())
+ using (SqlCommand cmd = new SqlCommand(sql, conn))
{
- int rev;
- if (reader.Read())
+ // MySqlParameter param = new MySqlParameter();
+ cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
+ conn.Open();
+ using (SqlDataReader reader = cmd.ExecuteReader())
{
- MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
- BinaryReader br = new BinaryReader(str);
- for (int x = 0; x < (int)Constants.RegionSize; x++)
+ if (reader.Read())
{
- for (int y = 0; y < (int)Constants.RegionSize; y++)
- {
- terrain[x, y] = br.ReadDouble();
- }
+ int rev = (int)reader["Revision"];
+ byte[] blob = (byte[])reader["Heightfield"];
+ terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
- rev = (int)reader["Revision"];
- }
- else
- {
- _Log.Info("[REGION DB]: No terrain found for region");
- return null;
+ else
+ {
+ _Log.Info("[REGION DB]: No terrain found for region");
+ return null;
+ }
+ _Log.Info("[REGION DB]: Loaded terrain");
}
- _Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
}
}
- return terrain;
+ return terrData;
+ }
+
+ // Legacy entry point for when terrain was always a 256x256 hieghtmap
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ StoreTerrain(new HeightmapTerrainData(ter), regionID);
}
///
@@ -574,10 +583,8 @@ ELSE
///
/// terrain map data.
/// regionID.
- public void StoreTerrain(double[,] terrain, UUID regionID)
+ public void StoreTerrain(TerrainData terrData, UUID regionID)
{
- int revision = Util.UnixTimeSinceEpoch();
-
//Delete old terrain map
string sql = "delete from terrain where RegionUUID=@RegionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -590,17 +597,23 @@ ELSE
sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
+ int terrainDBRevision;
+ Array terrainDBblob;
+ terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
+
using (SqlConnection conn = new SqlConnection(m_connectionString))
- using (SqlCommand cmd = new SqlCommand(sql, conn))
{
- cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
- cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision));
- cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain)));
- conn.Open();
- cmd.ExecuteNonQuery();
+ using (SqlCommand cmd = new SqlCommand(sql, conn))
+ {
+ cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
+ cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
+ cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
+ conn.Open();
+ cmd.ExecuteNonQuery();
+ }
}
- _Log.Info("[REGION DB]: Stored terrain revision r " + revision);
+ _Log.Info("[REGION DB]: Stored terrain");
}
///
@@ -1344,6 +1357,7 @@ VALUES
#region Private Methods
+ /*
///
/// Serializes the terrain data for storage in DB.
///
@@ -1367,6 +1381,7 @@ VALUES
return str.ToArray();
}
+ */
///
/// Stores new regionsettings.
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index cc844ae..f910e44 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -48,8 +48,18 @@ namespace OpenSim.Data.MySQL
public class MySQLSimulationData : ISimulationDataStore
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static string LogHeader = "[REGION DB MYSQL]";
private string m_connectionString;
+
+ ///
+ /// This lock was being used to serialize database operations when the connection was shared, but this has
+ /// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead.
+ /// FIXME: However, the locks remain in many places since they are effectively providing a level of
+ /// transactionality. This should be replaced by more efficient database transactions which would not require
+ /// unrelated operations to block each other or unrelated operations on the same tables from blocking each
+ /// other.
+ ///
private object m_dbLock = new object();
protected virtual Assembly Assembly
@@ -91,7 +101,7 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message);
+ m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
throw;
}
@@ -574,12 +584,16 @@ namespace OpenSim.Data.MySQL
}
}
- public virtual void StoreTerrain(double[,] ter, UUID regionID)
+ // Legacy entry point for when terrain was always a 256x256 hieghtmap
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ StoreTerrain(new HeightmapTerrainData(ter), regionID);
+ }
+
+ public void StoreTerrain(TerrainData terrData, UUID regionID)
{
Util.FireAndForget(delegate(object x)
{
- double[,] oldTerrain = LoadTerrain(regionID);
-
m_log.Info("[REGION DB]: Storing terrain");
lock (m_dbLock)
@@ -601,8 +615,12 @@ namespace OpenSim.Data.MySQL
"Revision, Heightfield) values (?RegionUUID, " +
"1, ?Heightfield)";
- cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
- cmd2.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter, oldTerrain));
+ int terrainDBRevision;
+ Array terrainDBblob;
+ terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
+
+ cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
+ cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd2);
@@ -618,9 +636,20 @@ namespace OpenSim.Data.MySQL
});
}
+ // Legacy region loading
public virtual double[,] LoadTerrain(UUID regionID)
{
- double[,] terrain = null;
+ double[,] ret = null;
+ TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
+ if (terrData != null)
+ ret = terrData.GetDoubles();
+ return ret;
+ }
+
+ // Returns 'null' if region not found
+ public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
+ {
+ TerrainData terrData = null;
lock (m_dbLock)
{
@@ -640,32 +669,15 @@ namespace OpenSim.Data.MySQL
while (reader.Read())
{
int rev = Convert.ToInt32(reader["Revision"]);
-
- terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
- terrain.Initialize();
-
- using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
- {
- using (BinaryReader br = new BinaryReader(mstr))
- {
- for (int x = 0; x < (int)Constants.RegionSize; x++)
- {
- for (int y = 0; y < (int)Constants.RegionSize; y++)
- {
- terrain[x, y] = br.ReadDouble();
- }
- }
- }
-
- m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
- }
+ byte[] blob = (byte[])reader["Heightfield"];
+ terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
}
}
}
}
- return terrain;
+ return terrData;
}
public virtual void RemoveLandObject(UUID globalID)
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index 15824a9..339e7f4 100644
--- a/OpenSim/Data/Null/NullSimulationData.cs
+++ b/OpenSim/Data/Null/NullSimulationData.cs
@@ -132,18 +132,36 @@ namespace OpenSim.Data.Null
return new List();
}
- Dictionary m_terrains = new Dictionary();
- public void StoreTerrain(double[,] ter, UUID regionID)
+ Dictionary m_terrains = new Dictionary();
+ public void StoreTerrain(TerrainData ter, UUID regionID)
{
if (m_terrains.ContainsKey(regionID))
m_terrains.Remove(regionID);
m_terrains.Add(regionID, ter);
}
+ // Legacy. Just don't do this.
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ TerrainData terrData = new HeightmapTerrainData(ter);
+ StoreTerrain(terrData, regionID);
+ }
+
+ // Legacy. Just don't do this.
+ // Returns 'null' if region not found
public double[,] LoadTerrain(UUID regionID)
{
if (m_terrains.ContainsKey(regionID))
{
+ return m_terrains[regionID].GetDoubles();
+ }
+ return null;
+ }
+
+ public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
+ {
+ if (m_terrains.ContainsKey(regionID))
+ {
return m_terrains[regionID];
}
return null;
diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
index 3243635..cd02e05 100644
--- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
+++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Data.PGSQL
public class PGSQLSimulationData : ISimulationDataStore
{
private const string _migrationStore = "RegionStore";
+ private const string LogHeader = "[REGION DB PGSQL]";
// private static FileSystemDataStore Instance = new FileSystemDataStore();
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -523,8 +524,17 @@ namespace OpenSim.Data.PGSQL
///
public double[,] LoadTerrain(UUID regionID)
{
- double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
- terrain.Initialize();
+ double[,] ret = null;
+ TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
+ if (terrData != null)
+ ret = terrData.GetDoubles();
+ return ret;
+ }
+
+ // Returns 'null' if region not found
+ public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
+ {
+ TerrainData terrData = null;
string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain
where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; ";
@@ -540,16 +550,9 @@ namespace OpenSim.Data.PGSQL
int rev;
if (reader.Read())
{
- MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
- BinaryReader br = new BinaryReader(str);
- for (int x = 0; x < (int)Constants.RegionSize; x++)
- {
- for (int y = 0; y < (int)Constants.RegionSize; y++)
- {
- terrain[x, y] = br.ReadDouble();
- }
- }
- rev = (int)reader["Revision"];
+ rev = Convert.ToInt32(reader["Revision"]);
+ byte[] blob = (byte[])reader["Heightfield"];
+ terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
else
{
@@ -560,7 +563,13 @@ namespace OpenSim.Data.PGSQL
}
}
- return terrain;
+ return terrData;
+ }
+
+ // Legacy entry point for when terrain was always a 256x256 heightmap
+ public void StoreTerrain(double[,] terrain, UUID regionID)
+ {
+ StoreTerrain(new HeightmapTerrainData(terrain), regionID);
}
///
@@ -568,35 +577,38 @@ namespace OpenSim.Data.PGSQL
///
/// terrain map data.
/// regionID.
- public void StoreTerrain(double[,] terrain, UUID regionID)
+ public void StoreTerrain(TerrainData terrData, UUID regionID)
{
- int revision = Util.UnixTimeSinceEpoch();
-
//Delete old terrain map
string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
- using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
- cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
- conn.Open();
- cmd.ExecuteNonQuery();
+ using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
+ {
+ cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
+ conn.Open();
+ cmd.ExecuteNonQuery();
+ }
}
-
- _Log.Info("[REGION DB]: Deleted terrain revision r " + revision);
+ int terrainDBRevision;
+ Array terrainDBblob;
+ terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
- using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
- cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
- cmd.Parameters.Add(_Database.CreateParameter("Revision", revision));
- cmd.Parameters.Add(_Database.CreateParameter("Heightfield", serializeTerrain(terrain)));
- conn.Open();
- cmd.ExecuteNonQuery();
+ using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
+ {
+ cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
+ cmd.Parameters.Add(_Database.CreateParameter("Revision", terrainDBRevision));
+ cmd.Parameters.Add(_Database.CreateParameter("Heightfield", terrainDBblob));
+ conn.Open();
+ cmd.ExecuteNonQuery();
+ }
}
- _Log.Info("[REGION DB]: Stored terrain revision r " + revision);
+ _Log.Info("[REGION DB]: Stored terrain revision r " + terrainDBRevision);
}
///
@@ -1349,6 +1361,7 @@ namespace OpenSim.Data.PGSQL
#region Private Methods
+ /*
///
/// Serializes the terrain data for storage in DB.
///
@@ -1372,6 +1385,7 @@ namespace OpenSim.Data.PGSQL
return str.ToArray();
}
+ */
///
/// Stores new regionsettings.
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
index 4d6a80a..d28c227 100644
--- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
@@ -51,6 +51,7 @@ namespace OpenSim.Data.SQLite
public class SQLiteSimulationData : ISimulationDataStore
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly string LogHeader = "[REGION DB SQLLITE]";
private const string primSelect = "select * from prims";
private const string shapeSelect = "select * from primshapes";
@@ -819,12 +820,18 @@ namespace OpenSim.Data.SQLite
prim.Inventory.RestoreInventoryItems(inventory);
}
+ // Legacy entry point for when terrain was always a 256x256 hieghtmap
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ StoreTerrain(new HeightmapTerrainData(ter), regionID);
+ }
+
///
/// Store a terrain revision in region storage
///
/// terrain heightfield
/// region UUID
- public void StoreTerrain(double[,] ter, UUID regionID)
+ public void StoreTerrain(TerrainData terrData, UUID regionID)
{
lock (ds)
{
@@ -853,11 +860,17 @@ namespace OpenSim.Data.SQLite
String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
" values(:RegionUUID, :Revision, :Heightfield)";
+ int terrainDBRevision;
+ Array terrainDBblob;
+ terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
+
+ m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision);
+
using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
{
cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
- cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
- cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
+ cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
+ cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
cmd.ExecuteNonQuery();
}
}
@@ -870,11 +883,20 @@ namespace OpenSim.Data.SQLite
/// Heightfield data
public double[,] LoadTerrain(UUID regionID)
{
+ double[,] ret = null;
+ TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
+ if (terrData != null)
+ ret = terrData.GetDoubles();
+ return ret;
+ }
+
+ // Returns 'null' if region not found
+ public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
+ {
+ TerrainData terrData = null;
+
lock (ds)
{
- double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
- terret.Initialize();
-
String sql = "select RegionUUID, Revision, Heightfield from terrain" +
" where RegionUUID=:RegionUUID order by Revision desc";
@@ -887,21 +909,9 @@ namespace OpenSim.Data.SQLite
int rev = 0;
if (row.Read())
{
- // TODO: put this into a function
- using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
- {
- using (BinaryReader br = new BinaryReader(str))
- {
- for (int x = 0; x < (int)Constants.RegionSize; x++)
- {
- for (int y = 0; y < (int)Constants.RegionSize; y++)
- {
- terret[x, y] = br.ReadDouble();
- }
- }
- }
- }
rev = Convert.ToInt32(row["Revision"]);
+ byte[] blob = (byte[])row["Heightfield"];
+ terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
else
{
@@ -912,8 +922,8 @@ namespace OpenSim.Data.SQLite
m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
}
}
- return terret;
}
+ return terrData;
}
public void RemoveLandObject(UUID globalID)
@@ -2016,6 +2026,7 @@ namespace OpenSim.Data.SQLite
return entry;
}
+ /*
///
///
///
@@ -2033,6 +2044,7 @@ namespace OpenSim.Data.SQLite
return str.ToArray();
}
+ */
// private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
// {
--
cgit v1.1
From 08c72a8dc1e54114559521a6c2952905ecf6f105 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sat, 28 Mar 2015 07:50:04 -0700
Subject: varregion: remove use of Constants.RegionSize is various places. More
use of the Util routines for conversion of region handles into addresses.
---
OpenSim/Data/IRegionData.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'OpenSim/Data')
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs
index 463c621..ca9b327 100644
--- a/OpenSim/Data/IRegionData.cs
+++ b/OpenSim/Data/IRegionData.cs
@@ -52,14 +52,14 @@ namespace OpenSim.Data
public int sizeY;
///
- /// Return the x-coordinate of this region.
+ /// Return the x-coordinate of this region in region units.
///
- public int coordX { get { return posX / (int)Constants.RegionSize; } }
+ public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
///
- /// Return the y-coordinate of this region.
+ /// Return the y-coordinate of this region in region units.
///
- public int coordY { get { return posY / (int)Constants.RegionSize; } }
+ public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
public Dictionary Data;
}
--
cgit v1.1