diff --git a/Kevo.Benchmarks/PerformanceTests.fs b/Kevo.Benchmarks/PerformanceTests.fs index e57e868..1f754e3 100644 --- a/Kevo.Benchmarks/PerformanceTests.fs +++ b/Kevo.Benchmarks/PerformanceTests.fs @@ -24,7 +24,7 @@ let inline testStraightWildcardSearch<'t> query = //Kevo.Store.findByQuery<'t> query |> List.collect (fun x -> x.Syn) let inline testDeserializeFromProtoBuf<'t> = let c = Kevo.Core.getDictionary<'t> - //let k = Kevo.ProtoBuf.deserialize<'t> + //let k = Kevo.ProtoBuf.deserialize<'t> Kevo.ProtoBuf.serialize> c (string typeof<'t>.GUID) Kevo.JsonNet.serialize> c let b = Kevo.JsonNet.deserialize> @@ -37,17 +37,14 @@ let inline testAppend c = [0..c] |> List.map (fun x -> Kevo.Store.append(x, (string x), None)) |> ignore let perf = float c / timer.Elapsed.TotalMilliseconds printfn "%i; %f" c perf - Kevo.MemoryCache.clearCache Kevo.Core.cacheIndex - printfn "%A" Kevo.Core.getDictionary.Count - + let inline testUpdate c = let timer = new System.Diagnostics.Stopwatch() timer.Start() [0..c] |> List.map (fun x -> Kevo.Store.update(x, (string x))) |> ignore let perf = float c / timer.Elapsed.TotalMilliseconds printfn "%i; %f" c perf - Kevo.MemoryCache.clearCache Kevo.Core.cacheIndex - printfn "%A" Kevo.Core.getDictionary.Count + let testAppendLoop lmax step type_of_append= @@ -67,9 +64,10 @@ let testAppendLoop lmax step type_of_append= let testWrapper<'t> query = - //testAppendLoop 100000 10000 + testAppendLoop 100000 10000 "insert" + printfn "update" testAppendLoop 100000 10000 "update" - + printfn "ok" diff --git a/Kevo.Benchmarks/screenshot1.png b/Kevo.Benchmarks/screenshot1.png index f002d66..5bb32cd 100644 Binary files a/Kevo.Benchmarks/screenshot1.png and b/Kevo.Benchmarks/screenshot1.png differ diff --git a/Kevo.Core/Core.fs b/Kevo.Core/Core.fs index a29ba5b..b6a8084 100644 --- a/Kevo.Core/Core.fs +++ b/Kevo.Core/Core.fs @@ -15,7 +15,7 @@ let getDictionary<'t> = match a with | null -> let b = deserialize> cacheIndex<'t> (addToCache cacheIndex<'t> b) - printfn "%A added to cache" cacheIndex<'t> + //printfn "%A added to cache" cacheIndex<'t> b | _ -> a :?> Dictionary diff --git a/Kevo.Core/ProtoBuf.fs b/Kevo.Core/ProtoBuf.fs index f5e9346..369094e 100644 --- a/Kevo.Core/ProtoBuf.fs +++ b/Kevo.Core/ProtoBuf.fs @@ -14,7 +14,7 @@ let serialize<'t> what where = file.SetLength(file.Position); // fix truncated file.Close()) stopWatch.Stop() - printfn "Protobuf serialization complete in %f ms" stopWatch.Elapsed.TotalMilliseconds + //printfn "Protobuf serialization complete in %f ms" stopWatch.Elapsed.TotalMilliseconds let deserialize<'t> from = @@ -24,7 +24,7 @@ let deserialize<'t> from = let c = Serializer.Deserialize<'t>(file); file.Close() stopWatch.Stop() - printfn "Protobuf deserialization complete in %f ms" stopWatch.Elapsed.TotalMilliseconds + //printfn "Protobuf deserialization complete in %f ms" stopWatch.Elapsed.TotalMilliseconds c else let t = System.Activator.CreateInstance(typeof<'t>) diff --git a/README.md b/README.md index ae11374..7b83cf8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ #KeVo -Damn Easy Key-Value Store written in F# 3.0. +KeVo is a Damn Easy Key-Value Store written in F# 3.0. It is in-memory store using System.Runtime.MemoryCache with full synchronized append log. + +It serialize all objects in Protocol Buffers (Json.NET or binary serialization optional) -- serializing all Object in Protocol Buffers or Json.NET -- using System.Runtinme.MemoryCache ##Getting Started @@ -13,13 +13,20 @@ Damn Easy Key-Value Store written in F# 3.0. val findByQuery : ('t -> bool) -> 't list -And function for insert items: +insert items: val append<'t> : int * 't * (unit -> unit) option -> unit +update + + val update<'t> : int * 't -> unit + ##Create/insert -By default if storage is not exist +By default if storage is not exist `append` function create new file. For example, to insert any string in Dictionary just use `append` function: + + let add_string index = + Kevo.Store.append(index, (index x), None) ##Read @@ -42,21 +49,25 @@ To find any item by id, use findById: Use predicate function for search by any templates: let query (x:WordItem) = - x.Wordst.Contains("ñëîâî") + x.Wordst.Contains("Local Street") Kevo.Store.findByQuery
query |> printfn "%A" ##Benchmarks -Few tests from: `Kevo.Benchmark` +Few tests from `Kevo.Benchmark`. -For Intel Core i5 2500K / 16gb RAM: +Test machine configuration is Intel Core i5 2500K / 16gb RAM: Protobuf deserialization complete in 1431.623400 ms Protobuf serialization complete in 311.327300 ms Json.Net serialization complete in 1770.890400 ms - Json.Net deserialization complete in 3060.234400 ms - "Kevo.PerformanceTests+testWrapper@24[Kevo.Performance+WordItem]" Ellapsed Time: 2291.827700 ms + Json.Net deserialization complete in 3060.234400 ms testReadSumAllNones 564674759 - "Kevo.PerformanceTests+testWrapper@25-3[Kevo.Performance+WordItem]" Ellapsed Time: 66.317000 ms \ No newline at end of file + + +### Append/Update + + +![benchmark screenshot](https://github.com/unknownexception/kevo/raw/master/Kevo.Benchmarks/screenshot1.png) \ No newline at end of file diff --git a/kevo.test/Kevo.Tests.fsproj b/kevo.test/Kevo.Tests.fsproj deleted file mode 100644 index 3dd843c..0000000 --- a/kevo.test/Kevo.Tests.fsproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - Debug - AnyCPU - 2.0 - 87418c59-5cb5-4b9d-8db7-4622d302a77d - Library - Kevo.Tests - Kevo.Tests - v4.5 - Kevo.Tests - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - bin\Debug\Kevo.Tests.XML - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - bin\Release\Kevo.Tests.XML - - - 11 - - - - - - - - - - True - - - ..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll - True - - - - - - - - Kevo.Core - {d5ae23dd-98bd-4a90-863c-4cc220e56e3e} - True - - - - \ No newline at end of file diff --git a/kevo.test/KevoTests.fs b/kevo.test/KevoTests.fs deleted file mode 100644 index 10be02e..0000000 --- a/kevo.test/KevoTests.fs +++ /dev/null @@ -1,52 +0,0 @@ -module Kevo.Tests - -open NUnit.Framework -open Kevo.Store -open System - - -let shouldBeTrue a = - Assert.AreEqual(a, true) - - -let shouldBeFalse a = - Assert.AreEqual(a, false) - -let checkFilesForType<'t> = - System.IO.Directory.GetFiles(Kevo.AppendLog.dataPath) |> Array.filter (fun x -> x.Contains(string typeof<'t>)) - -[] -let ``kevo should be able to append some integer`` () = - checkFilesForType |> Array.map (fun x -> System.IO.File.Delete x) |> ignore - Kevo.Store.append(1, 1, None) - checkFilesForType.Length = 1 |> shouldBeTrue - -[] -let ``kevo should be able to commit int`` () = - let dict = Kevo.Core.getDictionary - let length_before = dict.Count - - let random_value = System.Random().Next() - Kevo.AppendLog.appendSync length_before random_value - // just for for x.Contains(string DateTime.Now.Second) = false - System.Threading.Thread.Sleep(1000) - Kevo.AppendLog.commit |> shouldBeTrue - // file must be deleted - let files = checkFilesForType - files.Length = 0 |> shouldBeTrue - // dictionary must be with one more count - Kevo.Core.getDictionary.Count = 0 |> shouldBeFalse - (Kevo.Core.getDictionary.Count - length_before) = 1 |> shouldBeTrue - Kevo.Core.getDictionary.ContainsValue(random_value) |> shouldBeTrue - // delete cache and try again - Kevo.MemoryCache.clearCache Kevo.Core.cacheIndex - (Kevo.Core.getDictionary.Count - length_before) = 1 |> shouldBeTrue - Kevo.Core.getDictionary.ContainsValue(random_value) |> shouldBeTrue - -[] -let ``kevo should be correct process concurency commiting`` () = - Kevo.Store.append(1, 1.0f, None) - System.Threading.Thread.Sleep(1000) - async { [1..10] |> List.map (fun x -> Kevo.AppendLog.commit) |> ignore } |> Async.RunSynchronously - - checkFilesForType.Length = 0 |> shouldBeTrue diff --git a/kevo.test/packages.config b/kevo.test/packages.config deleted file mode 100644 index a52628b..0000000 --- a/kevo.test/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/kevo.tests/KevoTests.fs b/kevo.tests/KevoTests.fs index b6c3834..4c43458 100644 --- a/kevo.tests/KevoTests.fs +++ b/kevo.tests/KevoTests.fs @@ -37,7 +37,7 @@ let ``kevo should be able to commit int into memory and flush to disk`` () = let random_value = System.Random(100).Next() Kevo.AppendLog.appendSync length_before random_value - //System.Threading.Thread.Sleep(1000) + Kevo.AppendLog.commit |> shouldBeTrue // all files must be deleted