public void StringInterning() { var s = new ReusableStream(100); var strings = new[] { "cat", "deer", "snail", "dog", "frog", "human" }; const int max = 4; const string exclude = "frog"; foreach (var str in strings) { s.WriteString(str, false); } s.ResetForReading(); // we're not interning yet - make sure new strings were returned foreach (var str in strings) { var read = s.ReadString(false); Assert.AreEqual(str, read); Assert.AreNotSame(str, read); } s.ResetForReading(); var options = new StringSetOptions(); options.MaxEncodedSizeToLookupInSet = max; Assert.Throws <InvalidOperationException>(() => s.SetDefaultStringSetOptions(options)); var set = new StringSet(10); s.StringSet = set; s.SetDefaultStringSetOptions(options); s.StringSet = null; // should throw because no StringSet has been provided Assert.Throws <InvalidOperationException>(() => s.ReadString(false)); foreach (var str in strings) { if (str != exclude) { set.Add(str); } } s.StringSet = set; // read with interning (but no auto-interning) foreach (var str in strings) { var read = s.ReadString(false); Assert.AreEqual(str, read); if (str.Length <= max && str != exclude) { Assert.AreSame(str, read); } else { Assert.AreNotSame(str, read); } } // make sure the excluded string didn't get added to the set Assert.AreEqual(null, set.GetExistingString(exclude.ToCharArray(), 0, exclude.Length)); s.ResetForReading(); options.PerformDangerousAutoAddToSet = true; s.SetDefaultStringSetOptions(options); // read with auto-interning foreach (var str in strings) { var read = s.ReadString(false); Assert.AreEqual(str, read); if (str.Length <= max && str != exclude) { Assert.AreSame(str, read); } else { Assert.AreNotSame(str, read); } } // make sure the excluded string got added to the set Assert.AreEqual(exclude, set.GetExistingString(exclude.ToCharArray(), 0, exclude.Length)); }