mirror of
https://github.com/opensim/opensim.git
synced 2026-08-10 11:33:28 +08:00
Added assets service method AssetsExist(), which returns whether the given list of assets exist.
This method is used to optimize sending assets with embedded assets: e.g., when a Hypergrid visitor takes an item into the inventory.
This commit is contained in:
@@ -153,9 +153,24 @@ namespace OpenSim.Services.AssetService
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool[] AssetsExist(string[] ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
|
||||
return m_Database.AssetsExist(uuid);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[ASSET SERVICE]: Exception getting assets ", e);
|
||||
return new bool[ids.Length];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string Store(AssetBase asset)
|
||||
{
|
||||
if (!m_Database.ExistsAsset(asset.FullID))
|
||||
bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
|
||||
if (!exists)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
||||
@@ -186,4 +201,4 @@ namespace OpenSim.Services.AssetService
|
||||
return m_Database.Delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,9 +175,16 @@ namespace OpenSim.Services.AssetService
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool[] AssetsExist(string[] ids)
|
||||
{
|
||||
UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
|
||||
return m_Database.AssetsExist(uuid);
|
||||
}
|
||||
|
||||
public virtual string Store(AssetBase asset)
|
||||
{
|
||||
if (!m_Database.ExistsAsset(asset.FullID))
|
||||
bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
|
||||
if (!exists)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
||||
@@ -217,4 +224,4 @@ namespace OpenSim.Services.AssetService
|
||||
m_ChainedAssetService.Delete(asset.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,6 +254,27 @@ namespace OpenSim.Services.Connectors
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool[] AssetsExist(string[] ids)
|
||||
{
|
||||
string uri = m_ServerURI + "/get_assets_exist";
|
||||
|
||||
bool[] exist = null;
|
||||
try
|
||||
{
|
||||
exist = SynchronousRestObjectRequester.MakeRequest<string[], bool[]>("POST", uri, ids);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// This is most likely to happen because the server doesn't support this function,
|
||||
// so just silently return "doesn't exist" for all the assets.
|
||||
}
|
||||
|
||||
if (exist == null)
|
||||
exist = new bool[ids.Length];
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
public string Store(AssetBase asset)
|
||||
{
|
||||
if (asset.Local)
|
||||
|
||||
@@ -36,6 +36,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using OpenSim.Services.Connectors.SimianGrid;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Services.Connectors
|
||||
{
|
||||
@@ -83,39 +84,6 @@ namespace OpenSim.Services.Connectors
|
||||
}
|
||||
}
|
||||
|
||||
private bool StringToUrlAndAssetID(string id, out string url, out string assetID)
|
||||
{
|
||||
url = String.Empty;
|
||||
assetID = String.Empty;
|
||||
|
||||
Uri assetUri;
|
||||
|
||||
if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) &&
|
||||
assetUri.Scheme == Uri.UriSchemeHttp)
|
||||
{
|
||||
// Simian
|
||||
if (assetUri.Query != string.Empty)
|
||||
{
|
||||
NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
|
||||
assetID = qscoll["id"];
|
||||
if (assetID != null)
|
||||
url = id.Replace(assetID, ""); // Malformed again, as simian expects
|
||||
else
|
||||
url = id; // !!! best effort
|
||||
}
|
||||
else // robust
|
||||
{
|
||||
url = "http://" + assetUri.Authority;
|
||||
assetID = assetUri.LocalPath.Trim(new char[] { '/' });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[HG ASSET SERVICE]: Malformed URL {0}", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
private IAssetService GetConnector(string url)
|
||||
{
|
||||
IAssetService connector = null;
|
||||
@@ -149,7 +117,7 @@ namespace OpenSim.Services.Connectors
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
||||
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
return connector.Get(assetID);
|
||||
@@ -163,7 +131,7 @@ namespace OpenSim.Services.Connectors
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
||||
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
return connector.GetCached(assetID);
|
||||
@@ -177,7 +145,7 @@ namespace OpenSim.Services.Connectors
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
||||
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
return connector.GetMetadata(assetID);
|
||||
@@ -196,7 +164,7 @@ namespace OpenSim.Services.Connectors
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
||||
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
return connector.Get(assetID, sender, handler);
|
||||
@@ -205,12 +173,72 @@ namespace OpenSim.Services.Connectors
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private struct AssetAndIndex
|
||||
{
|
||||
public UUID assetID;
|
||||
public int index;
|
||||
|
||||
public AssetAndIndex(UUID assetID, int index)
|
||||
{
|
||||
this.assetID = assetID;
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool[] AssetsExist(string[] ids)
|
||||
{
|
||||
// This method is a bit complicated because it works even if the assets belong to different
|
||||
// servers; that requires sending separate requests to each server.
|
||||
|
||||
// Group the assets by the server they belong to
|
||||
|
||||
var url2assets = new Dictionary<string, List<AssetAndIndex>>();
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (Util.ParseForeignAssetID(ids[i], out url, out assetID))
|
||||
{
|
||||
if (!url2assets.ContainsKey(url))
|
||||
url2assets.Add(url, new List<AssetAndIndex>());
|
||||
url2assets[url].Add(new AssetAndIndex(UUID.Parse(assetID), i));
|
||||
}
|
||||
}
|
||||
|
||||
// Query each of the servers in turn
|
||||
|
||||
bool[] exist = new bool[ids.Length];
|
||||
|
||||
foreach (string url in url2assets.Keys)
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
lock (EndPointLock(connector))
|
||||
{
|
||||
List<AssetAndIndex> curAssets = url2assets[url];
|
||||
string[] assetIDs = curAssets.ConvertAll(a => a.assetID.ToString()).ToArray();
|
||||
bool[] curExist = connector.AssetsExist(assetIDs);
|
||||
|
||||
int i = 0;
|
||||
foreach (AssetAndIndex ai in curAssets)
|
||||
{
|
||||
exist[ai.index] = curExist[i];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
public string Store(AssetBase asset)
|
||||
{
|
||||
string url = string.Empty;
|
||||
string assetID = string.Empty;
|
||||
|
||||
if (StringToUrlAndAssetID(asset.ID, out url, out assetID))
|
||||
if (Util.ParseForeignAssetID(asset.ID, out url, out assetID))
|
||||
{
|
||||
IAssetService connector = GetConnector(url);
|
||||
// Restore the assetID to a simple UUID
|
||||
|
||||
@@ -231,6 +231,26 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool[] AssetsExist(string[] ids)
|
||||
{
|
||||
if (String.IsNullOrEmpty(m_serverUrl))
|
||||
{
|
||||
m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured");
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
bool[] exist = new bool[ids.Length];
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
AssetMetadata metadata = GetMetadata(ids[i]);
|
||||
if (metadata != null)
|
||||
exist[i] = true;
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new asset
|
||||
/// </summary>
|
||||
|
||||
@@ -75,6 +75,13 @@ namespace OpenSim.Services.Interfaces
|
||||
/// </param>
|
||||
/// <returns>True if the id was parseable, false otherwise</returns>
|
||||
bool Get(string id, Object sender, AssetRetrieved handler);
|
||||
|
||||
/// <summary>
|
||||
/// Check if assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="ids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
bool[] AssetsExist(string[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new asset
|
||||
|
||||
Reference in New Issue
Block a user