diff --git a/src/pocof.Benchmark/Benchmarks.fs b/src/pocof.Benchmark/Benchmarks.fs index a512e7d..d41d696 100644 --- a/src/pocof.Benchmark/Benchmarks.fs +++ b/src/pocof.Benchmark/Benchmarks.fs @@ -111,15 +111,7 @@ type HandleBenchmarks() = { state with InternalState.QueryState.Query = ":Name" InternalState.QueryState.Cursor = 5 - PropertySearch = - PropertySearch.Rotate( - "Na", - 0, - seq { - "Name" - "Names" - } - ) } + PropertySearch = PropertySearch.Rotate("Na", 0, Seq.cycle [ "Name"; "Names" ]) } let context, _ = state |> Query.prepare diff --git a/src/pocof.Test/Handle.fs b/src/pocof.Test/Handle.fs index b1b8246..86a7afe 100644 --- a/src/pocof.Test/Handle.fs +++ b/src/pocof.Test/Handle.fs @@ -1867,7 +1867,11 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "first"; "second"; "third" ] + + c + |> Seq.take 4 + |> List.ofSeq + |> shouldEqual [ "first"; "second"; "third"; "first" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd @@ -1891,7 +1895,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "p" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "Path" ] + c |> Seq.take 2 |> List.ofSeq |> shouldEqual [ "Path"; "Path" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd @@ -1917,7 +1921,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "n" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "name"; "number" ] + c |> Seq.take 3 |> List.ofSeq |> shouldEqual [ "name"; "number"; "name" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd @@ -1941,7 +1945,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "n" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "name" ] + c |> Seq.take 2 |> List.ofSeq |> shouldEqual [ "name"; "name" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryPartProperty "name" "foo" @@ -1965,7 +1969,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "name" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "name" ] + c |> Seq.take 2 |> List.ofSeq |> shouldEqual [ "name"; "name" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd @@ -1989,7 +1993,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "name" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "name" ] + c |> Seq.take 2 |> List.ofSeq |> shouldEqual [ "name"; "name" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryPartProperty "name" "a" @@ -2013,7 +2017,7 @@ module invokeAction = | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "nam" b |> shouldEqual 0 - c |> List.ofSeq |> shouldEqual [ "name" ] + c |> Seq.take 2 |> List.ofSeq |> shouldEqual [ "name"; "name" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryPartProperty "name" "a" @@ -2024,7 +2028,7 @@ module invokeAction = { state with InternalState.QueryState.Query = ":name" InternalState.QueryState.Cursor = 5 - PropertySearch = PropertySearch.Rotate("n", 0, [ "name"; "number" ]) } + PropertySearch = PropertySearch.Rotate("n", 0, Seq.cycle [ "name"; "number" ]) } let context, _ = Query.prepare state @@ -2038,8 +2042,8 @@ module invokeAction = |> function | PropertySearch.Rotate(a, b, c) -> a |> shouldEqual "n" - b |> shouldEqual 1 - c |> List.ofSeq |> shouldEqual [ "name"; "number" ] + b |> shouldEqual 0 + c |> Seq.take 3 |> List.ofSeq |> shouldEqual [ "number"; "name"; "number" ] | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd @@ -2050,18 +2054,22 @@ module invokeAction = { state with InternalState.QueryState.Query = ":number" InternalState.QueryState.Cursor = 7 - PropertySearch = PropertySearch.Rotate("n", 1, [ "name"; "number" ]) } + PropertySearch = PropertySearch.Rotate("n", 0, Seq.cycle [ "number"; "name" ]) } let context, _ = Query.prepare state let a1, a2 = invokeAction [ "name"; "path"; "number" ] state context Action.CompleteProperty - a1 - |> shouldEqual - { state with - InternalState.QueryState.Query = ":name" - InternalState.QueryState.Cursor = 5 - PropertySearch = PropertySearch.Rotate("n", 0, [ "name"; "number" ]) } + a1.QueryState.Query |> shouldEqual ":name" + a1.QueryState.Cursor |> shouldEqual 5 + + a1.PropertySearch + |> function + | PropertySearch.Rotate(a, b, c) -> + a |> shouldEqual "n" + b |> shouldEqual 0 + c |> Seq.take 3 |> List.ofSeq |> shouldEqual [ "name"; "number"; "name" ] + | _ -> failwith "PropertySearch should be Rotate" a2.Queries |> testQueryEnd diff --git a/src/pocof/Data.fs b/src/pocof/Data.fs index 05f6ced..c5b1c7c 100644 --- a/src/pocof/Data.fs +++ b/src/pocof/Data.fs @@ -70,6 +70,13 @@ module LanguageExtension = let fromIndex (index: int) (s: string) = s.Substring(index) let upToIndex (index: int) (s: string) = s.Substring(0, index) + module Seq = + let rec cycle source = + seq { + yield! source + yield! cycle source + } + let #if !DEBUG inline diff --git a/src/pocof/Handle.fs b/src/pocof/Handle.fs index ec737d0..08dcb9f 100644 --- a/src/pocof/Handle.fs +++ b/src/pocof/Handle.fs @@ -337,16 +337,16 @@ module Handle = #if DEBUG Logger.LogFile [ $"Search keyword '{keyword}' head '{head}' candidate '{candidate}' tail '{tail}'" ] #endif - buildValues head candidate tail keyword 0 candidates basePosition - | PropertySearch.Rotate(keyword, i, candidates) -> - let cur = candidates |> Seq.item i - let i = (i + 1) % Seq.length candidates - let next = candidates |> Seq.item i + buildValues head candidate tail keyword 0 (candidates |> Seq.cycle) basePosition + | PropertySearch.Rotate(keyword, _, candidates) -> + let cur = candidates |> Seq.head + let candidates = candidates |> Seq.tail + let next = candidates |> Seq.head let basePosition, head, tail = splitQuery cur next #if DEBUG Logger.LogFile [ $"Rotate keyword '{keyword}' head '{head}' cur '{cur}' next '{next}' tail '{tail}'" ] #endif - buildValues head next tail keyword i candidates basePosition + buildValues head next tail keyword 0 candidates basePosition let invokeAction (wordDelimiters: string)