Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the save performance of page elements #1193

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions OneMore/Helpers/Extensions/HashAlgorithmExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//************************************************************************************************
// Copyright © 2032 Steven M Cohn. All rights reserved.
//************************************************************************************************

namespace River.OneMoreAddIn
{
using System.Numerics;
using System.Security.Cryptography;
using System.Text;


internal static class HashAlgorithmExtensions
{
public static string GetHashString(this HashAlgorithm algorithm, string s)
{
var data = Encoding.UTF8.GetBytes(s);
var hash = algorithm.ComputeHash(data);
return new BigInteger(hash).ToString();
}
}
}
57 changes: 54 additions & 3 deletions OneMore/Models/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace River.OneMoreAddIn.Models
using System.Globalization;
using System.Linq;
using System.Media;
using System.Security.Policy;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
Expand All @@ -30,6 +30,8 @@ internal partial class Page
{
public int TopOutlinePosition = 86;

private const string HashAttributeName = "omHash";


/// <summary>
/// Initialize a new instance with the given page XML root
Expand All @@ -39,16 +41,65 @@ public Page(XElement root)
{
if (root != null)
{
Root = root;
Namespace = root.GetNamespaceOfPrefix(OneNote.Prefix);

PageId = root.Attribute("ID")?.Value;
ComputeHashes(root);

Root = root;
}

SelectionScope = SelectionScope.Unknown;
}


#region Hashing
/// <summary>
/// Calculates a hash value for each 1st gen child element on the page, which will
/// be used to optimize the page just prior to saving.
/// </summary>
/// <param name="root">The root element of the page</param>
private void ComputeHashes(XElement root)
{
using var algo = MD5.Create();

// 1st generation child elements of the Page
foreach (var child in root.Elements())
{
child.Add(new XAttribute(
HashAttributeName,
algo.GetHashString(child.ToString(SaveOptions.DisableFormatting))
));
}
}


/// <summary>
/// Keeps only modified 1st gen child elements of the page to optimize save performance
/// especially when the page is loaded with many Ink drawings.
/// </summary>
public void OptimizeForSave()
{
// MD5 should be sufficient and performs better than any other algorithm
using var algo = MD5.Create();

// 1st generation child elements of the Page
foreach (var child in Root.Elements().ToList())
{
var att = child.Attribute(HashAttributeName);
if (att != null)
{
att.Remove();
var hash = algo.GetHashString(child.ToString(SaveOptions.DisableFormatting));
if (hash == att.Value)
{
child.Remove();
}
}
}
}
#endregion Hashing


public bool IsValid => Root != null;


Expand Down
1 change: 1 addition & 0 deletions OneMore/OneMore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
<Compile Include="Helpers\ColorHelper.cs" />
<Compile Include="Helpers\Extensions\FontFamilyExtensions.cs" />
<Compile Include="Helpers\Extensions\GraphicsExtensions.cs" />
<Compile Include="Helpers\Extensions\HashAlgorithmExtensions.cs" />
<Compile Include="Helpers\Extensions\ScreenExtensions.cs" />
<Compile Include="Models\KnownSchemaAttributes.cs" />
<Compile Include="Models\PageReader.cs" />
Expand Down
19 changes: 5 additions & 14 deletions OneMore/OneNote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,22 +1047,13 @@ public async Task Update(Page page)
return;
}

await Update(page.Root);
}
// must optimize before we can validate schema...

page.OptimizeForSave();

/// <summary>
/// Updates the given content, with a unique ID, on the current page.
/// </summary>
/// <param name="element">A page or element within a page with a unique objectID</param>
public async Task Update(XElement element)
{
if (element.Name.LocalName == "Page")
if (!ValidateSchema(page.Root))
{
if (!ValidateSchema(element))
{
return;
}
return;
}

// dateExpectedLastModified is merely a pessimistic-locking safeguard to prevent
Expand All @@ -1072,7 +1063,7 @@ public async Task Update(XElement element)
// ? DateTime.Parse(att.Value).ToUniversalTime()
// : DateTime.MinValue;

var xml = element.ToString(SaveOptions.DisableFormatting);
var xml = page.Root.ToString(SaveOptions.DisableFormatting);

await InvokeWithRetry(() =>
{
Expand Down