/// <summary> /// Creates a new storage instance with specified types of keys and values. /// </summary> /// <typeparam name="TKey">The type of key</typeparam> /// <typeparam name="TValue">The type of value</typeparam> /// <param name="keySerializer">Object implementing ISerializer interface for key serialization</param> /// <param name="valueSerializer">Object implementing ISerializer interface for value serialization</param> /// <param name="settings">Setiings of creating storage</param> /// <returns>New storage instance</returns> public IKeyValueStorage <KeyOf <TKey>, ValueOf <TValue> > CreateRadixTreeStorage <TKey, TValue>(ISerializer <TKey> keySerializer, ISerializer <TValue> valueSerializer, RadixTreeStorageSettings settings) { bool usePageCache = settings.CacheSettings != null; if (settings.MaxEmptyPages < 0) { throw new ArgumentException("MaxEmptyPages shouldn't be negative", nameof(settings)); } if (usePageCache) { if (settings.CacheSettings.MaxCachedPages < 0) { throw new ArgumentException("MaxCachedPages shouldn't be negative", nameof(settings)); } if (settings.CacheSettings.MaxDirtyPages < 0) { throw new ArgumentException("MaxDirtyPages shouldn't be negative", nameof(settings)); } if (settings.CacheSettings.MaxDirtyPages > settings.CacheSettings.MaxCachedPages) { throw new ArgumentException("MaxDirtyPages shouldn be equal to or less than MaxCachedPages", nameof(settings)); } } IPageManager pageManager = null; IPageManager fsPageManager = null; try { fsPageManager = new FileSystemPageManager((int)settings.PageSize, settings.ForcedWrites, 1, true) { MaxEmptyPages = settings.MaxEmptyPages }; pageManager = usePageCache ? new CachingPageManager(fsPageManager, settings.CacheSettings.MaxCachedPages, settings.CacheSettings.MaxDirtyPages) : fsPageManager; var ks = new Serializer <KeyOf <TKey> >(obj => keySerializer.Serialize(obj), bytes => keySerializer.Deserialize(bytes)); var vs = new Serializer <ValueOf <TValue> >(obj => valueSerializer.Serialize(obj), bytes => valueSerializer.Deserialize(bytes)); var radixTree = new RadixTree <KeyOf <TKey>, ValueOf <TValue> >( new RadixTreeNodeStorage(pageManager), new ValueStorage <ValueOf <TValue> >(new MemoryManager(new FreeSpaceMap(pageManager), pageManager), vs), ks); return(new RadixTreeKeyValueStorage <KeyOf <TKey>, ValueOf <TValue> >(pageManager, radixTree, settings.AutoFlushInterval, settings.AutoFlushTimeout)); } catch (Exception) { if (pageManager != null) { pageManager.Close(); } else { fsPageManager?.Close(); } throw; } }
/// <summary> /// Creates a new storage instance with specified types of keys and values. /// </summary> /// <typeparam name="TKey">The type of key</typeparam> /// <typeparam name="TValue">The type of value</typeparam> /// <param name="keySerializer">Object implementing ISerializer interface for key serialization</param> /// <param name="valueSerializer">Object implementing ISerializer interface for value serialization</param> /// <param name="settings">Setiings of creating storage</param> /// <returns>New storage instance</returns> public IBPlusTreeKeyValueStorage <ComparableKeyOf <TKey>, ValueOf <TValue> > CreateBPlusTreeStorage <TKey, TValue>(ISerializer <TKey> keySerializer, ISerializer <TValue> valueSerializer, BPlusTreeStorageSettings settings) where TKey : IComparable { bool usePageCache = settings.CacheSettings != null; if (settings.MaxEmptyPages < 0) { throw new ArgumentException("MaxEmptyPages shouldn't be negative", nameof(settings)); } if (usePageCache) { if (settings.CacheSettings.MaxCachedPages < 0) { throw new ArgumentException("MaxCachedPages shouldn't be negative", nameof(settings)); } if (settings.CacheSettings.MaxDirtyPages < 0) { throw new ArgumentException("MaxDirtyPages shouldn't be negative", nameof(settings)); } if (settings.CacheSettings.MaxDirtyPages > settings.CacheSettings.MaxCachedPages) { throw new ArgumentException("MaxDirtyPages shouldn be equal to or less than MaxCachedPages", nameof(settings)); } } IPageManager pageManager = null; IPageManager fsPageManager = null; try { var asyncWriteBuffer = usePageCache ? Math.Min(settings.CacheSettings.MaxDirtyPages, 1000) : 100; fsPageManager = new FileSystemPageManager((int)settings.PageSize, settings.ForcedWrites, asyncWriteBuffer, true) { MaxEmptyPages = settings.MaxEmptyPages }; pageManager = usePageCache ? new CachingPageManager(fsPageManager, settings.CacheSettings.MaxCachedPages, settings.CacheSettings.MaxDirtyPages) : fsPageManager; var ks = new Serializer <ComparableKeyOf <TKey> >(obj => keySerializer.Serialize(obj), bytes => keySerializer.Deserialize(bytes)); var vs = new Serializer <ValueOf <TValue> >(obj => valueSerializer.Serialize(obj), bytes => valueSerializer.Deserialize(bytes)); if (settings.MaxKeySize <= 0) { throw new ArgumentException("MaxKeySize size should be positive", nameof(settings)); } var bPlusTree = new BPlusTree <ComparableKeyOf <TKey>, ValueOf <TValue> >( new BPlusTreeNodeStorage <ComparableKeyOf <TKey> >(pageManager, ks, settings.MaxKeySize), new ValueStorage <ValueOf <TValue> >(new MemoryManager(new FreeSpaceMap(pageManager), pageManager), vs)); return(new BPlusTreeKeyValueStorage <ComparableKeyOf <TKey>, ValueOf <TValue> >(pageManager, bPlusTree, settings.MaxKeySize, settings.AutoFlushInterval, settings.AutoFlushTimeout)); } catch (Exception) { if (pageManager != null) { pageManager.Close(); } else { fsPageManager?.Close(); } throw; } }