-
Notifications
You must be signed in to change notification settings - Fork 114
Add deterministic asset id generation process for asset caches. #264
Conversation
@@ -59,6 +59,8 @@ protected override TextMeshProBroadcasterChangeType CalculateDeltaChanges() | |||
|
|||
protected override void SendCompleteChanges(IEnumerable<SocketEndpoint> endpoints) | |||
{ | |||
previousText = this.textMesh.text; | |||
previousProperties = new TextMeshProperties(textMesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was some weird behavior here where font details were sent prior to populating on this first call to SendCompleteChanges
da96fe6
to
6448530
Compare
daf2b36
to
75c1fe1
Compare
dd422d1
to
07dadf2
Compare
m_storage: 74fae14d-39c0-497e-ae6d-72f1f2084231 | ||
Asset: {fileID: 21300000, guid: d651fc00b471cfe44834a222e9433461, type: 3} | ||
guid: | ||
m_storage: 00000000-0000-0000-f000-000000000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
00000000-0000-0000-f000-000000000000 [](start = 19, length = 36)
This GUID seems to be strannnnnnnnnnngely full of zeros - is it just the case that some portion of our deterministic guids are going to look like this?
It's just interesting seeing a bunch of other GUIDs that look like regular GUIDs, and then seeing this guid (and the c000 one) which looks like a bunch of zeroes that then got smashed by a cosmic ray.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen guids like this for Unity's default assets. Things like cube and cone meshes have similar guids.
} | ||
} | ||
|
||
CleanUpUnused(oldAssets, unvisitedAssets); | ||
assets = oldAssets.Values.ToArray(); | ||
assets = oldAssets.Values.OrderBy(x => x.AssetId.FileIdentifier).ThenBy(x => x.AssetId.Guid).ToArray(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OrderBy(x => x.AssetId.FileIdentifier).ThenBy(x => x.AssetId.Guid) [](start = 38, length = 66)
If we're changing the mechanics of how our assets are enumerated (i.e. the EnumerateAllAssets). it might be worth documenting in the surfaces where this is exposed (i.e. EnumerateAllAssets will enumerate assets on File Identifier and then Guid)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't we want to orderby Guid first, then file Id? As Guid represents the file, and fileId is the id within that file
[SerializeField] | ||
private StringGuid guid; | ||
|
||
public long FileIdentifier => fileIdentifier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FileIdentifier [](start = 20, length = 14)
Can you add a comment about what "FileIdentifier" is?
It's possible that this location isn't the right place for the comment (i.e. it's somewhat abstract at this location) but I'm trying to get a little more clarity for a reader who sees an abstract number (i.e. file ID), then look at this code, and ideally there should be some explanation/direction that this point that guides them to what's up
src/SpectatorView.Unity/Assets/SpectatorView/Scripts/StateSynchronization/AssetCacheEntry.cs
Show resolved
Hide resolved
src/SpectatorView.Unity/Assets/SpectatorView/Scripts/StateSynchronization/AssetCacheEntry.cs
Show resolved
Hide resolved
Now that I'm seeing this in two places, what's the significance of "D"? Is it just a sentinel string (i.e. "private static string INVALID_GUID = "D"?) Refers to: src/SpectatorView.Unity/Assets/SpectatorView/Scripts/StateSynchronization/StringGuid.cs:17 in 07dadf2. [](commit_id = 07dadf2, deletion_comment = False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
public override int GetHashCode() | ||
{ | ||
return FileIdentifier.GetHashCode() ^ Guid.ToString().GetHashCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will do an allocation everytime you add to the dictionary, because GetHashCode is called, which will create a string from Guid.
Instead, just do Guid.GetHashCode().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I'll pick these changes up in stabilization/1.1.0 with the expectation to merge back into master
} | ||
|
||
public static bool operator ==(AssetId lhs, AssetId rhs) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would simplify this to: Equals(lhs, rhs); which would propogate to your Equals override above.
I would update that method to not use this one, as you already did a null check, and "this" can't be null. So just compare Guid and FileIndentierifer.
Also, don't do Guid.ToString() for comparison, just compare Guids. Guid.Tostring() is an allocation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, what aspect of Guid.ToString() is an allocation? StringGuid has a custom ToString definition that just returns the internally stored string value for the Guid. I'm not 100% if historically this type was made for serializtion, but we aren't currently using the default Guid type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public override string ToString()
{
return (m_storage == null) ? System.Guid.Empty.ToString("D") : m_storage;
}
Now looking at:
https://github.com/microsoft/referencesource/blob/master/mscorlib/system/guid.cs
if (formatCh == 'D' || formatCh == 'd') {
guidString = string.FastAllocateString(36);
}
Looks like there is no special-casing for an empty guid, unless I missed it.
@@ -7,7 +7,7 @@ | |||
namespace Microsoft.MixedReality.SpectatorView | |||
{ | |||
[Serializable] | |||
internal class StringGuid | |||
internal class StringGuid : IComparable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StringGuid [](start = 19, length = 10)
Out of curiosity, what's wrong with the ordinary GUID? It's already comparable, and should be way faster to work with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure historically why the GUID wasn't used. is a GUID serializable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs say that it has SerializableAttribute, so it should be.
I'm genuinely curious why the string representation was chosen instead. Maybe there was some issue with the Unity integration?
This review addresses: #47. It contains the following changes:
Breaking Change Details:
Notes:
StringGuid keys for asset caches have been updated to AssetIds so that they can be deterministically created on different computers. This will break old AssetCaches.
Migration Instructions:
Spectator View -> Update All Asset Caches
in your project to regenerate asset caches.