Burstable BlobString Compare

So I am attempting to compare two different blobs’ strings together, and was hoping to do this in a bursted job; however, the compiler is not allowing me to utilize the BlobString due to the MayOnlyLiveInBlobStorage attribute. Note, I don’t need to mutate the string, merely check if it matches a constant. My attempt revolved around creating a BlobSingletonComponent upon System creation for the context I am looking for, then try to check equals to the other when in the job.

ref var blobRef = ref component.BlobReference.Value;
ref var contextBlobRef = ref contextBlob.Value;

ref var context = ref blobRef.Context;
ref var context2 = ref contextBlobRef.Context;

if (context2.Equals(context)) { }
1 Like

Did you ever find a solution for this? I saw in another thread that you started to use FixedString in blobs. It seems to me that there should be a way to compare BlobString with a FixedString in Burst.

I want to do something like:

public struct MyBlob
{
    public BlobString MyValue;
    // this won't work :-(
    public bool CompareToMyValue(FixedString128Bytes val)
    {
        return val.CompareTo(MyValue);
    }
}

While it will involve allocation, you can do return val.CompareTo(MyValue.ToString()); Also, this would return int, as its a comparison. Equals would return bool (although they would only equal if the BlobString was also 128 bytes, and equal).

To do this without allocation, if you can get a byte* pointer to the BlobString (via BlobAssetReference?), then you will be able to compare less/equal/more for each character with your own CompareTo method.

I don’t know much about Blobs, but if it was via BlobAssetReference, then for reference:

            BlobAssetReference<BlobString> blobString = new BlobAssetReference<BlobString>();
            FixedString128Bytes fixedString = new FixedString128Bytes();
            byte* blobStringPtr = (byte*)blobString.GetUnsafePtr();
            byte* fixedStringPtr = fixedString.GetUnsafePtr();

Now you can make your own Equals or CompareTo method, but will also need to use the lengths.

1 Like
public static class BlobStringEx
{
    public static unsafe bool StringEquals(this ref BlobString str, ref BlobString other)
    {
        fixed (void* strPtr = &str, otherPtr = &other)
        {
            return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes((byte*)((BlobArray<byte>*)strPtr)->GetUnsafePtr(), str.Length, (byte*)((BlobArray<byte>*)otherPtr)->GetUnsafePtr(), other.Length);
        }
    }

    public static unsafe bool StringEquals<T>(this ref BlobString str, in T other) where T : unmanaged, INativeList<byte>, IUTF8Bytes
    {
        fixed (void* strPtr = &str)
        {
            return UTF8ArrayUnsafeUtility.EqualsUTF8Bytes((byte*)((BlobArray<byte>*)strPtr)->GetUnsafePtr(), str.Length, (byte*)other.GetUnsafePtr(), other.Length);
        }
    }

    public static unsafe bool StringEquals(this ref BlobString str, string other)
    {
        fixed (void* strPtr = &str, otherPtr = other)
        {
            return UTF8ArrayUnsafeUtility.StrCmp((byte*)((BlobArray<byte>*)strPtr)->GetUnsafePtr(), str.Length, (char*)otherPtr, other.Length) == 0;
        }
    }
}
2 Likes

I can’t use ToString() because Burst will complain, but getting the unsafe pointer seems like it might work, assuming they both store their characters using the same encodings and format. Thanks!

Thanks! I didn’t know about UTF8ArrayUnsafeUtility! I think that will work as long as the strings are both stored as UTF8.