From 0226a0d1c9c331cb6e4b71e4acd34314a80917ab Mon Sep 17 00:00:00 2001 From: Ian O Connell Date: Tue, 5 Nov 2013 17:43:28 -0800 Subject: [PATCH 1/5] Reporting store algebra's --- .../algebra/reporting/Reporter.scala | 50 +++++++++ .../reporting/ReportingMergeableStore.scala | 40 +++++++ .../reporting/ReportingReadableStore.scala | 36 +++++++ .../algebra/reporting/ReportingStore.scala | 37 +++++++ .../ReportingMergeableStoreProperties.scala | 89 ++++++++++++++++ .../ReportingReadableStoreProperties.scala | 100 ++++++++++++++++++ .../reporting/ReportingStoreProperties.scala | 77 ++++++++++++++ 7 files changed, 429 insertions(+) create mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala create mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala create mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala create mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala create mode 100644 storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala create mode 100644 storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala create mode 100644 storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala new file mode 100644 index 00000000..d0271dae --- /dev/null +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.algebird.Monoid +import com.twitter.util.Future +import scala.collection.generic.CanBuildFrom + +object Reporter { + def sideEffect[T, U](params: U, f: Future[T], sideEffect: (U, Future[T]) => Future[Unit]): Future[T] = + Future.join(f, sideEffect(params, f)).map(_._1) + + def sideEffect[T, K, U](params: U, f: Map[K, Future[T]], sideEffect: (U, Map[K, Future[T]]) => Map[K, Future[Unit]]): Map[K, Future[T]] = { + val effected = sideEffect(params, f) + f.map{case (k, v) => + val unitF = effected.getOrElse(k, sys.error("Reporter for multi side effect didn't return a future for key" + k.toString)) + (k, Future.join(v, unitF).map(_._1)) + } + } + +} + +trait StoreReporter[K, V] { + def tracePut(kv: (K, Option[V]), request: Future[Unit]) = Future.Unit + def traceMultiPut[K1 <: K](kvs: Map[K1, Option[V]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = request +} + +trait ReadableStoreReporter[K, V]{ + def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) + def traceGet(k: K, request: Future[Option[V]]) = Future.Unit +} + +trait MergeableStoreReporter[K, V] extends StoreReporter[K, V] with ReadableStoreReporter[K, V]{ + def traceMerge(kv: (K, V), request: Future[Option[V]]) = Future.Unit + def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) +} diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala new file mode 100644 index 00000000..b506ae1b --- /dev/null +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala @@ -0,0 +1,40 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.Future +import com.twitter.storehaus.algebra.MergeableStore + +object ReportingMergeableStore { + def apply[K, V](passedStore: MergeableStore[K, V], + passedReporter: MergeableStoreReporter[K, V]) = new ReportingMergeableStore[K, V] { + val store = passedStore + val reporter = passedReporter + } + +} + +trait ReportingMergeableStore[K, V] extends MergeableStore[K, V] + with ReportingStore[K, V] with ReportingReadableStore[K,V] { + def store: MergeableStore[K, V] + def reporter: MergeableStoreReporter[K, V] + lazy val semigroup = store.semigroup + + + override def merge(kv: (K, V)) = Reporter.sideEffect(kv, store.merge(kv), reporter.traceMerge) + override def multiMerge[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, store.multiMerge(kvs), reporter.traceMultiMerge) +} diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala new file mode 100644 index 00000000..0fc0c957 --- /dev/null +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala @@ -0,0 +1,36 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.Future +import com.twitter.storehaus.ReadableStore + +object ReportingReadableStore { + def apply[K, V](passedStore: ReadableStore[K, V], + passedReporter: ReadableStoreReporter[K, V]) = new ReportingReadableStore[K, V] { + val store = passedStore + val reporter = passedReporter + } +} + +trait ReportingReadableStore[K, V] extends ReadableStore[K, V] { + def store: ReadableStore[K, V] + def reporter: ReadableStoreReporter[K, V] + + override def get(k: K): Future[Option[V]] = Reporter.sideEffect(k, store.get(k), reporter.traceGet) + override def multiGet[K1 <: K](keys: Set[K1]) = Reporter.sideEffect(keys, store.multiGet(keys), reporter.traceMultiGet) +} diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala new file mode 100644 index 00000000..f891ee39 --- /dev/null +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala @@ -0,0 +1,37 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.Future +import com.twitter.storehaus.Store + +object ReportingStore { + def apply[K, V](passedStore: Store[K, V], + passedReporter: StoreReporter[K, V]) = new ReportingStore[K, V] { + val store = passedStore + val reporter = passedReporter + } + +} + +trait ReportingStore[K, V] extends Store[K, V] { + def store: Store[K, V] + def reporter: StoreReporter[K, V] + + override def put(kv: (K, Option[V])): Future[Unit] = Reporter.sideEffect(kv, store.put(kv), reporter.tracePut) + override def multiPut[K1 <: K](kvs: Map[K1, Option[V]]) = Reporter.sideEffect(kvs, store.multiPut(kvs), reporter.traceMultiPut) +} \ No newline at end of file diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala new file mode 100644 index 00000000..34777ef3 --- /dev/null +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala @@ -0,0 +1,89 @@ + +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.{ Await, Future } +import org.scalacheck.{ Arbitrary, Properties } +import org.scalacheck.Gen.choose +import org.scalacheck.Prop._ + +import com.twitter.storehaus.algebra._ + +object ReportingMergeableStoreProperties extends Properties("ReportingMergeableStore") { + import MergeableStoreProperties.{mergeableStoreTest, newStore} + + property("Mergable stat store obeys the mergeable store proporites") = + mergeableStoreTest { + ReportingMergeableStore[Int,Int](newStore[Int, Int], new MergeableStoreReporter[Int, Int] {}) + } + + property("merge Some/None count matches") = forAll { (base: Map[Int, Int], merge: Map[Int, Int]) => + var mergeWithSomeCount = 0 + var mergeWithNoneCount = 0 + val reporter = new MergeableStoreReporter[Int, Int] { + override def traceMerge(kv: (Int, Int), request: Future[Option[Int]]) = { + request.map { optV => + optV match { + case Some(_) => mergeWithSomeCount += 1 + case None => mergeWithNoneCount += 1 + } + }.unit + } + } + val baseStore = MergeableStore.fromStore(newStore[Int, Int]) + baseStore.multiMerge(base) + val wrappedStore = ReportingMergeableStore[Int, Int](baseStore, reporter) + + + merge.map(kv => wrappedStore.merge((kv._1, kv._2))) + + val existsBeforeList = merge.keySet.toList.map(k => base.get(k)) + + existsBeforeList.collect{case Some(_) => 1}.size == mergeWithSomeCount && + existsBeforeList.collect{case None => 1}.size == mergeWithNoneCount + } + + property("multiMerge Some/None count matches") = forAll { (base: Map[Int, Int], merge: Map[Int, Int]) => + var mergeWithSomeCount = 0 + var mergeWithNoneCount = 0 + val reporter = new MergeableStoreReporter[Int, Int] { + override def traceMultiMerge[K1 <: Int](kvs: Map[K1, Int], request: Map[K1, Future[Option[Int]]]) = { + request.mapValues{optV => + optV.map{ v => + v match { + case Some(_) => mergeWithSomeCount += 1 + case None => mergeWithNoneCount += 1 + } + }.unit + } + } + } + + val baseStore = MergeableStore.fromStore(newStore[Int, Int]) + baseStore.multiMerge(base) + val wrappedStore = ReportingMergeableStore[Int, Int](baseStore, reporter) + + + wrappedStore.multiMerge(merge) + + val existsBeforeList = merge.keySet.toList.map(k => base.get(k)) + + existsBeforeList.collect{case Some(_) => 1}.size == mergeWithSomeCount && + existsBeforeList.collect{case None => 1}.size == mergeWithNoneCount + } +} diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala new file mode 100644 index 00000000..a2913242 --- /dev/null +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala @@ -0,0 +1,100 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.{ Await, Future } +import com.twitter.storehaus.ReadableStore +import org.scalacheck.{ Arbitrary, Properties } +import org.scalacheck.Gen.choose +import org.scalacheck.Prop._ + +object ReportingReadableStoreProperties extends Properties("ReportingReadableStore") { + /** + * get returns none when not in either store + */ + + def buildStoreRunQueries[K, V](mA: Map[K, V], others: Set[K], reporter: ReadableStoreReporter[K, V]) = { + val baseStore = ReadableStore.fromMap(mA) + val wrappedStore = ReportingReadableStore(baseStore, reporter) + val expanded: Set[K] = (mA.keySet ++ others) + // We use call to list, or it keeps the results of the map as a set and we loose data + expanded.toList.map{k: K => (mA.get(k), Await.result(wrappedStore.get(k)))} + } + + def buildStoreRunMultiGetQueries[K, V](mA: Map[K, V], others: Set[K], reporter: ReadableStoreReporter[K, V]) = { + val baseStore = ReadableStore.fromMap(mA) + val wrappedStore = ReportingReadableStore(baseStore, reporter) + val expanded: Set[K] = (mA.keySet ++ others) + // We use call to list, or it keeps the results of the map as a set and we loose data + (expanded.map{k => (k, mA.get(k))}.toMap, + wrappedStore.multiGet(expanded).map{case (k, futureV) => (k, Await.result(futureV))}) + } + + property("Stats store matches raw get for all queries") = forAll { (mA: Map[Int, String], others: Set[Int]) => + val reporter = new ReadableStoreReporter[Int, String] {} + val queryResults = buildStoreRunQueries(mA, others, reporter) + queryResults.forall{case (a, b) => a == b} + } + + property("Present/Absent count matches") = forAll { (mA: Map[Int, String], others: Set[Int]) => + var presentCount = 0 + var absentCount = 0 + val reporter = new ReadableStoreReporter[Int, String] { + override def traceGet(k: Int, request: Future[Option[String]]) = { + request.map{ optV => + optV match { + case Some(_) => presentCount += 1 + case None => absentCount += 1 + } + } + } + } + val queryResults = buildStoreRunQueries(mA, others, reporter) + val wrappedResults = queryResults.map(_._2) + val referenceResults = queryResults.map(_._2) + wrappedResults.collect{case Some(b) => b}.size == presentCount && + wrappedResults.collect{case None => 1}.size == absentCount + } + + property("Stats store matches raw get for multiget all queries") = forAll { (mA: Map[Int, String], others: Set[Int]) => + val reporter = new ReadableStoreReporter[Int, String] {} + val (mapRes, storeResults) = buildStoreRunMultiGetQueries(mA, others, reporter) + mapRes.size == storeResults.size && + mapRes.keySet.forall(k => mapRes.get(k) == storeResults.get(k)) + } + + property("Present/Absent count matches in multiget") = forAll { (mA: Map[Int, String], others: Set[Int]) => + var presentCount = 0 + var absentCount = 0 + val reporter = new ReadableStoreReporter[Int, String] { + override def traceMultiGet[K1 <: Int](ks: Set[K1], request: Map[K1, Future[Option[String]]]) = { + request.mapValues{fOptV => + fOptV.map {optV => + optV match { + case Some(_) => presentCount += 1 + case None => absentCount += 1 + } + } + } + } + } + + val (_, storeResults) = buildStoreRunMultiGetQueries(mA, others, reporter) + storeResults.values.collect{case Some(b) => b}.size == presentCount && + storeResults.values.collect{case None => 1}.size == absentCount + } +} diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala new file mode 100644 index 00000000..736eb489 --- /dev/null +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala @@ -0,0 +1,77 @@ +/* + * Copyright 2013 Twitter Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.twitter.storehaus.algebra.reporting + +import com.twitter.util.{ Await, Future } +import org.scalacheck.{ Arbitrary, Properties } +import org.scalacheck.Gen.choose +import org.scalacheck.Prop._ + +import com.twitter.storehaus._ +import com.twitter.storehaus.algebra._ + +object ReportingStoreProperties extends Properties("ReportingStore") { + def newStore[K, V] = new JMapStore[K, V] + + property("Put Some/None count matches") = forAll { (inserts: Map[Int, Option[Int]]) => + var putSomeCount = 0 + var putNoneCount = 0 + val reporter = new StoreReporter[Int, Int] { + override def tracePut(kv: (Int, Option[Int]), request: Future[Unit]) = { + Future { + kv._2 match { + case Some(_) => putSomeCount += 1 + case None => putNoneCount += 1 + } + }.unit + } + } + val baseStore = newStore[Int, Int] + val wrappedStore = ReportingStore[Int, Int](baseStore, reporter) + + inserts.foreach{ i => + wrappedStore.put(i._1, i._2) + } + inserts.map(_._2).collect{case Some(b) => b}.size == putSomeCount && + inserts.map(_._2).collect{case None => 1}.size == putNoneCount + } + + property("MultiPut Some/None count matches") = forAll { (inserts: Map[Int, Option[Int]]) => + var multiPutSomeCount = 0 + var multiPutNoneCount = 0 + val reporter = new StoreReporter[Int, Int] { + override def traceMultiPut[K1 <: Int](kvs: Map[K1, Option[Int]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = { + kvs.mapValues {v => + Future { + v match { + case Some(_) => multiPutSomeCount += 1 + case None => multiPutNoneCount += 1 + } + }.unit + } + } + } + val baseStore = newStore[Int, Int] + val wrappedStore = ReportingStore[Int, Int](baseStore, reporter) + + + wrappedStore.multiPut(inserts) + + inserts.map(_._2).collect{case Some(b) => b}.size == multiPutSomeCount && + inserts.map(_._2).collect{case None => 1}.size == multiPutNoneCount + } +} From 115f99bd55f9f5bdb10231dbd2992ddca4eb9f07 Mon Sep 17 00:00:00 2001 From: Ian O Connell Date: Fri, 8 Nov 2013 11:43:54 -0800 Subject: [PATCH 2/5] Have a Writable Store reporter, and inherit the store reporter from it --- .../algebra/reporting/Reporter.scala | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala index d0271dae..ba1e1fac 100644 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala @@ -16,9 +16,7 @@ package com.twitter.storehaus.algebra.reporting -import com.twitter.algebird.Monoid import com.twitter.util.Future -import scala.collection.generic.CanBuildFrom object Reporter { def sideEffect[T, U](params: U, f: Future[T], sideEffect: (U, Future[T]) => Future[Unit]): Future[T] = @@ -34,17 +32,20 @@ object Reporter { } -trait StoreReporter[K, V] { - def tracePut(kv: (K, Option[V]), request: Future[Unit]) = Future.Unit - def traceMultiPut[K1 <: K](kvs: Map[K1, Option[V]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = request -} trait ReadableStoreReporter[K, V]{ def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) - def traceGet(k: K, request: Future[Option[V]]) = Future.Unit + def traceGet(k: K, request: Future[Option[V]]) = request.unit +} + +trait WritableStoreReporter[K, V] { + def tracePut(kv: (K, Option[V]), request: Future[Unit]) = request + def traceMultiPut[K1 <: K](kvs: Map[K1, Option[V]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = request } -trait MergeableStoreReporter[K, V] extends StoreReporter[K, V] with ReadableStoreReporter[K, V]{ - def traceMerge(kv: (K, V), request: Future[Option[V]]) = Future.Unit +trait StoreReporter[K, V] extends ReadableStoreReporter[K, V] with WritableStoreReporter[K, V] + +trait MergeableStoreReporter[K, V] extends StoreReporter[K, V]{ + def traceMerge(kv: (K, V), request: Future[Option[V]]) = request.unit def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) } From 09fd61351286b1ffa052cdd3d17031230a1d1b28 Mon Sep 17 00:00:00 2001 From: Ian O Connell Date: Tue, 11 Mar 2014 11:41:11 -0700 Subject: [PATCH 3/5] Clean up/update this. Use proxies, reduce code a bit --- .../algebra/reporting/Reporter.scala | 37 ++++++++++++----- .../reporting/ReportingMergeableStore.scala | 40 ------------------- .../reporting/ReportingReadableStore.scala | 36 ----------------- .../algebra/reporting/ReportingStore.scala | 37 ----------------- .../ReportingMergeableStoreProperties.scala | 33 +++++++++------ .../ReportingReadableStoreProperties.scala | 24 ++++++----- .../reporting/ReportingStoreProperties.scala | 23 +++++++---- 7 files changed, 78 insertions(+), 152 deletions(-) delete mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala delete mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala delete mode 100644 storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala index ba1e1fac..1e55d5bd 100644 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala @@ -16,6 +16,8 @@ package com.twitter.storehaus.algebra.reporting +import com.twitter.storehaus.{Store, ReadableStore, WritableStore} +import com.twitter.storehaus.algebra.Mergeable import com.twitter.util.Future object Reporter { @@ -29,23 +31,38 @@ object Reporter { (k, Future.join(v, unitF).map(_._1)) } } +} + +trait ReadableStoreReporter[K, V] extends ReadableStore[K, V] { + def self: ReadableStore[K, V] + override def get(k: K): Future[Option[V]] = Reporter.sideEffect(k, self.get(k), traceGet) + override def multiGet[K1 <: K](keys: Set[K1]) = Reporter.sideEffect(keys, self.multiGet(keys), traceMultiGet) + def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] + def traceGet(k: K, request: Future[Option[V]]): Future[Unit] } -trait ReadableStoreReporter[K, V]{ - def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) - def traceGet(k: K, request: Future[Option[V]]) = request.unit +trait WritableStoreReporter[K, V] extends WritableStore[K, V] { + def self: WritableStore[K, V] + override def put(kv: (K, V)): Future[Unit] = Reporter.sideEffect(kv, self.put(kv), tracePut) + override def multiPut[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiPut(kvs), traceMultiPut) + + def tracePut(kv: (K, V), request: Future[Unit]): Future[Unit] + def traceMultiPut[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] } -trait WritableStoreReporter[K, V] { - def tracePut(kv: (K, Option[V]), request: Future[Unit]) = request - def traceMultiPut[K1 <: K](kvs: Map[K1, Option[V]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = request + +trait MergeableReporter[K, V] extends Mergeable[K, V] { + def self: Mergeable[K, V] + override def merge(kv: (K, V)) = Reporter.sideEffect(kv, self.merge(kv), traceMerge) + override def multiMerge[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiMerge(kvs), traceMultiMerge) + + def traceMerge(kv: (K, V), request: Future[Option[V]]): Future[Unit] + def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] } -trait StoreReporter[K, V] extends ReadableStoreReporter[K, V] with WritableStoreReporter[K, V] -trait MergeableStoreReporter[K, V] extends StoreReporter[K, V]{ - def traceMerge(kv: (K, V), request: Future[Option[V]]) = request.unit - def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) +trait StoreReporter[K, V] extends ReadableStoreReporter[K, V] with WritableStoreReporter[K, Option[V]] { + def self: Store[K, V] } diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala deleted file mode 100644 index b506ae1b..00000000 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStore.scala +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013 Twitter Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twitter.storehaus.algebra.reporting - -import com.twitter.util.Future -import com.twitter.storehaus.algebra.MergeableStore - -object ReportingMergeableStore { - def apply[K, V](passedStore: MergeableStore[K, V], - passedReporter: MergeableStoreReporter[K, V]) = new ReportingMergeableStore[K, V] { - val store = passedStore - val reporter = passedReporter - } - -} - -trait ReportingMergeableStore[K, V] extends MergeableStore[K, V] - with ReportingStore[K, V] with ReportingReadableStore[K,V] { - def store: MergeableStore[K, V] - def reporter: MergeableStoreReporter[K, V] - lazy val semigroup = store.semigroup - - - override def merge(kv: (K, V)) = Reporter.sideEffect(kv, store.merge(kv), reporter.traceMerge) - override def multiMerge[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, store.multiMerge(kvs), reporter.traceMultiMerge) -} diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala deleted file mode 100644 index 0fc0c957..00000000 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStore.scala +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013 Twitter Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twitter.storehaus.algebra.reporting - -import com.twitter.util.Future -import com.twitter.storehaus.ReadableStore - -object ReportingReadableStore { - def apply[K, V](passedStore: ReadableStore[K, V], - passedReporter: ReadableStoreReporter[K, V]) = new ReportingReadableStore[K, V] { - val store = passedStore - val reporter = passedReporter - } -} - -trait ReportingReadableStore[K, V] extends ReadableStore[K, V] { - def store: ReadableStore[K, V] - def reporter: ReadableStoreReporter[K, V] - - override def get(k: K): Future[Option[V]] = Reporter.sideEffect(k, store.get(k), reporter.traceGet) - override def multiGet[K1 <: K](keys: Set[K1]) = Reporter.sideEffect(keys, store.multiGet(keys), reporter.traceMultiGet) -} diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala deleted file mode 100644 index f891ee39..00000000 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/ReportingStore.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2013 Twitter Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.twitter.storehaus.algebra.reporting - -import com.twitter.util.Future -import com.twitter.storehaus.Store - -object ReportingStore { - def apply[K, V](passedStore: Store[K, V], - passedReporter: StoreReporter[K, V]) = new ReportingStore[K, V] { - val store = passedStore - val reporter = passedReporter - } - -} - -trait ReportingStore[K, V] extends Store[K, V] { - def store: Store[K, V] - def reporter: StoreReporter[K, V] - - override def put(kv: (K, Option[V])): Future[Unit] = Reporter.sideEffect(kv, store.put(kv), reporter.tracePut) - override def multiPut[K1 <: K](kvs: Map[K1, Option[V]]) = Reporter.sideEffect(kvs, store.multiPut(kvs), reporter.traceMultiPut) -} \ No newline at end of file diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala index 34777ef3..6acb7cc3 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala @@ -27,15 +27,30 @@ import com.twitter.storehaus.algebra._ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableStore") { import MergeableStoreProperties.{mergeableStoreTest, newStore} + + + class DummyReporter[K, V](val self: Mergeable[K, V]) extends MergeableProxy[K, V] with MergeableReporter[K, V] { + def traceMerge(kv: (K, V), request: Future[Option[V]]) = request.unit + def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) + } + property("Mergable stat store obeys the mergeable store proporites") = mergeableStoreTest { - ReportingMergeableStore[Int,Int](newStore[Int, Int], new MergeableStoreReporter[Int, Int] {}) + val store = newStore[Int, Int] + new MergeableStoreProxy[Int, Int] with MergeableReporter[Int, Int] { + val self = store + def traceMerge(kv: (Int, Int), request: Future[Option[Int]]) = request.unit + def traceMultiMerge[K1 <: Int](kvs: Map[K1, Int], request: Map[K1, Future[Option[Int]]]) = request.mapValues(_.unit) + } } property("merge Some/None count matches") = forAll { (base: Map[Int, Int], merge: Map[Int, Int]) => var mergeWithSomeCount = 0 var mergeWithNoneCount = 0 - val reporter = new MergeableStoreReporter[Int, Int] { + val baseStore = MergeableStore.fromStore(newStore[Int, Int]) + baseStore.multiMerge(base) + + val wrappedStore = new DummyReporter[Int, Int](baseStore) { override def traceMerge(kv: (Int, Int), request: Future[Option[Int]]) = { request.map { optV => optV match { @@ -45,10 +60,6 @@ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableS }.unit } } - val baseStore = MergeableStore.fromStore(newStore[Int, Int]) - baseStore.multiMerge(base) - val wrappedStore = ReportingMergeableStore[Int, Int](baseStore, reporter) - merge.map(kv => wrappedStore.merge((kv._1, kv._2))) @@ -61,7 +72,10 @@ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableS property("multiMerge Some/None count matches") = forAll { (base: Map[Int, Int], merge: Map[Int, Int]) => var mergeWithSomeCount = 0 var mergeWithNoneCount = 0 - val reporter = new MergeableStoreReporter[Int, Int] { + val baseStore = MergeableStore.fromStore(newStore[Int, Int]) + baseStore.multiMerge(base) + + val wrappedStore = new DummyReporter[Int, Int](baseStore) { override def traceMultiMerge[K1 <: Int](kvs: Map[K1, Int], request: Map[K1, Future[Option[Int]]]) = { request.mapValues{optV => optV.map{ v => @@ -74,11 +88,6 @@ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableS } } - val baseStore = MergeableStore.fromStore(newStore[Int, Int]) - baseStore.multiMerge(base) - val wrappedStore = ReportingMergeableStore[Int, Int](baseStore, reporter) - - wrappedStore.multiMerge(merge) val existsBeforeList = merge.keySet.toList.map(k => base.get(k)) diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala index a2913242..4d51c0bf 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala @@ -17,7 +17,7 @@ package com.twitter.storehaus.algebra.reporting import com.twitter.util.{ Await, Future } -import com.twitter.storehaus.ReadableStore +import com.twitter.storehaus.{ReadableStore, ReadableStoreProxy} import org.scalacheck.{ Arbitrary, Properties } import org.scalacheck.Gen.choose import org.scalacheck.Prop._ @@ -27,17 +27,22 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto * get returns none when not in either store */ - def buildStoreRunQueries[K, V](mA: Map[K, V], others: Set[K], reporter: ReadableStoreReporter[K, V]) = { + class DummyReporter[K, V](val self: ReadableStore[K, V]) extends ReadableStoreProxy[K, V] with ReadableStoreReporter[K, V] { + def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) + def traceGet(k: K, request: Future[Option[V]]) = request.unit + } + + def buildStoreRunQueries[K, V](mA: Map[K, V], others: Set[K], builder: (ReadableStore[K, V]) => ReadableStore[K, V]) = { val baseStore = ReadableStore.fromMap(mA) - val wrappedStore = ReportingReadableStore(baseStore, reporter) + val wrappedStore = builder(baseStore) val expanded: Set[K] = (mA.keySet ++ others) // We use call to list, or it keeps the results of the map as a set and we loose data expanded.toList.map{k: K => (mA.get(k), Await.result(wrappedStore.get(k)))} } - def buildStoreRunMultiGetQueries[K, V](mA: Map[K, V], others: Set[K], reporter: ReadableStoreReporter[K, V]) = { + def buildStoreRunMultiGetQueries[K, V](mA: Map[K, V], others: Set[K], builder: (ReadableStore[K, V]) => ReadableStore[K, V]) = { val baseStore = ReadableStore.fromMap(mA) - val wrappedStore = ReportingReadableStore(baseStore, reporter) + val wrappedStore = builder(baseStore) val expanded: Set[K] = (mA.keySet ++ others) // We use call to list, or it keeps the results of the map as a set and we loose data (expanded.map{k => (k, mA.get(k))}.toMap, @@ -45,7 +50,7 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto } property("Stats store matches raw get for all queries") = forAll { (mA: Map[Int, String], others: Set[Int]) => - val reporter = new ReadableStoreReporter[Int, String] {} + def reporter(store: ReadableStore[Int, String]) = new DummyReporter[Int, String](store) val queryResults = buildStoreRunQueries(mA, others, reporter) queryResults.forall{case (a, b) => a == b} } @@ -53,7 +58,7 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto property("Present/Absent count matches") = forAll { (mA: Map[Int, String], others: Set[Int]) => var presentCount = 0 var absentCount = 0 - val reporter = new ReadableStoreReporter[Int, String] { + def reporter(store: ReadableStore[Int, String]) = new DummyReporter[Int, String](store) { override def traceGet(k: Int, request: Future[Option[String]]) = { request.map{ optV => optV match { @@ -71,7 +76,7 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto } property("Stats store matches raw get for multiget all queries") = forAll { (mA: Map[Int, String], others: Set[Int]) => - val reporter = new ReadableStoreReporter[Int, String] {} + def reporter(store: ReadableStore[Int, String]) = new DummyReporter[Int, String](store) val (mapRes, storeResults) = buildStoreRunMultiGetQueries(mA, others, reporter) mapRes.size == storeResults.size && mapRes.keySet.forall(k => mapRes.get(k) == storeResults.get(k)) @@ -80,7 +85,8 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto property("Present/Absent count matches in multiget") = forAll { (mA: Map[Int, String], others: Set[Int]) => var presentCount = 0 var absentCount = 0 - val reporter = new ReadableStoreReporter[Int, String] { + + def reporter(store: ReadableStore[Int, String]) = new DummyReporter[Int, String](store) { override def traceMultiGet[K1 <: Int](ks: Set[K1], request: Map[K1, Future[Option[String]]]) = { request.mapValues{fOptV => fOptV.map {optV => diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala index 736eb489..c0683ef3 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala @@ -27,10 +27,20 @@ import com.twitter.storehaus.algebra._ object ReportingStoreProperties extends Properties("ReportingStore") { def newStore[K, V] = new JMapStore[K, V] + class DummyReporter[K, V](val self: Store[K, V]) extends StoreProxy[K, V] with StoreReporter[K, V] { + def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) + def traceGet(k: K, request: Future[Option[V]]) = request.unit + + def tracePut(kv: (K, Option[V]), request: Future[Unit]) = request.unit + def traceMultiPut[K1 <: K](kvs: Map[K1, Option[V]], request: Map[K1, Future[Unit]]) = request.mapValues(_.unit) + } + property("Put Some/None count matches") = forAll { (inserts: Map[Int, Option[Int]]) => var putSomeCount = 0 var putNoneCount = 0 - val reporter = new StoreReporter[Int, Int] { + val baseStore = newStore[Int, Int] + + val wrappedStore = new DummyReporter[Int, Int](baseStore) { override def tracePut(kv: (Int, Option[Int]), request: Future[Unit]) = { Future { kv._2 match { @@ -40,8 +50,6 @@ object ReportingStoreProperties extends Properties("ReportingStore") { }.unit } } - val baseStore = newStore[Int, Int] - val wrappedStore = ReportingStore[Int, Int](baseStore, reporter) inserts.foreach{ i => wrappedStore.put(i._1, i._2) @@ -53,8 +61,10 @@ object ReportingStoreProperties extends Properties("ReportingStore") { property("MultiPut Some/None count matches") = forAll { (inserts: Map[Int, Option[Int]]) => var multiPutSomeCount = 0 var multiPutNoneCount = 0 - val reporter = new StoreReporter[Int, Int] { - override def traceMultiPut[K1 <: Int](kvs: Map[K1, Option[Int]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = { + val baseStore = newStore[Int, Int] + + val wrappedStore = new DummyReporter[Int, Int](baseStore) { + override def traceMultiPut[K1 <: Int](kvs: Map[K1, Option[Int]], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] = { kvs.mapValues {v => Future { v match { @@ -65,9 +75,6 @@ object ReportingStoreProperties extends Properties("ReportingStore") { } } } - val baseStore = newStore[Int, Int] - val wrappedStore = ReportingStore[Int, Int](baseStore, reporter) - wrappedStore.multiPut(inserts) From 064485fa9fdd3847b0742efbfcde63541ee0f8c6 Mon Sep 17 00:00:00 2001 From: Ian O Connell Date: Tue, 11 Mar 2014 14:56:06 -0700 Subject: [PATCH 4/5] Review comment changes --- .../algebra/reporting/Reporter.scala | 22 +++++++++++-------- .../ReportingMergeableStoreProperties.scala | 4 ++-- .../ReportingReadableStoreProperties.scala | 2 +- .../reporting/ReportingStoreProperties.scala | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala index 1e55d5bd..71b1df93 100644 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala @@ -18,7 +18,8 @@ package com.twitter.storehaus.algebra.reporting import com.twitter.storehaus.{Store, ReadableStore, WritableStore} import com.twitter.storehaus.algebra.Mergeable -import com.twitter.util.Future +import com.twitter.util.{Future, Time} + object Reporter { def sideEffect[T, U](params: U, f: Future[T], sideEffect: (U, Future[T]) => Future[Unit]): Future[T] = @@ -33,36 +34,39 @@ object Reporter { } } -trait ReadableStoreReporter[K, V] extends ReadableStore[K, V] { - def self: ReadableStore[K, V] +trait ReadableStoreReporter[S <: ReadableStore[K, V], K, V] extends ReadableStore[K, V] { + def self: S override def get(k: K): Future[Option[V]] = Reporter.sideEffect(k, self.get(k), traceGet) override def multiGet[K1 <: K](keys: Set[K1]) = Reporter.sideEffect(keys, self.multiGet(keys), traceMultiGet) def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] def traceGet(k: K, request: Future[Option[V]]): Future[Unit] + override def close(time: Time) = self.close(time) } -trait WritableStoreReporter[K, V] extends WritableStore[K, V] { - def self: WritableStore[K, V] +trait WritableStoreReporter[S <: WritableStore[K, V],K, V] extends WritableStore[K, V] { + def self: S override def put(kv: (K, V)): Future[Unit] = Reporter.sideEffect(kv, self.put(kv), tracePut) override def multiPut[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiPut(kvs), traceMultiPut) def tracePut(kv: (K, V), request: Future[Unit]): Future[Unit] def traceMultiPut[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] + override def close(time: Time) = self.close(time) } -trait MergeableReporter[K, V] extends Mergeable[K, V] { - def self: Mergeable[K, V] +trait MergeableReporter[S <: Mergeable[K, V],K, V] extends Mergeable[K, V] { + def self: S override def merge(kv: (K, V)) = Reporter.sideEffect(kv, self.merge(kv), traceMerge) override def multiMerge[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiMerge(kvs), traceMultiMerge) def traceMerge(kv: (K, V), request: Future[Option[V]]): Future[Unit] def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] + override def close(time: Time) = self.close(time) } -trait StoreReporter[K, V] extends ReadableStoreReporter[K, V] with WritableStoreReporter[K, Option[V]] { - def self: Store[K, V] +trait StoreReporter[S <: Store[K, V], K, V] extends ReadableStoreReporter[S, K, V] with WritableStoreReporter[S, K, Option[V]] { + def self: S } diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala index 6acb7cc3..8287a4c3 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingMergeableStoreProperties.scala @@ -29,7 +29,7 @@ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableS - class DummyReporter[K, V](val self: Mergeable[K, V]) extends MergeableProxy[K, V] with MergeableReporter[K, V] { + class DummyReporter[K, V](val self: Mergeable[K, V]) extends MergeableProxy[K, V] with MergeableReporter[Mergeable[K, V], K, V] { def traceMerge(kv: (K, V), request: Future[Option[V]]) = request.unit def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) } @@ -37,7 +37,7 @@ object ReportingMergeableStoreProperties extends Properties("ReportingMergeableS property("Mergable stat store obeys the mergeable store proporites") = mergeableStoreTest { val store = newStore[Int, Int] - new MergeableStoreProxy[Int, Int] with MergeableReporter[Int, Int] { + new MergeableStoreProxy[Int, Int] with MergeableReporter[Mergeable[Int, Int], Int, Int] { val self = store def traceMerge(kv: (Int, Int), request: Future[Option[Int]]) = request.unit def traceMultiMerge[K1 <: Int](kvs: Map[K1, Int], request: Map[K1, Future[Option[Int]]]) = request.mapValues(_.unit) diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala index 4d51c0bf..cc85bd34 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingReadableStoreProperties.scala @@ -27,7 +27,7 @@ object ReportingReadableStoreProperties extends Properties("ReportingReadableSto * get returns none when not in either store */ - class DummyReporter[K, V](val self: ReadableStore[K, V]) extends ReadableStoreProxy[K, V] with ReadableStoreReporter[K, V] { + class DummyReporter[K, V](val self: ReadableStore[K, V]) extends ReadableStoreProxy[K, V] with ReadableStoreReporter[ReadableStore[K, V], K, V] { def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) def traceGet(k: K, request: Future[Option[V]]) = request.unit } diff --git a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala index c0683ef3..e24144c7 100644 --- a/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala +++ b/storehaus-algebra/src/test/scala/com/twitter/storehaus/algebra/reporting/ReportingStoreProperties.scala @@ -27,7 +27,7 @@ import com.twitter.storehaus.algebra._ object ReportingStoreProperties extends Properties("ReportingStore") { def newStore[K, V] = new JMapStore[K, V] - class DummyReporter[K, V](val self: Store[K, V]) extends StoreProxy[K, V] with StoreReporter[K, V] { + class DummyReporter[K, V](val self: Store[K, V]) extends StoreProxy[K, V] with StoreReporter[Store[K, V], K, V] { def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]) = request.mapValues(_.unit) def traceGet(k: K, request: Future[Option[V]]) = request.unit From 5240f32c88406b2eac09df0bfeae58be85a39bf8 Mon Sep 17 00:00:00 2001 From: Ian O Connell Date: Wed, 12 Mar 2014 09:28:06 -0700 Subject: [PATCH 5/5] Added protected statements --- .../storehaus/algebra/reporting/Reporter.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala index 71b1df93..76bd69b3 100644 --- a/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala +++ b/storehaus-algebra/src/main/scala/com/twitter/storehaus/algebra/reporting/Reporter.scala @@ -39,8 +39,8 @@ trait ReadableStoreReporter[S <: ReadableStore[K, V], K, V] extends ReadableStor override def get(k: K): Future[Option[V]] = Reporter.sideEffect(k, self.get(k), traceGet) override def multiGet[K1 <: K](keys: Set[K1]) = Reporter.sideEffect(keys, self.multiGet(keys), traceMultiGet) - def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] - def traceGet(k: K, request: Future[Option[V]]): Future[Unit] + protected def traceMultiGet[K1 <: K](ks: Set[K1], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] + protected def traceGet(k: K, request: Future[Option[V]]): Future[Unit] override def close(time: Time) = self.close(time) } @@ -50,8 +50,8 @@ trait WritableStoreReporter[S <: WritableStore[K, V],K, V] extends WritableStore override def put(kv: (K, V)): Future[Unit] = Reporter.sideEffect(kv, self.put(kv), tracePut) override def multiPut[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiPut(kvs), traceMultiPut) - def tracePut(kv: (K, V), request: Future[Unit]): Future[Unit] - def traceMultiPut[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] + protected def tracePut(kv: (K, V), request: Future[Unit]): Future[Unit] + protected def traceMultiPut[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Unit]]): Map[K1, Future[Unit]] override def close(time: Time) = self.close(time) } @@ -61,8 +61,8 @@ trait MergeableReporter[S <: Mergeable[K, V],K, V] extends Mergeable[K, V] { override def merge(kv: (K, V)) = Reporter.sideEffect(kv, self.merge(kv), traceMerge) override def multiMerge[K1 <: K](kvs: Map[K1, V]) = Reporter.sideEffect(kvs, self.multiMerge(kvs), traceMultiMerge) - def traceMerge(kv: (K, V), request: Future[Option[V]]): Future[Unit] - def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] + protected def traceMerge(kv: (K, V), request: Future[Option[V]]): Future[Unit] + protected def traceMultiMerge[K1 <: K](kvs: Map[K1, V], request: Map[K1, Future[Option[V]]]): Map[K1, Future[Unit]] override def close(time: Time) = self.close(time) }