Ejemplo n.º 1
0
 void SwapOrRemoveEntityComponents
     (EGID fromEntityGID, EGID?toEntityGID, IComponentBuilder[] entitiesToMove
     , FasterDictionary <RefWrapperType, ITypeSafeDictionary> fromGroup, in PlatformProfiler sampler)
Ejemplo n.º 2
0
 public FasterDictionaryKeyValueEnumerator(FasterDictionary <TKey, TValue> dic) : this()
 {
     _dic   = dic;
     _index = -1;
     _count = dic.Count;
 }
Ejemplo n.º 3
0
 internal FasterDictionaryKeys(FasterDictionary <TKey, TValue> dic) : this()
 {
 }
 void MoveEntityViewFromAndToEngines(EGID entityGID, EGID?toEntityGID,
                                     FasterDictionary <RefWrapper <Type>, ITypeSafeDictionary> fromGroup,
                                     FasterDictionary <RefWrapper <Type>, ITypeSafeDictionary> toGroup, Type entityViewType,
                                     in PlatformProfiler profiler)
Ejemplo n.º 5
0
        public LocalFasterReadOnlyList <ExclusiveGroupStruct> FindGroups <T1, T2, T3, T4>()
            where T1 : IEntityComponent
            where T2 : IEntityComponent
            where T3 : IEntityComponent
            where T4 : IEntityComponent
        {
            FasterList <FasterDictionary <ExclusiveGroupStruct, ITypeSafeDictionary> > localArray =
                localgroups.Value.listOfGroups;

            if (groupsPerEntity.TryGetValue(TypeRefWrapper <T1> .wrapper, out localArray[0]) == false || localArray[0].count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }
            if (groupsPerEntity.TryGetValue(TypeRefWrapper <T2> .wrapper, out localArray[1]) == false || localArray[1].count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }
            if (groupsPerEntity.TryGetValue(TypeRefWrapper <T3> .wrapper, out localArray[2]) == false || localArray[2].count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }
            if (groupsPerEntity.TryGetValue(TypeRefWrapper <T4> .wrapper, out localArray[3]) == false || localArray[3].count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }

            localgroups.Value.groups.FastClear();

            FasterDictionary <ExclusiveGroupStruct, ExclusiveGroupStruct> localGroups = localgroups.Value.groups;

            int startIndex = 0;
            int min        = int.MaxValue;

            for (int i = 0; i < 4; i++)
            {
                if (localArray[i].count < min)
                {
                    min        = localArray[i].count;
                    startIndex = i;
                }
            }

            foreach (var value in localArray[startIndex])
            {
                if (value.key.IsEnabled())
                {
                    localGroups.Add(value.key, value.key);
                }
            }

            var groupData = localArray[++startIndex & 3]; //&3 == %4

            localGroups.Intersect(groupData);
            if (localGroups.count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }
            groupData = localArray[++startIndex & 3];
            localGroups.Intersect(groupData);
            if (localGroups.count == 0)
            {
                return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(
                           FasterReadOnlyList <ExclusiveGroupStruct> .DefaultEmptyList));
            }
            groupData = localArray[++startIndex & 3];
            localGroups.Intersect(groupData);

            return(new LocalFasterReadOnlyList <ExclusiveGroupStruct>(localGroups.unsafeValues
                                                                      , (uint)localGroups.count));
        }
        public void TestFasterDictionary()
        {
            FasterDictionary <int, Test> test = new FasterDictionary <int, Test>();
            uint dictionarysize = 10000;

            int[] numbers = new int[dictionarysize];
            for (int i = 1; i < dictionarysize; i++)
            {
                numbers[i] = numbers[i - 1] + i * HashHelpers.Expand((int)dictionarysize);
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                test[i] = new Test(numbers[i]);
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                if (test[i].i != numbers[i])
                {
                    throw new Exception();
                }
            }

            for (int i = 0; i < dictionarysize; i += 2)
            {
                if (test.Remove(i) == false)
                {
                    throw new Exception();
                }
            }

            test.Trim();

            for (int i = 0; i < dictionarysize; i++)
            {
                test[i] = new Test(numbers[i]);
            }

            for (int i = 1; i < dictionarysize - 1; i += 2)
            {
                if (test[i].i != numbers[i])
                {
                    throw new Exception();
                }
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                if (test[i].i != numbers[i])
                {
                    throw new Exception();
                }
            }

            for (int i = (int)(dictionarysize - 1); i >= 0; i -= 3)
            {
                if (test.Remove(i) == false)
                {
                    throw new Exception();
                }
            }

            test.Trim();

            for (int i = (int)(dictionarysize - 1); i >= 0; i -= 3)
            {
                test[i] = new Test(numbers[i]);
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                if (test[i].i != numbers[i])
                {
                    throw new Exception();
                }
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                if (test.Remove(i) == false)
                {
                    throw new Exception();
                }
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                if (test.Remove(i) == true)
                {
                    throw new Exception();
                }
            }

            test.Trim();

            test.Clear();
            for (int i = 0; i < dictionarysize; i++)
            {
                test[numbers[i]] = new Test(i);
            }

            for (int i = 0; i < dictionarysize; i++)
            {
                Test JapaneseCalendar = test[numbers[i]];
                if (JapaneseCalendar.i != i)
                {
                    throw new Exception("read back test failed");
                }
            }
        }
Ejemplo n.º 7
0
 public EntityComponentInitializer(EGID id, FasterDictionary <RefWrapperType, ITypeSafeDictionary> group)
 {
     _group = group;
     _ID    = id;
 }
Ejemplo n.º 8
0
 public EntityInitializer(EGID id, FasterDictionary <RefWrapperType, ITypeSafeDictionary> group,
                          in EntityReference reference)
Ejemplo n.º 9
0
            public bool MoveNext()
            {
                //attention, the while is necessary to skip empty groups
                while (_db.MoveNext() == true)
                {
                    FasterDictionary <ExclusiveGroupStruct, ITypeSafeDictionary> .KeyValuePairFast group = _db.Current;
                    ITypeSafeDictionary <T1> typeSafeDictionary = @group.Value as ITypeSafeDictionary <T1>;

                    if (typeSafeDictionary.count == 0)
                    {
                        continue;
                    }

                    _array.collection = new EntityCollection <T1>(typeSafeDictionary.GetValues(out var count), count);
                    _array.@group     = new ExclusiveGroupStruct(group.Key);

                    return(true);
                }

                return(false);
            }
Ejemplo n.º 10
0
 public LegacyFilters(
     FasterDictionary <RefWrapperType, FasterDictionary <ExclusiveGroupStruct, LegacyGroupFilters> >
     filtersLegacy)
 {
     _filtersLegacy = filtersLegacy;
 }
Ejemplo n.º 11
0
        public void RunGo()
        {
            var words = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.".Split(' ');
            var map   = new NativeFasterDictionary <StringKey, SomeData>(100, Allocator.Persistent);
            var map2  = new NativeFasterDictionary <StringKey, SomeData>(100, Allocator.Persistent);
            var dict  = new Dictionary <StringKey, SomeData>(100);
            var fdict = new FasterDictionary <StringKey, SomeData>(100);

            // I would test this against unity's NativeHashMap except they currently have no ability to set values by key :S

            try
            {
                for (int i = 0; i < words.Length; i++)
                {
                    var key = new StringKey(words[i]);
                    map[key]   = new SomeData();
                    map2[key]  = new SomeData();
                    dict[key]  = new SomeData();
                    fdict[key] = new SomeData();
                }

                var randomKeys = new StringKey[map.Length];
                for (int i = 0; i < map.Length; i++)
                {
                    var idx = UnityEngine.Random.Range(0, map.Length - 1);
                    randomKeys[i] = new StringKey(words[idx]);
                }

                // Fair comparison assigning new value.
                NormalNativeDict(map, randomKeys);

                // Proper version using refs
                NormalNativeDictRef(map2, randomKeys);

                // Note the first time a job runs it's 10x slower.
                BurstJob(randomKeys, map);

                // Svelto's implementation.
                NormalFasterDict(fdict, randomKeys);

                // Stock standard C#
                NormalCSharpDict(dict, randomKeys);

                // Verify that the updates were correctly done
                for (int i = 0; i < words.Length; i++)
                {
                    var key = new StringKey(words[i]);

                    var id1 = map[key].Id;
                    var id2 = map2[key].Id;
                    var id3 = dict[key].Id;
                    var id4 = fdict[key].Id;
                    Debug.Assert(id1 == id2 && id1 == id3 && id1 == id4);

                    var p1 = map[key].Position;
                    var p2 = map2[key].Position;
                    var p3 = dict[key].Position;
                    var p4 = fdict[key].Position;
                    Debug.Assert(p1 == p2 && p1 == p3 && p1 == p4);
                }

                Debug.Log("-----------------------------------------");
            }
            catch (Exception e)
            {
                Debug.Log(e);
                throw;
            }
            finally
            {
                map.Dispose();
                map2.Dispose();
            }
        }
 public TypeSafeDictionary()
 {
     _implementation = new FasterDictionary <uint, TValue>(1);
 }
 public TypeSafeDictionary(uint size)
 {
     _implementation = new FasterDictionary <uint, TValue>(size);
 }
 static void RemoveEntities
     (FasterDictionary <ExclusiveGroupStruct, FasterDictionary <RefWrapperType, FasterList <(uint, string)> > >
 public EntityStructInitializer(EGID id, FasterDictionary <RefWrapper <Type>, ITypeSafeDictionary> group)
 {
     _group = group;
     _ID    = id;
 }
        void AddEntityViewsToTheDBAndSuitableEngines(DoubleBufferedEntitiesToAdd dbgroupsOfEntitiesToSubmit,
                                                     PlatformProfiler profiler)
        {
            //each group is indexed by entity view type. for each type there is a dictionary indexed by entityID
            var groupsOfEntitiesToSubmit = dbgroupsOfEntitiesToSubmit.other;

            foreach (var groupOfEntitiesToSubmit in groupsOfEntitiesToSubmit)
            {
                var groupID = groupOfEntitiesToSubmit.Key;

                if (dbgroupsOfEntitiesToSubmit.otherEntitiesCreatedPerGroup.ContainsKey(groupID) == false)
                {
                    continue;
                }

                //if the group doesn't exist in the current DB let's create it first
                if (_groupEntityDB.TryGetValue(groupID, out var groupDB) == false)
                {
                    groupDB = _groupEntityDB[groupID] = new Dictionary <Type, ITypeSafeDictionary>();
                }

                //add the entityViews in the group
                foreach (var entityViewsToSubmit in groupOfEntitiesToSubmit.Value)
                {
                    var type = entityViewsToSubmit.Key;
                    var typeSafeDictionary = entityViewsToSubmit.Value;

                    if (groupDB.TryGetValue(type, out var dbDic) == false)
                    {
                        dbDic = groupDB[type] = typeSafeDictionary.Create();
                    }

                    //Fill the DB with the entity views generate this frame.
                    dbDic.AddEntitiesFromDictionary(typeSafeDictionary, groupID);

                    if (_groupsPerEntity.TryGetValue(type, out var groupedGroup) == false)
                    {
                        groupedGroup = _groupsPerEntity[type] = new FasterDictionary <uint, ITypeSafeDictionary>();
                    }

                    groupedGroup[groupID] = dbDic;
                }
            }

            //then submit everything in the engines, so that the DB is up to date with all the entity views and struct
            //created by the entity built
            using (profiler.Sample("Add entities to engines"))
            {
                foreach (var groupToSubmit in groupsOfEntitiesToSubmit)
                {
                    var groupID = groupToSubmit.Key;
                    var groupDB = _groupEntityDB[groupID];

                    foreach (var entityViewsPerType in groupToSubmit.Value)
                    {
                        var realDic = groupDB[entityViewsPerType.Key];

                        entityViewsPerType.Value.AddEntitiesToEngines(_reactiveEnginesAddRemove, realDic, ref profiler);
                    }
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Note: unluckily I didn't design the serialization system to be component order independent, so unless
        /// I do something about it, this method cannot be optimized, the logic of the component order must stay
        /// untouched (no reordering, no use of dictionaries). Components order must stay as it comes, as
        /// well as extracomponents order.
        /// Speed, however, is not a big issue for this class, as the data is always composed once per entity descriptor
        /// at static constructor time
        /// </summary>
        /// <returns></returns>
        IComponentBuilder[] Construct(int extraComponentsLength, IComponentBuilder[] extraComponents)
        {
            IComponentBuilder[] MergeLists
                (IComponentBuilder[] startingComponents, IComponentBuilder[] newComponents, int newComponentsLength)
            {
                var startComponents =
                    new FasterDictionary <RefWrapper <IComponentBuilder, ComponentBuilderComparer>, IComponentBuilder>();
                var xtraComponents =
                    new FasterDictionary <RefWrapper <IComponentBuilder, ComponentBuilderComparer>, IComponentBuilder>();

                for (uint i = 0; i < startingComponents.Length; i++)
                {
                    startComponents
                    [new RefWrapper <IComponentBuilder, ComponentBuilderComparer>(startingComponents[i])] =
                        startingComponents[i];
                }

                for (uint i = 0; i < newComponentsLength; i++)
                {
                    xtraComponents[new RefWrapper <IComponentBuilder, ComponentBuilderComparer>(newComponents[i])] =
                        newComponents[i];
                }

                xtraComponents.Exclude(startComponents);

                if (newComponentsLength != xtraComponents.count)
                {
                    newComponentsLength = xtraComponents.count;

                    uint index = 0;
                    foreach (var couple in xtraComponents)
                    {
                        newComponents[index++] = couple.key.type;
                    }
                }

                IComponentBuilder[] componentBuilders =
                    new IComponentBuilder[newComponentsLength + startingComponents.Length];

                Array.Copy(startingComponents, 0, componentBuilders, 0, startingComponents.Length);
                Array.Copy(newComponents, 0, componentBuilders, startingComponents.Length, newComponentsLength);

                var entityInfoComponentIndex = FetchEntityInfoComponent(componentBuilders);

                DBC.ECS.Check.Assert(entityInfoComponentIndex != -1);

                componentBuilders[entityInfoComponentIndex] = new ComponentBuilder <EntityInfoComponent>(
                    new EntityInfoComponent
                {
                    componentsToBuild = componentBuilders
                });

                return(componentBuilders);
            }

            if (extraComponentsLength == 0)
            {
                return(_componentsToBuild);
            }

            var safeCopyOfExtraComponents = new IComponentBuilder[extraComponentsLength];

            Array.Copy(extraComponents, safeCopyOfExtraComponents, extraComponentsLength);

            return(MergeLists(_componentsToBuild, safeCopyOfExtraComponents, extraComponentsLength));
        }
Ejemplo n.º 18
0
 internal EntitiesDB(FasterDictionary <int, Dictionary <Type, ITypeSafeDictionary> > groupEntityViewsDB,
                     Dictionary <Type, FasterDictionary <int, ITypeSafeDictionary> > groupedGroups)
 {
     _groupEntityViewsDB = groupEntityViewsDB;
     _groupedGroups      = groupedGroups;
 }
Ejemplo n.º 19
0
 public Filters
     (FasterDictionary <RefWrapperType, FasterDictionary <ExclusiveGroupStruct, GroupFilters> > filters)
 {
     _filters = filters;
 }
Ejemplo n.º 20
0
        //[InlineData(5_000_000)]
        public async Task AddIterateUpdateIterateKeys(int loops, CheckpointType checkpointType)
        {
            var options = GetOptions($"{nameof(AddIterateUpdateIterate)}-{loops}");

            options.CheckPointType = checkpointType;
            options.DeleteOnClose  = false;

            FasterDictionary <int, string> .ReadResult result;
            using (var dictionary = new FasterDictionary <int, string>(TestHelper.GetKeyComparer <int>(), options))
            {
                for (var i = 0; i < loops; i++)
                {
                    dictionary.Upsert(i, (i + 1).ToString()).Dismiss();
                }

                await dictionary.Ping();

                await dictionary.Save();
            }

            var count = 0;

            using (var dictionary = new FasterDictionary <int, string>(TestHelper.GetKeyComparer <int>(), options))
            {
                for (var i = 0; i < 100; i++)
                {
                    result = await dictionary.TryGet(i);

                    Assert.True(result.Found);
                    Assert.Equal((result.Key + 1).ToString(), result.Value);
                }

                await foreach (var entry in dictionary.AsKeysIterator())
                {
                    count++;
                }

                result = await dictionary.TryGet(loops);

                Assert.False(result.Found);

                Assert.Equal(loops, count);
            }

            count = 0;
            using (var dictionary = new FasterDictionary <int, string>(TestHelper.GetKeyComparer <int>(), options))
            {
                for (var i = 0; i < loops; i++)
                {
                    if (i % 4 == 0)
                    {
                        dictionary.Remove(i).Dismiss();
                    }
                    else
                    {
                        count++;
                        dictionary.Upsert(i, (i + 2).ToString()).Dismiss();
                    }
                }

                await dictionary.Ping();

                await dictionary.Save();
            }

            options.DeleteOnClose = true;

            using (var dictionary = new FasterDictionary <int, string>(TestHelper.GetKeyComparer <int>(), options))
            {
                for (var i = 0; i < 100; i++)
                {
                    result = await dictionary.TryGet(i);

                    if (i % 4 == 0)
                    {
                        Assert.False(result.Found);
                    }
                    else
                    {
                        Assert.True(result.Found);
                        Assert.Equal((result.Key + 2).ToString(), result.Value);
                    }
                }

                var loopCount = 0;

                await foreach (var entry in dictionary.AsKeysIterator())
                {
                    loopCount++;
                    Assert.False(entry % 4 == 0);
                }

                result = await dictionary.TryGet(loops);

                Assert.False(result.Found);

                Assert.Equal(loopCount, count);
            }
        }