public (DataPage <TPrimaryKey, TRow> NewValue, IMaybe <TRow> PreviousValue) Upsert(
            TPrimaryKey key,
            Func <TRow> factoryFunction,
            Func <TRow, TRow> updateFunction,
            Action <TRow> onBeforeUpsert)
        {
            var previous = Maybe.Empty <TRow>();

            var newValue = _map.AddOrReplace(key,
                                             () =>
            {
                var toInsert = factoryFunction();
                onBeforeUpsert?.Invoke(toInsert);
                return(new DataPage <TPrimaryKey, TRow>(key, toInsert));
            },
                                             p =>
            {
                previous     = Maybe.Return(p.Row);
                var toUpdate = updateFunction(previous.Value);
                onBeforeUpsert?.Invoke(toUpdate);
                p.Update(toUpdate);
                return(p);
            });

            return(newValue, previous);
        }
 public void Add(TIndexKey key, DataPage <TPrimaryKey, TRow> page)
 {
     _map.AddOrReplace(key,
                       () =>
     {
         var group = new Set <DataPage <TPrimaryKey, TRow> >(_primaryKeyComparer);
         group.Add(page);
         return(group);
     },
                       s =>
     {
         if (!s.Add(page))
         {
             throw new Exception($"Unable to add record to group at key: '{key}'. Row with primary key '{page.PrimaryKey}' already existed in the group");
         }
         return(s);
     });
 }