├── .gitignore ├── README.md ├── build.sbt ├── project ├── App.scala ├── assembly.sbt ├── build.properties └── plugins.sbt └── src ├── main ├── java │ ├── FilterFunction.java │ ├── ListUtil.java │ ├── MapFunction.java │ ├── MapSample.java │ ├── MyMap.java │ └── UglyJava.java ├── resources │ ├── application.conf │ ├── logback.xml │ └── quartz.properties ├── scala │ ├── ScalaMapSample.scala │ ├── adt │ │ ├── FunctorModule.scala │ │ ├── ListModule.scala │ │ ├── OptionalApp.scala │ │ ├── OptionalModule.scala │ │ └── TreeModule.scala │ ├── basicFunctions │ │ └── BasicFunctionModule.scala │ ├── cakePatternSimple │ │ ├── User.scala │ │ └── UserService.scala │ ├── cat │ │ └── CatApp.scala │ ├── collection │ │ └── collection.scala │ ├── combine │ │ └── Flow.scala │ ├── compose │ │ └── compose.scala │ ├── concurrency │ │ ├── Concurrency.scala │ │ ├── akka │ │ │ ├── account │ │ │ │ ├── AccountApp.scala │ │ │ │ ├── AccountAssistant.scala │ │ │ │ └── AccountManager.scala │ │ │ ├── cloc │ │ │ │ ├── ClocApp.scala │ │ │ │ ├── Collector.scala │ │ │ │ └── counter.scala │ │ │ ├── pingpang │ │ │ │ ├── Pang.scala │ │ │ │ ├── Ping.scala │ │ │ │ └── PingPangRoom.scala │ │ │ ├── simpleIO │ │ │ │ ├── GreetingActor.scala │ │ │ │ ├── MultiplyActor.scala │ │ │ │ ├── SimpleIOApp.scala │ │ │ │ └── SimpleIOStreamApp.scala │ │ │ └── timer │ │ │ │ └── SepTask.scala │ │ ├── akkaStream │ │ │ ├── Factorials.scala │ │ │ ├── MapUtil.scala │ │ │ └── WordCount.scala │ │ ├── future │ │ │ ├── DaXiong.scala │ │ │ ├── FutureAwait.scala │ │ │ ├── FutureSeq.scala │ │ │ ├── SimpleFuture.scala │ │ │ └── StrictTimedFuture.scala │ │ ├── futurePractice │ │ │ └── FuturePractice.scala │ │ └── par │ │ │ ├── CustomerRepository.scala │ │ │ ├── DataAggregator.scala │ │ │ ├── OrderRepository.scala │ │ │ └── package.scala │ ├── dci │ │ ├── Account.scala │ │ ├── AccountService.scala │ │ ├── LoginService.scala │ │ ├── TransferService.scala │ │ └── User.scala │ ├── ddd │ │ └── fp │ │ │ └── LoginModule.scala │ ├── diamondProblem │ │ └── A.scala │ ├── dup │ │ └── DupModule.scala │ ├── excercise │ │ └── fp │ │ │ └── Factory.scala │ ├── expressiveness │ │ ├── inherit │ │ │ ├── Client.scala │ │ │ └── Shape.scala │ │ ├── switchcase │ │ │ ├── Client.scala │ │ │ └── ShapeModule.scala │ │ └── typeclass │ │ │ ├── Client.scala │ │ │ ├── ShapeModule.scala │ │ │ └── mptc │ │ │ └── ConsModule.scala │ ├── fibs │ │ └── FibsModule.scala │ ├── fold │ │ ├── fold.scala │ │ └── sum.scala │ ├── fpbasic │ │ └── MyFunctor.scala │ ├── funcserv │ │ ├── akka │ │ │ ├── HSS.scala │ │ │ ├── MME.scala │ │ │ └── UE.scala │ │ └── prototype │ │ │ ├── HSS.scala │ │ │ ├── MME.scala │ │ │ ├── MMEApp.scala │ │ │ └── UE.scala │ ├── hoi4 │ │ └── Hoi4Helper.scala │ ├── hotelPractice │ │ └── fp │ │ │ └── HotelReservationService.scala │ ├── hr │ │ └── ExCalculator.scala │ ├── implicitSample │ │ └── ImplicitSample.scala │ ├── lift │ │ └── liftModule.scala │ ├── loanPattern │ │ ├── FileReadSupport.scala │ │ ├── FileTraverseSupport.scala │ │ ├── SampleTxtProcessor.scala │ │ ├── SampleTxtProcessorLoanImpl.scala │ │ └── SampleTxtProcessorLoanImplMk1.scala │ ├── monad │ │ ├── FileWriteSupport.scala │ │ ├── Persisted.scala │ │ └── StringPresentable.scala │ ├── myList │ │ └── MyList.scala │ ├── option │ │ └── OptionModule.scala │ ├── optionSample │ │ └── OptionFuncs.scala │ ├── optional │ │ └── Optional.scala │ ├── patternMatch │ │ ├── ifversion │ │ │ └── BinarySearchWithIf.scala │ │ └── sample │ │ │ └── PatternMatchingMain.scala │ ├── patterns │ │ ├── FileTransformer.scala │ │ ├── Persist.scala │ │ ├── ReadSupport.scala │ │ └── WriteSupport.scala │ ├── queryOptimizer │ │ └── QueryOptimizer.scala │ ├── reactiveComponent │ │ ├── Platform.scala │ │ ├── framework │ │ │ ├── Flow.scala │ │ │ ├── ReactiveComponent.scala │ │ │ └── Source.scala │ │ └── nbiot │ │ │ ├── dependency │ │ │ ├── L2Service.scala │ │ │ └── RBService.scala │ │ │ ├── flow │ │ │ ├── CellLoadBalanceCheck.scala │ │ │ ├── RBSetup.scala │ │ │ ├── RRCConnectionReject.scala │ │ │ ├── RRCConnectionSetup.scala │ │ │ ├── RRCInstanceSetup.scala │ │ │ ├── RRCLocalRelease.scala │ │ │ ├── RRCProcessing.scala │ │ │ ├── RRCProtoType.scala │ │ │ ├── RRCRejectL2Notify.scala │ │ │ └── package.scala │ │ │ └── source │ │ │ └── L2Source.scala │ ├── sample │ │ ├── Account.scala │ │ └── Segment.scala │ ├── scripting │ │ ├── ScriptLoader.scala │ │ └── Service.scala │ ├── slick │ │ ├── DBConfigProvider.scala │ │ ├── Database.scala │ │ ├── domain │ │ │ └── Order.scala │ │ ├── repo │ │ │ ├── CustomerRepo.scala │ │ │ ├── OrderRepo.scala │ │ │ └── ProductRepo.scala │ │ └── service │ │ │ └── OrderService.scala │ ├── smallPractice │ │ └── MyMaths.scala │ ├── sqlGen │ │ ├── DBConfigLoader.scala │ │ ├── Domain.scala │ │ ├── GranularitySQLGenerator.scala │ │ ├── ReportSQLGeneratorImpl.scala │ │ └── TimeSegmentSQLGenerator.scala │ ├── state │ │ └── RNG.scala │ ├── stats │ │ └── pregnent │ │ │ └── PregnancyAnalyze.scala │ ├── streaming │ │ └── CellStream.scala │ ├── temp │ │ ├── Codec.scala │ │ ├── UglyJavaVsScala.scala │ │ └── UnitList.scala │ ├── traitSample │ │ └── 武将.scala │ ├── typeParameter │ │ └── InstanceTypeCheck.scala │ ├── utils │ │ ├── Combinator.scala │ │ ├── JSONUtil.scala │ │ └── StreamBenchmark.scala │ ├── variants │ │ ├── Chef.scala │ │ └── Fruit.scala │ └── withLog │ │ └── WithLogModule.scala └── thrift │ ├── BinaryService.thrift │ └── DicService.thrift └── test ├── fixture └── words.txt ├── java ├── ListUtilJavaTest.java ├── MyMapTest.java └── UglyJavaTest.scala ├── resources ├── doOverSample.txt ├── logback-test.xml ├── sample.txt └── test.conf ├── scala ├── ListUtilTest.scala ├── MapSampleTest.scala ├── ScalaMapSampleSpec.scala ├── cakePatternSimple │ └── UserServiceTest.scala ├── concurrency │ ├── akkaStream │ │ └── MapUtilTest.scala │ ├── par │ │ ├── DataAggregatorSpec.scala │ │ ├── MockCustomerRepository.scala │ │ ├── MockCustomerRepositorySpec.scala │ │ ├── MockOrderRepository.scala │ │ └── OrderDataSelectorSpec.scala │ └── promise │ │ └── Double11.scala ├── diamondProblem │ └── DTest.scala ├── excercise │ └── fp │ │ └── FactorySpec.scala ├── expressiveness │ └── typeclass │ │ └── ClientTest.scala ├── ft │ └── sample │ │ └── AccountAcceptSpec.scala ├── hoi4 │ └── Hoi4HelperTest.scala ├── hotelPractice │ └── fp │ │ └── HotelReservationServiceTest.scala ├── hr │ └── ExCalculatorSpec.scala ├── it │ └── sample │ │ └── AccountScalaCheckSpec.scala ├── loanPattern │ ├── SampleTxtProcessorLoanImplTest.scala │ └── SampleTxtProcessorTest.scala ├── microbenchmarks │ ├── CaseClassCollectionToListListStringBenchmark.scala │ ├── CollectionAppendBenchmark.scala │ └── PerfOfWhile.scala ├── monad │ └── PersistedTest.scala ├── optionSample │ └── OptionFuncsTest.scala ├── queryOptimizer │ └── QueryOptimizerSpec.scala ├── reactiveComponent │ ├── framework │ │ └── FlowTest.scala │ └── nbiot │ │ └── flow │ │ ├── CellLoadBalanceCheckTest.scala │ │ └── RRCProcessingTest.scala ├── sample │ ├── AccountSpec.scala │ └── SegmentTest.scala ├── slick │ ├── repo │ │ ├── CustomerRepoTest.scala │ │ └── TestDatabase.scala │ └── service │ │ └── OrderServiceSpec.scala ├── smallPractice │ └── MyMathsSpec.scala ├── sqlGen │ ├── ReportSQLGeneratorImplTest.scala │ └── TimeSegmentSQLGeneratorTest.scala ├── state │ └── RNGTest.scala ├── stats │ └── pregnent │ │ └── PregnancyAnalyzeSpec.scala ├── tags │ └── Tags.scala ├── utils │ └── CombinatorsSpec.scala └── webtest │ └── BaiduSpec.scala └── script └── SQLGen.scala /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.cache 3 | /.classpath 4 | /.project 5 | *.log 6 | *.*~ 7 | /target 8 | /project/target 9 | /project/project/target 10 | /.settings 11 | *.DS_Store 12 | .ensime 13 | .idea* 14 | /tmp 15 | /temp 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # scalaSnippet 2 | [ ![Codeship Status for notyy/snippet](https://codeship.io/projects/6547f7b0-1ee8-0132-7537-727422619b42/status)](https://codeship.io/projects/35587) 3 | 4 | [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/notyy/scalaSnippet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | 6 | [![Codacy Badge](https://www.codacy.com/project/badge/086946f1190144f6b854ebc82e9b2c93)](https://www.codacy.com/public/notyycn/scalaSnippet) 7 | 8 | ***scala各种代码片段,是我在培训和指导scala开发的过程中提取而来*** 9 | 10 | * 运行sbt test会编译并运行自动化单元测试 11 | * sbt test-only -- -n FunctionTest 可运行打了FunctionTest tag的测试 12 | 13 | ## release note 14 | 2014.11.02 工程改名为scalaSnippet,我将另外弄一个giter8格式的工程模板 15 | 16 | 2014.10.21 增加了例子展示怎么使用par集合 17 | 18 | 2014.09.15 intellij的scala插件自动导入的sbt工程还是有种种问题,因此还是恢复了gen-idea插件,另外,删除了it和ft目录,还是用tag来区分吧 19 | 20 | 2014.08.24 配置了FunctionTest tag,作为用tag来区分测试的例子 21 | 22 | 2014.08.21 发现logback配置错误,现已改正 23 | 24 | 2014.08.15 在build.properties里指定sbt为1.3.5 25 | 26 | 2014.08.07 升级到scala2.11.2,相应的升级了第三方库,同时添加了大量代码例子 27 | 28 | 2014.05.03 将集成测试和功能测试分别放在src/it/scala和src/ft/scala下,现在用户可以执行sbt ft:test和sbt it:test运行不同的测试, 29 | sbt test仍然运行默认的src/test/scala下的单元测试。 30 | 31 | 2014.04.05 升级到sbt1.3.1, scala 2.10.4,之前的版本打了个2.9.2的tag,将不再维护 32 | 33 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | import de.johoop.jacoco4sbt._ 2 | import JacocoPlugin._ 3 | import sbt._ 4 | 5 | //com.twitter.scrooge.ScroogeSBT.newSettings 6 | // 7 | //scroogeBuildOptions in Compile := Seq("--finagle", "--verbose") 8 | // set the name of the project 9 | 10 | 11 | name := "scalaSnippet" 12 | 13 | version := "0.0.1" 14 | 15 | isSnapshot := true 16 | 17 | organization := "com.github.notyy" 18 | 19 | // set the Scala version used for the project 20 | scalaVersion := "2.12.3" 21 | 22 | resolvers ++= Seq( 23 | "Sonatype Releases" at "http://oss.sonatype.org/content/repositories/releases", 24 | "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots" 25 | ) 26 | 27 | libraryDependencies ++= Seq( 28 | "org.scalacheck" %% "scalacheck" % "1.13.4" % "test", 29 | "org.pegdown" % "pegdown" % "1.6.0" % "test", //used in html report 30 | "org.scalatest" %% "scalatest" % "2.2.1" % "test", 31 | "org.slf4j" % "slf4j-api" % "1.7.7", 32 | "com.storm-enroute" %% "scalameter" % "0.8.2" % "test", 33 | "ch.qos.logback" % "logback-classic" % "1.1.2", 34 | "com.typesafe.scala-logging" %% "scala-logging" % "3.7.2", 35 | "junit" % "junit" % "4.11" % "test", 36 | "com.novocode" % "junit-interface" % "0.11" % "test", 37 | "com.h2database" % "h2" % "1.3.176", 38 | "org.mockito" % "mockito-all" % "1.9.5" % "test,provided", 39 | "com.typesafe.akka" %% "akka-actor" % "2.5.3", 40 | "com.typesafe.akka" %% "akka-agent" % "2.5.3", 41 | "com.typesafe.akka" %% "akka-camel" % "2.5.3", 42 | "com.typesafe.akka" %% "akka-cluster" % "2.5.3", 43 | "com.typesafe.akka" %% "akka-cluster-metrics" % "2.5.3", 44 | "com.typesafe.akka" %% "akka-cluster-sharding" % "2.5.3", 45 | "com.typesafe.akka" %% "akka-cluster-tools" % "2.5.3", 46 | "com.typesafe.akka" %% "akka-distributed-data" % "2.5.3", 47 | "com.typesafe.akka" %% "akka-multi-node-testkit" % "2.5.3", 48 | "com.typesafe.akka" %% "akka-osgi" % "2.5.3", 49 | "com.typesafe.akka" %% "akka-persistence" % "2.5.3", 50 | "com.typesafe.akka" %% "akka-persistence-query" % "2.5.3", 51 | "com.typesafe.akka" %% "akka-persistence-tck" % "2.5.3", 52 | "com.typesafe.akka" %% "akka-remote" % "2.5.3", 53 | "com.typesafe.akka" %% "akka-slf4j" % "2.5.3", 54 | "com.typesafe.akka" %% "akka-stream" % "2.5.3", 55 | "com.typesafe.akka" %% "akka-stream-testkit" % "2.5.3", 56 | "com.typesafe.akka" %% "akka-testkit" % "2.5.3", 57 | "com.typesafe.akka" %% "akka-typed" % "2.5.3", 58 | "com.typesafe.akka" %% "akka-contrib" % "2.5.3", 59 | "com.googlecode.scalascriptengine" %% "scalascriptengine" % "1.3.11", 60 | "org.scala-lang" % "scala-compiler" % "2.12.3", 61 | "org.seleniumhq.selenium" % "selenium-java" % "2.35.0" % "test", 62 | "org.json4s" %% "json4s-native" % "3.5.3", 63 | "org.hamcrest" % "hamcrest-junit" %"2.0.0.0", 64 | "org.mockito" % "mockito-core" % "2.7.22", 65 | "org.quartz-scheduler" % "quartz" % "2.2.3", 66 | "org.quartz-scheduler" % "quartz-jobs" % "2.2.3", 67 | "com.typesafe.slick" %% "slick" % "3.2.1", 68 | "com.typesafe.slick" %% "slick-hikaricp" % "3.2.1", 69 | "com.github.dreamhead" % "moco-core" % "0.11.1" exclude("org.apache.httpcomponents", "httpclient"), 70 | "org.typelevel" %% "cats-core" % "1.0.0-RC1" 71 | ) 72 | 73 | // TODO reopen it later 74 | //testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework") 75 | 76 | logBuffered := false 77 | 78 | // reduce the maximum number of errors shown by the Scala compiler 79 | maxErrors := 20 80 | 81 | // increase the time between polling for file changes when using continuous execution 82 | pollInterval := 1000 83 | 84 | // append several options to the list of options passed to the Java compiler 85 | javacOptions ++= Seq("-source", "1.6", "-target", "1.6") 86 | 87 | // append -deprecation to the options passed to the Scala compiler 88 | scalacOptions += "-deprecation" 89 | 90 | incOptions := incOptions.value.withNameHashing(true) 91 | 92 | // set the initial commands when entering 'console' only 93 | // initialCommands in console := "import com.kaopua.recall._" 94 | 95 | // set the main class for packaging the main jar 96 | // 'run' will still auto-detect and prompt 97 | // change Compile to Test to set it for the test jar 98 | // mainClass in (Compile, packageBin) := Some("com.kaopua.recall.Main") 99 | 100 | // set the main class for the main 'run' task 101 | // change Compile to Test to set it for 'test:run' 102 | // mainClass in (Compile, run) := Some("com.kaopua.recall.Main") 103 | 104 | // set the main class for the main 'test:run' task 105 | // mainClass in (Test, run) := Some("com.kaopua.recall.Main") 106 | 107 | // disable updating dynamic revisions (including -SNAPSHOT versions) 108 | offline := true 109 | 110 | // set the prompt (for this build) to include the project id. 111 | shellPrompt in ThisBuild := { state => Project.extract(state).currentRef.project + "> " } 112 | 113 | // set the prompt (for the current project) to include the username 114 | shellPrompt := { state => System.getProperty("user.name") + "> " } 115 | 116 | // disable printing timing information, but still print [success] 117 | showTiming := false 118 | 119 | // disable printing a message indicating the success or failure of running a task 120 | showSuccess := false 121 | 122 | // change the format used for printing task completion time 123 | timingFormat := { 124 | import java.text.DateFormat 125 | DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT) 126 | } 127 | 128 | // only use a single thread for building 129 | parallelExecution := false 130 | 131 | 132 | // Use Scala from a directory on the filesystem instead of retrieving from a repository 133 | //scalaHome := Some(file("/home/user/scala/trunk/")) 134 | 135 | // don't aggregate clean (See FullConfiguration for aggregation details) 136 | aggregate in clean := false 137 | 138 | // only show warnings and errors on the screen for compilations. 139 | // this applies to both test:compile and compile and is Info by default 140 | logLevel in compile := Level.Info 141 | 142 | // only show warnings and errors on the screen for all tasks (the default is Info) 143 | // individual tasks can then be more verbose using the previous setting 144 | logLevel := Level.Info 145 | 146 | // only store messages at info and above (the default is Debug) 147 | // this is the logging level for replaying logging with 'last' 148 | persistLogLevel := Level.Info 149 | 150 | // only show 10 lines of stack traces 151 | traceLevel := 10 152 | 153 | exportJars := true 154 | 155 | // only show stack traces up to the first sbt stack frame 156 | traceLevel := 0 157 | 158 | // add SWT to the unmanaged classpath 159 | // unmanagedJars in Compile += file("/usr/share/java/swt.jar") 160 | 161 | // seq(oneJarSettings: _*) 162 | 163 | // libraryDependencies += "commons-lang" % "commons-lang" % "2.6" 164 | 165 | jacoco.settings 166 | 167 | // Execute tests in the current project serially 168 | // Tests from other projects may still run concurrently. 169 | parallelExecution in Test := false 170 | 171 | // create beautiful scala test report 172 | testOptions in Test ++= Seq( 173 | Tests.Argument(TestFrameworks.ScalaTest,"-h","target/html-unit-test-report"), 174 | Tests.Argument(TestFrameworks.ScalaTest,"-u","target/unit-test-reports"), 175 | Tests.Argument(TestFrameworks.ScalaTest,"-o"), 176 | Tests.Argument(TestFrameworks.ScalaTest,"-l","FunctionTest") 177 | ) 178 | 179 | testOptions in jacoco.Config ++= Seq( 180 | Tests.Argument(TestFrameworks.ScalaTest,"-h","target/html-unit-test-report"), 181 | Tests.Argument(TestFrameworks.ScalaTest,"-u","target/unit-test-reports"), 182 | Tests.Argument(TestFrameworks.ScalaTest,"-o"), 183 | Tests.Argument(TestFrameworks.ScalaTest,"-l","FunctionTest") 184 | ) 185 | 186 | testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v") 187 | 188 | packAutoSettings 189 | 190 | scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature","-language:higherKinds","-language:implicitConversions") -------------------------------------------------------------------------------- /project/App.scala: -------------------------------------------------------------------------------- 1 | object App { 2 | def myGen() = { 3 | val sum = 1 + 2 4 | println("in my new app:"+"sum: " + sum) 5 | } 6 | } -------------------------------------------------------------------------------- /project/assembly.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.16 2 | #sbt.version=1.1.1 -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") 2 | 3 | addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.1.6") 4 | 5 | addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0") 6 | 7 | resolvers += "Typesafe Repository" at "https://repo.typesafe.com/typesafe/releases/" 8 | 9 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.0") 10 | 11 | addSbtPlugin("com.codacy" % "sbt-codacy-coverage" % "1.0.3") 12 | 13 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.6.12") 14 | 15 | //addSbtPlugin("co`m.github.mwz" % "sbt-sonar" % "1.3.0") -------------------------------------------------------------------------------- /src/main/java/FilterFunction.java: -------------------------------------------------------------------------------- 1 | public interface FilterFunction { 2 | public boolean filter(A item); 3 | } 4 | -------------------------------------------------------------------------------- /src/main/java/ListUtil.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class ListUtil { 5 | public static List filter(List list, FilterFunction f) { 6 | List result = new ArrayList(); 7 | for (A item : list) { 8 | if (f.filter(item)) { 9 | result.add(item); 10 | } 11 | } 12 | return result; 13 | } 14 | 15 | public static List map(List list, MapFunction f) { 16 | List result = new ArrayList(); 17 | for(A item: list){ 18 | result.add(f.map(item)); 19 | } 20 | return result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/MapFunction.java: -------------------------------------------------------------------------------- 1 | public interface MapFunction { 2 | public B map(A item); 3 | } 4 | -------------------------------------------------------------------------------- /src/main/java/MapSample.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | /** 5 | * this demo shows simple collection manipulate(filter,map) in java 6 | */ 7 | public class MapSample { 8 | 9 | public List process(List list) { 10 | List result = new ArrayList(); 11 | for (int x : list) { 12 | if (x > 2) { 13 | result.add(x * 2); 14 | } 15 | } 16 | return result; 17 | } 18 | 19 | public List funcProcess(List list) { 20 | List filterRs = ListUtil.filter(list, new FilterFunction() { 21 | @Override 22 | public boolean filter(Integer item) { 23 | return item > 2; 24 | } 25 | }); 26 | List mapRs = ListUtil.map(filterRs, new MapFunction() { 27 | @Override 28 | public Integer map(Integer item) { 29 | return item * 2; 30 | } 31 | }); 32 | return mapRs; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/MyMap.java: -------------------------------------------------------------------------------- 1 | public interface MyMap { 2 | void put(String key, Object value); 3 | Object get(String key); 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/UglyJava.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | public class UglyJava { 6 | 7 | private String sumFilePath = "./temp/sum.txt"; 8 | 9 | public int getSum(List list) { 10 | if (list.isEmpty()) throw new IllegalArgumentException("empty list parameter!"); 11 | int sum = 0; 12 | List newList = new ArrayList(); 13 | for(int i : list){ 14 | if(i > 2){ 15 | int j = i * 2; 16 | sum += j; 17 | newList.add(j); 18 | } 19 | } 20 | list.clear(); 21 | list.addAll(newList); 22 | int prevSum = readSum(); 23 | int finalSum = sum + prevSum; 24 | saveSum(finalSum); 25 | return finalSum; 26 | } 27 | 28 | public int getSum1(List list) { 29 | int rs = 0; 30 | for (int i : 31 | list) { 32 | rs += i; 33 | } 34 | return rs; 35 | } 36 | 37 | private void saveSum(int sum){ 38 | BufferedWriter writer = null; 39 | try { 40 | File file = new File(sumFilePath); 41 | if (!file.exists()) { 42 | file.createNewFile(); 43 | } 44 | writer = new BufferedWriter(new FileWriter(file)); 45 | writer.write(String.valueOf(sum)); 46 | }catch (Exception e){ 47 | e.printStackTrace(); 48 | }finally { 49 | if(writer!=null) try { 50 | writer.close(); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | 57 | private int readSum() { 58 | int result = 0; 59 | BufferedReader reader = null; 60 | try { 61 | File file = new File(sumFilePath); 62 | if(!file.exists()) { 63 | return 0; 64 | } 65 | reader = new BufferedReader(new FileReader(sumFilePath)); 66 | String line = reader.readLine(); 67 | if (line == null || line.isEmpty()) { 68 | return 0; 69 | } else { 70 | result = Integer.valueOf(line); 71 | } 72 | }catch (IOException ex){ 73 | ex.printStackTrace(); 74 | }finally { 75 | if(reader != null) try { 76 | reader.close(); 77 | } catch (IOException e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | return result; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | h2mem1 { 2 | profile = "slick.jdbc.H2Profile$" 3 | db { 4 | // connectionPool = disabled 5 | driver = "org.h2.Driver" 6 | url = "jdbc:h2:mem:test1;DB_CLOSE_DELAY=-1" 7 | keepAliveConnection = true 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | logs/sbtTemplate.log 10 | 11 | %d{HH:mm:ss} %level %logger{36} - %msg%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/quartz.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notyy/scalaSnippet/b6e4827f32fce6efea30fff307b3e8f767504692/src/main/resources/quartz.properties -------------------------------------------------------------------------------- /src/main/scala/ScalaMapSample.scala: -------------------------------------------------------------------------------- 1 | object ScalaMapSample extends App { 2 | def process(xs: List[Int]): List[Int] = { 3 | xs.par.filter(x => { 4 | println(s"filtering $x in thread ${Thread.currentThread().getName}") 5 | x > 2 6 | }).map(x => { 7 | println(s"mapping $x in thread ${Thread.currentThread().getName}") 8 | x * 2 9 | }).toList 10 | } 11 | 12 | process(List(1,2,3,4,5)) 13 | } 14 | 15 | 16 | 17 | // xs.par.filter(_ > 2).map(_ * 2).toList 18 | -------------------------------------------------------------------------------- /src/main/scala/adt/FunctorModule.scala: -------------------------------------------------------------------------------- 1 | package adt 2 | 3 | import adt.ListModule.{Cons, MyList, MyNil} 4 | import adt.TreeModule.{Branch, Empty, Leaf, Tree} 5 | 6 | object FunctorModule { 7 | 8 | trait Functor[T[_]] { 9 | def map[A, B](t: T[A])(f: A => B): T[B] 10 | } 11 | 12 | implicit object FunctorMyTree extends Functor[Tree] { 13 | override def map[A, B](t: Tree[A])(f: (A) => B): Tree[B] = t match { 14 | case Leaf(v) => Leaf(f(v)) 15 | case Branch(l,v,r) => Branch(map(l)(f), f(v), map(r)(f)) 16 | case Empty => Empty 17 | } 18 | } 19 | 20 | implicit object FunctorMyList extends Functor[MyList] { 21 | override def map[A, B](t: MyList[A])(f: (A) => B): MyList[B] = t match { 22 | case MyNil => MyNil 23 | case Cons(h,tail) => Cons(f(h), map(tail)(f)) 24 | } 25 | } 26 | 27 | // implicit def Function1Functor[T]: Functor[({type l[a]=(T) => a})#l] = new Functor[({type l[a]=(T) => a})#l] { 28 | // override def map[A, B](t: (T) => A)(f: (A) => B): (T) => B = t andThen f 29 | // } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/scala/adt/ListModule.scala: -------------------------------------------------------------------------------- 1 | package adt 2 | 3 | object ListModule extends App { 4 | sealed trait MyList[+T]{ 5 | def head: T 6 | def tail: MyList[T] 7 | } 8 | 9 | case object MyNil extends MyList[Nothing] { 10 | override def head: Nothing = throw new IllegalArgumentException("no head on empty List") 11 | 12 | override def tail: MyList[Nothing] = throw new IllegalArgumentException("no tail on empty List") 13 | } 14 | 15 | case class Cons[T](head: T, tail: MyList[T]) extends MyList[T] 16 | 17 | println(MyNil) 18 | val list: Cons[Int] = Cons(1, Cons(2, Cons(3, MyNil))) 19 | println(list) 20 | println(list.head) 21 | println(list.tail) 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/adt/OptionalApp.scala: -------------------------------------------------------------------------------- 1 | package adt 2 | 3 | import adt.OptionalModule.{Just, NotExist, Optional} 4 | 5 | object OptionalApp extends App { 6 | 7 | case class User(name: String, age: Int, email: String) 8 | case class Address(road: String) 9 | 10 | def getUserByNameSimple: String => User = ??? 11 | 12 | def getUserByName: String => Optional[User] = { 13 | case "damotou" => Just(User("damotou", 39, "notyycn@gmail.com")) 14 | case _ => NotExist 15 | } 16 | 17 | def getAge: User => Int = _.age 18 | 19 | def fetchGetAgeFunc: Optional[User => Int] = Just((user:User) => user.age) 20 | 21 | def getEmail: User => Optional[String] = ??? 22 | def getAddress: String => Optional[Address] = ??? 23 | 24 | getUserByName("damotou").map(getAge) 25 | 26 | def lift[A,B]: (A => B) => (Optional[A] => Optional[B]) = f => { 27 | case Just(v) => Just(f(v)) 28 | case NotExist => NotExist 29 | } 30 | 31 | lift(getAge)(getUserByName("damotou")) 32 | 33 | val address:Optional[Address] = getUserByName("damotou").flatMap(getEmail).flatMap(getAddress) 34 | val address1:Optional[Address] = for{ 35 | user <- getUserByName("damotou") 36 | email <- getEmail(user) 37 | address <- getAddress(email) 38 | } yield address 39 | 40 | 41 | // getUserByName("damotou") match { 42 | // case Just(user) => getEmail(user) match { 43 | // case Just(email) => getAddress(email) 44 | // case NotExist => NotExist 45 | // } 46 | // case NotExist => NotExist 47 | // } 48 | 49 | // getUserByName("damotou") match { 50 | // case Just(user) => fetchGetAgeFunc match { 51 | // case Just(func) => Just(func(user)) 52 | // case NotExist => NotExist 53 | // } 54 | // case NotExist => NotExist 55 | // } 56 | getUserByName("damotou") <%> fetchGetAgeFunc 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/scala/adt/OptionalModule.scala: -------------------------------------------------------------------------------- 1 | package adt 2 | 3 | object OptionalModule { 4 | 5 | sealed trait Optional[+T]{ 6 | def get: T 7 | def isEmpty: Boolean 8 | def getOrElse[B >: T](default: B):B 9 | def map[R](f: T => R): Optional[R] 10 | def <%>[R](optFunc: Optional[T => R]): Optional[R] 11 | def flatMap[R](f: T => Optional[R]): Optional[R] 12 | } 13 | 14 | case class Just[T](value: T) extends Optional[T] { 15 | override def get: T = value 16 | 17 | override def isEmpty: Boolean = false 18 | 19 | override def getOrElse[B >: T](default: B): B = value 20 | 21 | override def map[R](f: (T) => R): Optional[R] = Just(f(value)) 22 | 23 | override def <%>[R](optFunc: Optional[(T) => R]): Optional[R] = { 24 | if(optFunc.isEmpty) NotExist else Just(optFunc.get(value)) 25 | } 26 | 27 | override def flatMap[R](f: (T) => Optional[R]): Optional[R] = { 28 | val optResult = f(value) 29 | if(optResult.isEmpty) NotExist else optResult 30 | } 31 | } 32 | 33 | case object NotExist extends Optional[Nothing] { 34 | override def get: Nothing = ??? 35 | 36 | override def isEmpty: Boolean = true 37 | 38 | override def getOrElse[B >: Nothing](default: B): B = default 39 | 40 | override def map[R](f: (Nothing) => R): Optional[R] = NotExist 41 | 42 | override def <%>[R](optFunc: Optional[(Nothing) => R]): Optional[R] = NotExist 43 | 44 | override def flatMap[R](f: (Nothing) => Optional[R]): Optional[R] = NotExist 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/adt/TreeModule.scala: -------------------------------------------------------------------------------- 1 | package adt 2 | 3 | import adt.FunctorModule.Functor 4 | import adt.ListModule.{Cons, MyList, MyNil} 5 | import adt.OptionalModule.{Just, NotExist, Optional} 6 | 7 | object TreeModule extends App { 8 | 9 | sealed trait Tree[+T] { 10 | def map[R](f: T => R): Tree[R] 11 | } 12 | 13 | case class Branch[T](left: Tree[T], value: T, right: Tree[T]) extends Tree[T] { 14 | override def map[R](f: (T) => R): Tree[R] = Branch(left.map(f), f(value), right.map(f)) 15 | } 16 | 17 | case class Leaf[T](value: T) extends Tree[T] { 18 | override def map[R](f: (T) => R): Tree[R] = Leaf(f(value)) 19 | } 20 | 21 | case object Empty extends Tree[Nothing] { 22 | override def map[R](f: (Nothing) => R): Tree[R] = Empty 23 | } 24 | 25 | private val bigTree: Tree[Int] = Branch(Leaf(2), 1, Branch(Leaf(3), 4, Leaf(5))) 26 | 27 | def rightMost[T]: Tree[T] => Optional[T] = { 28 | case Leaf(v) => Just(v) 29 | case Branch(_, _, right) => rightMost(right) 30 | case Empty => NotExist 31 | } 32 | 33 | println(s"right most value is ${rightMost(bigTree).map(_ * 2).map(_ + 1).getOrElse(-1)}") 34 | 35 | def allMulti2(tree: Tree[Int]): Tree[Int] = map(tree)(_ * 2) 36 | 37 | // def map[A,B](tree: Tree[A])(f: A => B): Tree[B] = tree.map(f) 38 | 39 | println(allMulti2(bigTree)) 40 | 41 | 42 | def map[T[_], A, B](t: T[A])(f: A => B)(implicit functor: Functor[T]): T[B] = { 43 | functor.map(t)(f) 44 | } 45 | 46 | import FunctorModule._ 47 | 48 | println(map(bigTree)(_ * 2)) 49 | 50 | val list: MyList[Int] = Cons(1, Cons(2, Cons(3, MyNil))) 51 | println(map(list)(_ * 2)) 52 | } 53 | -------------------------------------------------------------------------------- /src/main/scala/basicFunctions/BasicFunctionModule.scala: -------------------------------------------------------------------------------- 1 | package basicFunctions 2 | 3 | object BasicFunctionModule { 4 | def add1: Int => Int = _ + 1 5 | 6 | def multi2: Int => Int = _ * 2 7 | 8 | def int2String: Int => String = _.toString 9 | 10 | def add1ThenMulti2: Int => Int = x => multi2(add1(x)) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/cakePatternSimple/User.scala: -------------------------------------------------------------------------------- 1 | package cakePatternSimple 2 | 3 | case class User(name: String) -------------------------------------------------------------------------------- /src/main/scala/cakePatternSimple/UserService.scala: -------------------------------------------------------------------------------- 1 | package cakePatternSimple 2 | 3 | trait UserService { 4 | def findAll: List[User] 5 | } 6 | 7 | trait UserRepository { 8 | def loadUser: List[User] 9 | } 10 | 11 | trait TransactionManager { 12 | def executeSQL(sql: String): List[User] 13 | } 14 | 15 | trait TransactionManagerImpl extends TransactionManager{ 16 | override def executeSQL(sql: String): List[User] = ??? 17 | } 18 | 19 | trait UserRepositoryImpl extends UserRepository{ 20 | this: TransactionManager => 21 | override def loadUser: List[User] = executeSQL("SELECT * FROM user") 22 | } 23 | 24 | trait DefaultUserRepositoryImpl extends UserRepositoryImpl with TransactionManagerImpl 25 | trait UserServiceImpl extends UserService { 26 | this: UserRepository => 27 | override def findAll: List[User] = loadUser 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/scala/cat/CatApp.scala: -------------------------------------------------------------------------------- 1 | package cat 2 | 3 | import cats._ 4 | object CatApp extends App { 5 | def combineAll[A](list: List[A])(implicit a: Monoid[A]): A = list.foldRight(a.empty)(a.combine) 6 | 7 | implicit val intAdditionMonoid: Monoid[Int] = new Monoid[Int] { 8 | def empty: Int = 0 9 | def combine(x: Int, y: Int): Int = x + y 10 | } 11 | 12 | //have to comment this out, or the combine pair example will fail 13 | // implicit val intMultiMonoid: Monoid[Int] = new Monoid[Int] { 14 | // override def empty:Int = 1 15 | // override def combine(x: Int, y: Int) = x * y 16 | // } 17 | 18 | implicit val strAdditionMonoid: Monoid[String] = new Monoid[String] { 19 | def empty: String = "" 20 | def combine(x: String, y: String): String = x ++ y 21 | } 22 | 23 | implicit def pairMonoid[A,B](implicit a: Monoid[A], b: Monoid[B]): Monoid[(A,B)] = 24 | new Monoid[(A,B)] { 25 | override def empty: (A, B) = (a.empty, b.empty) 26 | 27 | override def combine(x: (A, B), y: (A, B)): (A, B) = { 28 | (a.combine(x._1, y._1), b.combine(x._2,y._2)) 29 | } 30 | } 31 | 32 | println(combineAll(List(1,2,3,4,5))(intAdditionMonoid)) 33 | // println(combineAll(List(1,2,3,4,5))(intMultiMonoid)) 34 | println(combineAll(List("1","2","3"))) 35 | println(combineAll(List((1,2),(3,4),(5,6)))) 36 | println(combineAll(List((1,"2"),(3,"4"),(5,"6")))) 37 | println(combineAll(List(("1",2),("3",4),("5",6)))) 38 | println(combineAll(List(("1","2"),("3","4"),("5","6")))) 39 | } 40 | -------------------------------------------------------------------------------- /src/main/scala/collection/collection.scala: -------------------------------------------------------------------------------- 1 | package collection 2 | 3 | object collection extends App { 4 | //dup(List(1,2,3)) should be List(1,1,2,2,3,3) 5 | // def dup[A]: List[A] => List[A] = ??? 6 | 7 | def dup[A]: List[A] => List[A] = _.map(x => List(x,x)).flatten 8 | 9 | println(dup(List(1,2,3))) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/combine/Flow.scala: -------------------------------------------------------------------------------- 1 | package combine 2 | 3 | trait Flow[A,B] 4 | case class LastStep[A,B](f: A => B) extends Flow[A,B] 5 | case class CombinedSteps[A,B,C](head: A => B, tail: Flow[B,C]) -------------------------------------------------------------------------------- /src/main/scala/compose/compose.scala: -------------------------------------------------------------------------------- 1 | package compose 2 | import basicFunctions.BasicFunctionModule._ 3 | 4 | object compose extends App { 5 | 6 | def compose[A, B, C](f1: A => B)(f2: B => C): A => C = x => f2(f1(x)) 7 | 8 | import withLog.WithLogModule._ 9 | withLog("add1thenMulti2")(compose(add1)(multi2))(2) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/Concurrency.scala: -------------------------------------------------------------------------------- 1 | package concurrency 2 | 3 | object Concurrency { 4 | def sum(xs: List[Int]): Int = xs match { 5 | case Nil => 0 6 | case (x :: Nil) => x 7 | case _ => { 8 | val (l,r) = xs.splitAt(xs.length / 2) 9 | sum(l) + sum(r) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/account/AccountApp.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.account 2 | 3 | import akka.actor.{ActorSystem, PoisonPill, Props} 4 | import com.typesafe.scalalogging.StrictLogging 5 | 6 | object AccountApp extends App with StrictLogging { 7 | val system = ActorSystem("accountSystem") 8 | val agent1 = system.actorOf(Props[AccountAssistant], "agent1") 9 | logger.info("start") 10 | agent1 ! Create("xx", 50) 11 | agent1 ! Create("yy", 150) 12 | agent1 ! Create("zz", 250) 13 | agent1 ! Increase("xx", 20) 14 | agent1 ! Decrease("xx", 10) 15 | agent1 ! Query("xx") 16 | agent1 ! Report 17 | agent1 ! PoisonPill 18 | Thread.sleep(1000) 19 | system.terminate() 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/account/AccountAssistant.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.account 2 | 3 | import akka.actor.{Actor, ActorLogging} 4 | 5 | import scala.collection.mutable 6 | 7 | case class Create(name: String, balance: Double) 8 | 9 | //开户,暂时以name为key,所以不能重复 10 | case class Destroy(name: String) 11 | 12 | //销户 13 | case class Increase(name: String, amount: Double) 14 | 15 | case class Decrease(name: String, amount: Double) 16 | 17 | case class Query(name: String) 18 | 19 | case object Report 20 | 21 | class AccountAssistant extends Actor with ActorLogging{ 22 | var accounts: mutable.Map[String, Double] = mutable.Map() 23 | override def receive: Receive = { 24 | case Create(name,balance) => accounts += (name -> balance) 25 | case Destroy(name) => accounts -= name 26 | case Increase(name,amount) => accounts.update(name, accounts(name) + amount) 27 | case Decrease(name,amount) => accounts.update(name, accounts(name) - amount) 28 | case Query(name) => log.info(s"balance in $name is ${accounts(name)}") 29 | case Report => { 30 | log.info(s"accounts informations:") 31 | accounts.foreach{ 32 | case (name, balance) => log.info(s" $name $balance") 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/account/AccountManager.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.account 2 | 3 | import akka.actor.{ActorRef, Props, Actor, ActorLogging} 4 | 5 | class AccountManager extends Actor with ActorLogging { 6 | val assistants = (1 to 5).map { 7 | i => context.actorOf(Props[AccountAssistant], s"assistant$i") 8 | } 9 | 10 | var current = 0 11 | 12 | def next: ActorRef = { 13 | if (current < 4) { 14 | current += 1 15 | } else { 16 | current = 0 17 | } 18 | assistants(current) 19 | } 20 | 21 | override def receive: Receive = { 22 | case c: Create => next ! c 23 | case Report => assistants.foreach(_ ! Report) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/cloc/ClocApp.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.cloc 2 | 3 | import akka.actor.{ActorSystem, Props} 4 | import com.typesafe.scalalogging.StrictLogging 5 | 6 | object ClocApp extends App with StrictLogging { 7 | val system = ActorSystem("cloc") 8 | val collector = system.actorOf(Props[Collector],"collector") 9 | collector ! Collect("/Users/twer/source/data1") 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/cloc/Collector.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.cloc 2 | 3 | import java.io.File 4 | 5 | import akka.actor.Actor.Receive 6 | import akka.actor.{Props, ActorLogging, Actor} 7 | import concurrency.akka.pingpang.Ping 8 | 9 | case class Collect(directory: String) 10 | case class Report(filePath: String, loc: Int) 11 | 12 | class Collector extends Actor with ActorLogging { 13 | 14 | override def receive: Receive = { 15 | case Collect(dir) => { 16 | val files = new File(dir).listFiles().filter(_.isFile) 17 | files.foreach(file => { 18 | context.actorOf(Props[Counter],file.getName) ! Count(file.getPath) 19 | }) 20 | } 21 | case Report(filePath, loc) => log.info(s"$filePath has $loc lines of code") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/cloc/counter.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.cloc 2 | 3 | import akka.actor.{Actor, ActorLogging} 4 | 5 | import scala.io.Source 6 | 7 | case class Count(path: String) 8 | 9 | class Counter extends Actor with ActorLogging{ 10 | override def receive: Receive = { 11 | case Count(path) => { 12 | val loc = Source.fromFile(path).getLines().length 13 | sender() ! Report(path, loc) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/pingpang/Pang.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.pingpang 2 | 3 | import akka.actor.{Actor, ActorLogging} 4 | 5 | class Pang extends Actor with ActorLogging { 6 | override def receive: Receive = { 7 | case "Ping!" => { 8 | log.info("Ping! received") 9 | sender() ! "Pang!" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/pingpang/Ping.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.pingpang 2 | 3 | import akka.actor.{ActorRef, ActorLogging, Actor} 4 | 5 | case class Start(opponent: ActorRef) 6 | 7 | class Ping extends Actor with ActorLogging { 8 | private var count = 0 9 | 10 | override def receive: Receive = { 11 | case Start(opponent) => { 12 | log.info("starting...") 13 | opponent ! "Ping!" 14 | } 15 | case "Pang!" => { 16 | count += 1 17 | log.info(s"Pang! received $count times") 18 | if (count >= 10) { 19 | context become tired 20 | } 21 | sender() ! "Ping!" 22 | } 23 | } 24 | 25 | def tired: Receive = { 26 | case _ => { 27 | log.info("already tired") 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/pingpang/PingPangRoom.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.pingpang 2 | 3 | import akka.actor.{ActorSystem, Props} 4 | import com.typesafe.scalalogging.StrictLogging 5 | 6 | object PingPangRoom extends App with StrictLogging { 7 | val system = ActorSystem("pingpang") 8 | val ping = system.actorOf(Props[Ping], "ping") 9 | val pang = system.actorOf(Props[Pang], "pang") 10 | ping ! Start(pang) 11 | logger.info("watching") 12 | Thread.sleep(2000) 13 | system.terminate() 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/simpleIO/GreetingActor.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.simpleIO 2 | 3 | import akka.actor.{Actor, Props} 4 | import com.typesafe.scalalogging.StrictLogging 5 | import concurrency.akka.simpleIO.GreetingActor.{GreetResp, GreetingReq} 6 | 7 | object GreetingActor { 8 | def props():Props = Props(new GreetingActor) 9 | 10 | case class GreetingReq(value: String) 11 | case class GreetResp(value: String) 12 | } 13 | 14 | class GreetingActor extends Actor with StrictLogging { 15 | 16 | override def preStart(): Unit = { 17 | logger.info("restarting") 18 | } 19 | 20 | override def receive: Receive = { 21 | case GreetingReq(v) => { 22 | if(v == "222") { 23 | throw new IllegalArgumentException("can't process 222") 24 | } else 25 | sender() ! GreetResp(s"hello, your result is $v") 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/simpleIO/MultiplyActor.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.simpleIO 2 | 3 | import akka.actor.SupervisorStrategy.{Escalate, Restart, Resume, Stop} 4 | import akka.actor.{Actor, ActorRef, OneForOneStrategy, Props} 5 | import com.typesafe.scalalogging.StrictLogging 6 | import concurrency.akka.simpleIO.GreetingActor.{GreetResp, GreetingReq} 7 | import concurrency.akka.simpleIO.MultiplyActor.NumberInput 8 | 9 | import scala.concurrent.duration._ 10 | import scala.language.postfixOps 11 | 12 | object MultiplyActor { 13 | def props(): Props = Props(new MultiplyActor) 14 | 15 | case class NumberInput(num: Int) 16 | } 17 | 18 | class MultiplyActor extends Actor with StrictLogging { 19 | 20 | override val supervisorStrategy = 21 | OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { 22 | case _: ArithmeticException => Resume 23 | case _: NullPointerException => Restart 24 | case _: IllegalArgumentException => Stop 25 | case _: Exception => Escalate 26 | } 27 | 28 | val greetingActor: ActorRef = context.actorOf(GreetingActor.props()) 29 | // var asker: Option[ActorRef] = None 30 | 31 | override def receive: Receive = { 32 | case NumberInput(i) => { 33 | // asker = Some(sender()) 34 | val v = i * 2 35 | greetingActor ! GreetingReq(v.toString) 36 | } 37 | case GreetResp(v) => { 38 | // asker.foreach(_ ! v) 39 | logger.info(v) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/simpleIO/SimpleIOApp.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.simpleIO 2 | 3 | import akka.actor.{ActorRef, ActorSystem} 4 | import com.typesafe.scalalogging.StrictLogging 5 | import concurrency.akka.simpleIO.MultiplyActor.NumberInput 6 | 7 | import scala.io.StdIn 8 | 9 | object SimpleIOApp extends App with StrictLogging { 10 | val system = ActorSystem("SimpleIOProcessing") 11 | val multiplyActor: ActorRef = system.actorOf(MultiplyActor.props()) 12 | 13 | var shouldContinue = true 14 | try { 15 | while (shouldContinue) { 16 | logger.info("please input numbers to be processed, input :q to quit") 17 | val input = StdIn.readLine() 18 | if (input == ":q") { 19 | shouldContinue = false 20 | } else { 21 | multiplyActor ! NumberInput(input.toInt) 22 | // implicit val timeout: Timeout = 5.seconds 23 | // implicit val dispatcher = system.dispatcher 24 | // val rs = multiplyActor ? NumberInput(input.toInt) 25 | // rs.mapTo[String].foreach(v => logger.info(v)) 26 | // logger.info(Await.result(rs.mapTo[String], 5 seconds)) 27 | } 28 | } 29 | } finally { 30 | println("good bye!") 31 | system.terminate() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/simpleIO/SimpleIOStreamApp.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.simpleIO 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.scaladsl.{Flow, Sink, Source} 5 | import akka.stream.{ActorMaterializer, OverflowStrategy, ThrottleMode} 6 | import akka.{Done, NotUsed} 7 | import com.typesafe.scalalogging.StrictLogging 8 | 9 | import scala.concurrent.Future 10 | import scala.concurrent.duration._ 11 | import scala.io.StdIn 12 | import scala.language.postfixOps 13 | 14 | object SimpleIOStreamApp extends App with StrictLogging { 15 | implicit val system = ActorSystem("CodebaseAnalyzer") 16 | implicit val materializer = ActorMaterializer() 17 | implicit val ec = system.dispatcher 18 | 19 | logger.info("please input numbers to be processed") 20 | 21 | private def printResult(s: String) = { 22 | logger.info(s) 23 | logger.info("please input numbers to be processed") 24 | } 25 | 26 | // Source.fromIterator(() => Iterator.continually(StdIn.readLine())) 27 | // .map(_.toInt * 2).map(v => s"hello, your result is $v") 28 | // .runForeach(printResult) 29 | // 30 | val source: Source[String, NotUsed] = Source.fromIterator(() => Iterator.continually(StdIn.readLine())) 31 | val flow: Flow[String, String, NotUsed] = 32 | Flow[String].buffer(1, OverflowStrategy.backpressure) 33 | .throttle(1, 1 second,1, ThrottleMode.shaping) 34 | .map{ i => i.toInt * 2}.map { v => 35 | s"hello, your result is $v" 36 | } 37 | val sink: Sink[String, Future[Done]] = Sink.foreach[String]{ rs => 38 | printResult(rs) 39 | } 40 | // 41 | val listSource = Source.fromIterator(() => (1 to 100).map(_.toString).toIterator) 42 | val tickSource = Source.tick(0 second, 200 millis, 0) 43 | val source1 = listSource.zip(tickSource).map(_._1).buffer(3, OverflowStrategy.dropNew) 44 | // 45 | source1.runWith(flow to sink) 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akka/timer/SepTask.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akka.timer 2 | 3 | import akka.actor.{Actor, ActorSystem, PoisonPill, Props} 4 | import com.typesafe.scalalogging.StrictLogging 5 | 6 | case object STOP 7 | case object WORK 8 | 9 | class SepTask extends Actor with StrictLogging { 10 | var working = true 11 | var count = 1 12 | 13 | override def receive: Receive = { 14 | case STOP => { 15 | logger.info("get STOP order") 16 | working = false 17 | logger.info("work stopped") 18 | } 19 | case WORK if working => { 20 | logger.info("get WORK order") 21 | logger.info(s"calc $count") 22 | Thread.sleep(1000) 23 | count += 1 24 | self ! WORK 25 | logger.info("work done") 26 | } 27 | case x => logger.info(s"ignore order $x") 28 | } 29 | 30 | //this proves that the following loop always occupy thread, 31 | // that the STOP message doesn't have chance to be processed 32 | // while(working){ 33 | // logger.info(s"calc $count") 34 | // Thread.sleep(1000) 35 | // count += 1 36 | // } 37 | } 38 | 39 | object SepTaskSample extends App with StrictLogging { 40 | val system = ActorSystem("pingpang") 41 | val sepTask = system.actorOf(Props[SepTask], "task1") 42 | logger.info("start!") 43 | sepTask ! WORK 44 | Thread.sleep(3000) 45 | sepTask ! STOP 46 | Thread.sleep(3000) 47 | sepTask ! PoisonPill 48 | Thread.sleep(1000) 49 | system.terminate() 50 | } 51 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akkaStream/Factorials.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akkaStream 2 | 3 | import java.nio.file.Paths 4 | 5 | import akka.NotUsed 6 | import akka.actor.ActorSystem 7 | import akka.stream._ 8 | import akka.stream.scaladsl._ 9 | import akka.util.ByteString 10 | 11 | import scala.concurrent.{Await, Future} 12 | import scala.concurrent.duration._ 13 | import scala.language.postfixOps 14 | 15 | object Factorials extends App { 16 | 17 | implicit val system = ActorSystem("QuickStart") 18 | implicit val materializer = ActorMaterializer() 19 | 20 | val source: Source[Int, NotUsed] = Source(1 to 100) 21 | source.runForeach(println) 22 | 23 | val factorials = source.scan(BigInt(1))((acc, next) => acc * next) 24 | 25 | def lineSink(fileName: String): Sink[String, Future[IOResult]] = { 26 | Flow[String] 27 | .map(num => ByteString(s"$num\n")) 28 | .toMat(FileIO.toPath(Paths.get(fileName)))(Keep.right) 29 | } 30 | 31 | Await.ready(factorials.map(_.toString) 32 | .runWith(lineSink("temp/factorials2.txt")), 3 second) 33 | 34 | system.terminate() 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akkaStream/MapUtil.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akkaStream 2 | 3 | object MapUtil { 4 | def mergeMaps[K,V](map1: Map[K, V], map2: Map[K, V])(f:(V,V) => V): Map[K, V] = { 5 | map2.foldLeft(map1) { case (acc, (k, v)) => 6 | if (acc.contains(k)) { 7 | acc.updated(k, f(acc(k), v)) 8 | } else { 9 | acc.updated(k, v) 10 | } 11 | } 12 | } 13 | 14 | def mergeMaps[K,V](map1: Map[K, V], map2: Map[K, V],map3: Map[K,V]*)(f:(V,V) => V): Map[K, V] = { 15 | map3.foldLeft(mergeMaps(map1,map2)(f)){ (acc,m) => 16 | mergeMaps(acc,m)(f) 17 | } 18 | } 19 | implicit class MergeableMap[K,V](map1: Map[K, V]){ 20 | def merge(map2: Map[K, V])(f:(V,V) => V): Map[K, V] = mergeMaps(map1,map2)(f) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/akkaStream/WordCount.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akkaStream 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream.scaladsl.Source 6 | import com.typesafe.scalalogging.StrictLogging 7 | import concurrency.akkaStream.MapUtil._ 8 | 9 | object WordCount extends App with StrictLogging { 10 | implicit val system = ActorSystem("WordCount") 11 | implicit val materializer = ActorMaterializer() 12 | implicit val ec = system.dispatcher 13 | 14 | val path = args(0) 15 | 16 | val source = Source.fromIterator(() => scala.io.Source.fromFile(path).getLines()) 17 | val flow = source.map(_.split(" ").foldLeft(Map[String, Int]()) { (wordCountMap, word) => 18 | if (wordCountMap.contains(word)) { 19 | wordCountMap.updated(word, wordCountMap(word) + 1) 20 | } else { 21 | wordCountMap.updated(word, 1) 22 | } 23 | }) 24 | .reduce((wordCountMap1, wordCountMap2) => mergeMaps(wordCountMap1, wordCountMap2)(_ + _)) 25 | 26 | logger.info("flow is ready to run") 27 | val result = flow.runForeach(println) 28 | result.onComplete { 29 | rs => 30 | println(s"complete: $rs") 31 | system.terminate() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/future/DaXiong.scala: -------------------------------------------------------------------------------- 1 | package concurrency.future 2 | 3 | import java.util.Date 4 | 5 | import com.typesafe.scalalogging.LazyLogging 6 | 7 | case class Money(amount: Double) 8 | 9 | case class Shoe(brand: String) 10 | 11 | case class BasketBall(id: Int) 12 | 13 | object 大雄 extends App with LazyLogging { 14 | val start = new Date().getTime 15 | takeCloth() 16 | val money = takeMoneyFromBank(500) 17 | buyShoesFromHongkong(money) 18 | takeBasketBall() 19 | playBasketBall() 20 | val end = new Date().getTime 21 | logger.info(s"total duration: ${end - start}") 22 | 23 | def takeCloth(): Unit = logger.info("taking up adidas") 24 | 25 | def takeBasketBall(): Unit = { 26 | logger.info("taking basketBall") 27 | val basketBall = borrowFrom静香() 28 | logger.info(s"got basketBall $basketBall") 29 | } 30 | 31 | def borrowFrom静香(): BasketBall = { 32 | logger.info("borrowing basketBall from 静香") 33 | Thread.sleep(5000) 34 | val basketBall = BasketBall(1) 35 | logger.info(s"basketBall $basketBall successfully borrowed from XiaoHong") 36 | basketBall 37 | } 38 | 39 | def buyShoesFromHongkong(money: Money): Shoe = { 40 | logger.info("buying shoes from hongkong") 41 | Thread.sleep(2000) 42 | val shoes = Shoe("Asics") 43 | logger.info(s"shoes bought from hongkong: $shoes") 44 | shoes 45 | } 46 | 47 | def takeMoneyFromBank(amount: Double): Money = { 48 | logger.info("taking money from bank") 49 | Thread.sleep(2000) 50 | val money = Money(amount) 51 | logger.info(s"money taken from bank $money") 52 | money 53 | } 54 | 55 | def playBasketBall() = println("wahahaha!!!") 56 | 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/future/FutureAwait.scala: -------------------------------------------------------------------------------- 1 | package concurrency.future 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | 5 | import scala.concurrent.{Await, Future} 6 | import scala.concurrent.duration._ 7 | import scala.language.postfixOps 8 | import scala.concurrent.ExecutionContext.Implicits.global 9 | 10 | object FutureAwait extends App with StrictLogging { 11 | logger.info("now") 12 | 13 | def doSomethingInFuture: Future[Int] = Future { 14 | println(s"this is in thread: ${Thread.currentThread().getName}") 15 | 1 16 | } 17 | 18 | val rs = Await.result(doSomethingInFuture, 1 second) 19 | logger.info(s"rs is $rs") 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/future/FutureSeq.scala: -------------------------------------------------------------------------------- 1 | package concurrency.future 2 | 3 | import scala.concurrent.{Await, Future} 4 | import scala.concurrent.duration._ 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | 7 | object FutureSeq extends App { 8 | def calcX(x:Int): Future[Int] = Future.successful(x + 2) 9 | def calcY(x:Int): Future[Int] = Future.successful(x * 2) 10 | 11 | val rs = Await.result(Future.sequence(List(calcX(2),calcY(2))), 1 seconds) 12 | println(rs(0)) 13 | println(rs(1)) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/future/SimpleFuture.scala: -------------------------------------------------------------------------------- 1 | package concurrency.future 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | import scala.concurrent.Future 7 | import scala.util.Try 8 | 9 | object SimpleFuture extends App with StrictLogging { 10 | def add(x: Int, y: Int): Int = x + y 11 | 12 | def concat(x: Int, y: Int): List[Int] = List(x, y) 13 | 14 | def divide(x: Int, y: Int): Option[Int] = if (y == 0) None else Some(x / y) 15 | 16 | def safeDiv(x: Int, y: Int): Try[Int] = Try { 17 | x / y 18 | } 19 | 20 | // safeDiv(2,1).map(_ * 2).flatMap(i => safeDiv(i, 2)) match { 21 | // case Success(v) => logger.info(s"result of div is $v") 22 | // case Failure(e) => logger.info("failed to div", e) 23 | // } 24 | 25 | def sum(xs: List[Int]): Future[Int] = Future { 26 | logger.info("summing") 27 | Thread.sleep(1000) 28 | xs.sum 29 | } 30 | 31 | logger.info("starting...") 32 | val futureSum = sum(List(1,2,3)) 33 | futureSum.onSuccess{ 34 | case i => logger.info(s"sum result is $i") 35 | } 36 | futureSum.onFailure{ 37 | case t => logger.info(s"sum failed", t) 38 | } 39 | Thread.sleep(2000) 40 | logger.info("done") 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/future/StrictTimedFuture.scala: -------------------------------------------------------------------------------- 1 | //package concurrency.future 2 | // 3 | //import java.util.concurrent.TimeoutException 4 | //import java.util.{Timer, TimerTask} 5 | // 6 | //import scala.concurrent.{ExecutionContext, Future, Promise} 7 | //import scala.concurrent.ExecutionContext.Implicits.global 8 | // 9 | //object StrictTimedFuture { 10 | // 11 | // implicit class KestrelCombinator[A](val a: A) extends AnyVal { 12 | // def withSideEffect(fun: A => Unit): A = { 13 | // fun(a) 14 | // a 15 | // } 16 | // 17 | // def tap(fun: A => Unit): A = withSideEffect(fun) 18 | // } 19 | // 20 | // val timer = new Timer() 21 | // 22 | // def apply[T](after: Long)(body: => T, onTimeout: => Unit = Unit)(implicit ec: ExecutionContext): Future[T] = { 23 | // val promise = Promise[T]() 24 | // val timeOutTask = new TimerTask { 25 | // def run() { 26 | // onTimeout 27 | // promise.failure( 28 | // new TimeoutException(s"Future timed out after ${after}ms in thread ${Thread.currentThread().getName}")) 29 | // println("interrupting") 30 | // Thread.currentThread().stop() 31 | // } 32 | // } 33 | // timer.schedule(timeOutTask, after) 34 | // // does not cancel future, only resolves result in approx duration. Your future may still be running! 35 | // Future.firstCompletedOf(Seq(Future(body), promise.future)).tap(_.onComplete { case result => timeOutTask.cancel() }) 36 | // } 37 | //} 38 | // 39 | //object StrictTimedFutureSample extends App { 40 | // println(s"main program running in ${Thread.currentThread().getName}") 41 | // val future = StrictTimedFuture(2000) { 42 | // var i = 1 43 | // while (true) { 44 | // Thread.sleep(1000) 45 | // println(s"run for $i time in thread ${Thread.currentThread().getName}") 46 | // i += 1 47 | // } 48 | // i 49 | // } 50 | // future.onSuccess { case i => s"get value $i" } 51 | // future.onFailure { case t => println(s"future run error, logged, ${t.getMessage}") } 52 | //} -------------------------------------------------------------------------------- /src/main/scala/concurrency/futurePractice/FuturePractice.scala: -------------------------------------------------------------------------------- 1 | package concurrency.futurePractice 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | 5 | import scala.concurrent.{Await, Future} 6 | import scala.concurrent.ExecutionContext.Implicits.global 7 | import scala.concurrent.duration._ 8 | import scala.io.StdIn 9 | import scala.util.{Failure, Success, Try} 10 | 11 | object FuturePractice extends App with StrictLogging { 12 | def greeting: String = { 13 | logger.info("creating greeting") 14 | "hello,world" 15 | } 16 | 17 | def greetingFuture: Future[String] = Future { 18 | // throw new IllegalStateException("BAD BAD") 19 | logger.info("creating greeting") 20 | "hello,world from greeting future" 21 | } 22 | 23 | def anotherFuture: Future[String] = Future { 24 | // throw new IllegalStateException("BAD BAD") 25 | logger.info("creating another future") 26 | "hello,world from another future" 27 | } 28 | 29 | //fallbackTo is not lazy, both future will be created and run 30 | val future = greetingFuture.fallbackTo(anotherFuture) 31 | 32 | future.onComplete{ 33 | case Success(greeting) => println(greeting) 34 | case Failure(e) => logger.error("error running future", e) 35 | } 36 | 37 | //// greetingFuture.fallbackTo() 38 | // 39 | // logger.info("let's begin") 40 | // // logger.info(s"i say $greetingFuture") 41 | // val lastFuture = greetingFuture.flatMap { s => 42 | // Future { 43 | // throw new IllegalArgumentException("xx wrong") 44 | // logger.info("creating xx") 45 | // s + "-xx" 46 | // } 47 | // }.map { s => 48 | // logger.info("creating yy") 49 | // s + "-yy" 50 | // } 51 | //// logger.info(s"i say: ${Await.result(lastFuture, 2 seconds)}") 52 | // // greetingFuture.foreach(s => logger.info(s"i say: $s")) 53 | // lastFuture.onComplete{ 54 | // case Success(x) => logger.info(x) 55 | // case Failure(e) => logger.error(e.getMessage,e) 56 | // } 57 | // logger.info("something") 58 | // 59 | // def processResult: Try[String] => String = { 60 | // case Success(s) => logger.info(s"i say: $s"); "x" 61 | // case Failure(e) => logger.error(s"error occures: ${e.getMessage}", e); "y" 62 | // } 63 | 64 | println("press enter to close") 65 | StdIn.readLine() 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/par/CustomerRepository.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | import com.typesafe.scalalogging.LazyLogging 4 | 5 | trait CustomerRepository extends LazyLogging { 6 | 7 | def fetch(cid: CustomerId): Option[Name] = ??? 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/par/DataAggregator.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | trait DataAggregator { 4 | this: CustomerRepository with OrderRepository => 5 | 6 | def aggregate(f: OrderAmount => Boolean): Set[(Name, OrderAmount)] = { 7 | filterByAmount(f).par.map { case (cid, oAmount) => (fetch(cid).get, oAmount)}.seq 8 | } 9 | } 10 | 11 | object DataAggregator extends CustomerRepository with OrderRepository 12 | 13 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/par/OrderRepository.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | trait OrderRepository{ 4 | def filterByAmount(f: OrderAmount => Boolean): Set[(CustomerId, OrderAmount)] = ??? 5 | } 6 | -------------------------------------------------------------------------------- /src/main/scala/concurrency/par/package.scala: -------------------------------------------------------------------------------- 1 | package concurrency 2 | 3 | package object par { 4 | type CustomerId = String 5 | type OrderAmount = Float 6 | type Name = String 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/dci/Account.scala: -------------------------------------------------------------------------------- 1 | package dci 2 | 3 | case class Account (owner: String, var balance: Double) 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/scala/dci/AccountService.scala: -------------------------------------------------------------------------------- 1 | package dci 2 | 3 | case class UserName(value: String) extends AnyVal 4 | case class Password(value: String) extends AnyVal 5 | case class Email(value: String) extends AnyVal 6 | case class Address(value: String) extends AnyVal 7 | 8 | object AccountService { 9 | def openAccount(user: User): Account = ??? 10 | 11 | def register1:(UserInfo, Set[RegisteredUser]) => (RegisteredUser, Set[RegisteredUser]) = ??? 12 | 13 | def register(name: String, password: String, email: String, address: String):RegisteredUser = ??? 14 | 15 | def register: (UserName, Password, Email, Address) => RegisteredUser = ??? 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/dci/LoginService.scala: -------------------------------------------------------------------------------- 1 | package dci 2 | 3 | object LoginService { 4 | def login(userName: String, password: String): RegisteredUser = RegisteredUser("1000","yy") 5 | } 6 | 7 | object CrazyShopping { 8 | def buybuybuy(user:RegisteredUser,product: Product): ShoppingCart = ??? 9 | 10 | def destroyIt(user: User, product: Product): Unit = user match { 11 | case AnonymousUser(_) => println("you can't!") 12 | case RegisteredUser(_,name) => print(s"you can destroy your own $product") 13 | case SuperUser(_,powerLevel,_) if powerLevel > 3 => print(s"done and done") 14 | case _ => println("who are you?") 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/dci/TransferService.scala: -------------------------------------------------------------------------------- 1 | package dci 2 | 3 | trait TransferSource { 4 | this: Account => 5 | 6 | def transferOut(money: Double) = balance -= money 7 | } 8 | 9 | trait TransferTarget { 10 | this: Account => 11 | 12 | def transferIn(money: Double) = balance += money 13 | } 14 | 15 | object TransferService { 16 | def transfer(source: TransferSource, target: TransferTarget, money: Double) = { 17 | source.transferOut(money) 18 | target.transferIn(money) 19 | } 20 | } 21 | 22 | object TransferApp extends App{ 23 | val source = new Account("xx", 100) with TransferSource 24 | val target = new Account("yy", 100) with TransferTarget 25 | 26 | TransferService.transfer(source,target, 50) 27 | } 28 | -------------------------------------------------------------------------------- /src/main/scala/dci/User.scala: -------------------------------------------------------------------------------- 1 | package dci 2 | 3 | sealed trait User 4 | 5 | case class AnonymousUser(tempId: String) extends User 6 | private[dci] case class RegisteredUser(id: String, name: String) extends User 7 | case class SuperUser(id: String, powerLevel: Int, scope: String) extends User 8 | 9 | trait ShoppingCart 10 | 11 | trait UserInfo -------------------------------------------------------------------------------- /src/main/scala/ddd/fp/LoginModule.scala: -------------------------------------------------------------------------------- 1 | package ddd.fp 2 | 3 | object LoginModule { 4 | case class Email(value: String) 5 | 6 | //TODO how to make this private? 7 | case class VerifiedEmail(email: Email) 8 | 9 | case class User(name: String, email: VerifiedEmail) 10 | 11 | def verify: Email => VerifiedEmail = ??? 12 | 13 | def login: VerifiedEmail => User = ??? 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/diamondProblem/A.scala: -------------------------------------------------------------------------------- 1 | package diamondProblem 2 | 3 | trait A{ 4 | def hello() = println("hello from A") 5 | } 6 | 7 | trait B extends A{ 8 | override def hello() = println("hello from B") 9 | } 10 | 11 | trait C extends A { 12 | override def hello() = println("hello from C") 13 | } 14 | 15 | object D extends App with B with C{ 16 | hello() 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/dup/DupModule.scala: -------------------------------------------------------------------------------- 1 | package dup 2 | 3 | object DupModule { 4 | def repl[A](xs: List[A], times: Int): List[A] = xs.flatMap(multiply(_,times)) 5 | 6 | def multiply[A](x: A, times: Int): List[A] = (1 to times).map(_ => x).toList 7 | 8 | repl(List(1,2,3),3 ) 9 | 10 | def dup[A] = repl(_:List[A], 2) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/excercise/fp/Factory.scala: -------------------------------------------------------------------------------- 1 | package excercise.fp 2 | 3 | import org.slf4j.LoggerFactory 4 | 5 | import scala.io.Source 6 | 7 | object Factory { 8 | val logger = LoggerFactory.getLogger(Factory.getClass) 9 | 10 | case class FileName(value: String) extends AnyVal 11 | 12 | def processInput: FileName => Unit = fileName => { 13 | val request = Source.fromFile(fileName.value).getLines().toList 14 | createPlan(request).map(formatShowPlan).foreach(println) 15 | } 16 | 17 | case class Plan(orderId: Int, workProcesses: List[WorkProcess]) 18 | case class Product(value: String) extends AnyVal 19 | 20 | def createPlan: List[String] => List[Plan] = requestDesc => { 21 | val (resources, orders) = parseRequest(requestDesc) 22 | orders.map(naiveCreatePlan(resources)) 23 | } 24 | 25 | case class Order(id: Int, products: List[Product]) 26 | type ResourceDesc = (MachineType, Quantity) 27 | trait MachineType 28 | case object GMachine extends MachineType 29 | case object MMachine extends MachineType 30 | case object RMachine extends MachineType 31 | case object PMachine extends MachineType 32 | case object Cooler extends MachineType 33 | 34 | case class Quantity(value: Int) extends AnyVal 35 | 36 | def parseRequest: List[String] => (List[ResourceDesc], List[Order]) = { 37 | splitRequest andThen transformRequest.tupled 38 | } 39 | 40 | def splitRequest: List[String] => (List[String], List[String]) = src =>{ 41 | src.splitAt(src.indexWhere(_.startsWith("Order:"))) 42 | } 43 | 44 | def transformRequest: (List[String], List[String]) => (List[ResourceDesc], List[Order]) = 45 | (resourceDescStr, orderStrs) => { 46 | (resourceDescStr.map(parseResourceDesc), orderStrs.zipWithIndex.map { 47 | case (order, id) => parseOrderDesc(id)(order) 48 | }) 49 | } 50 | 51 | def parseOrderDesc: Int => String => Order = orderId => str => { 52 | Order(orderId, str.split(":").last.trim.split(" ").toList.map(Product)) 53 | } 54 | 55 | def parseResourceDesc: String => ResourceDesc = s => { 56 | val splitted = s.split(":") 57 | (strToMachineType(splitted.head), Quantity(splitted.last.trim.toInt)) 58 | } 59 | 60 | def naiveCreatePlan: List[ResourceDesc] => Order => Plan = rDesc => order => { 61 | val workProcesses = rDesc.flatMap(initializeMachine) 62 | naiveCreatePlanFromWorkProcess(workProcesses)(order) 63 | } 64 | 65 | case class WorkProcess(machine: Machine, products: List[Product]) 66 | case class Machine(mType: MachineType, id: Int) 67 | 68 | def initializeMachine: ResourceDesc => List[WorkProcess] = { 69 | case (machineType, quantity) => (1 to quantity.value).map(i => 70 | WorkProcess(Machine(machineType, i), Nil)).toList 71 | } 72 | 73 | def naiveCreatePlanFromWorkProcess: List[WorkProcess] => Order => Plan = workProcesses => order => { 74 | Plan(order.id, arrange(arrangeProduction)(workProcesses)(order.products)) 75 | } 76 | 77 | def arrange: ArrangeFunc => List[WorkProcess] => List[Product] => List[WorkProcess] = 78 | f => workProcesses => products => { 79 | products.foldLeft(workProcesses)((wps, product) => f(wps)(product)) 80 | } 81 | 82 | type ArrangeFunc = List[WorkProcess] => Product => List[WorkProcess] 83 | 84 | def arrangeProduction: ArrangeFunc = workProcesses => product => { 85 | workProcesses.groupBy(_.machine.mType).values.map( 86 | workProcessByType => assignProduct(workProcessByType, product)). 87 | flatten.toList.sortBy(_.machine.toString) 88 | } 89 | 90 | def assignProduct(processes: List[WorkProcess], product: Product): List[WorkProcess] = { 91 | val sorted = processes.sortBy(_.products.size) 92 | val idlest: WorkProcess = sorted(0) 93 | sorted.updated(0, WorkProcess(idlest.machine, idlest.products :+ product)) 94 | } 95 | 96 | def formatShowPlan: Plan => String = plan => { 97 | s"Order #${plan.orderId}\n" + 98 | plan.workProcesses.map(w => s"${machine2Str(w.machine)}: ${w.products.map(_.value).mkString("\t")}").mkString("\n") + "\n" + 99 | s"Total: ${calcTime(productMachineTime)(plan)} hours" 100 | } 101 | 102 | val machineTypeStrMap: Map[String, MachineType] = Map("G" -> GMachine, "M" -> MMachine, "R" -> RMachine, "P" -> PMachine) 103 | 104 | def strToMachineType: String => MachineType = machineTypeStrMap(_) 105 | 106 | def machine2Str: Machine => String = m => s"${m.mType.toString.head}${m.id}" 107 | 108 | type Hour = Int 109 | type ProductMachineTime = Map[Product, Map[MachineType, Hour]] 110 | val productMachineTime: ProductMachineTime = Map( 111 | Product("zteT") -> Map(GMachine -> 3, MMachine -> 3, RMachine -> 1, Cooler -> 2, PMachine -> 1), 112 | Product("zteW") -> Map(GMachine -> 2, MMachine -> 2, RMachine -> 3, Cooler -> 2, PMachine -> 2), 113 | Product("zteX") -> Map(GMachine -> 3, MMachine -> 3, RMachine -> 1, Cooler -> 5, PMachine -> 1), 114 | Product("zteY") -> Map(GMachine -> 1, MMachine -> 1, RMachine -> 4, Cooler -> 3, PMachine -> 3), 115 | Product("zteZ") -> Map(GMachine -> 2, MMachine -> 3, RMachine -> 2, Cooler -> 1, PMachine -> 1) 116 | ) 117 | 118 | def calcTime: ProductMachineTime => Plan => Int = pmTime => plan => { 119 | (for (w <- plan.workProcesses; p <- w.products) yield pmTime(p)(w.machine.mType)).sum 120 | } 121 | } -------------------------------------------------------------------------------- /src/main/scala/expressiveness/inherit/Client.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.inherit 2 | 3 | object Client { 4 | def printArea(shape: Shape) = shape.area 5 | } 6 | -------------------------------------------------------------------------------- /src/main/scala/expressiveness/inherit/Shape.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.inherit 2 | 3 | trait Shape { 4 | def area:Double 5 | } 6 | 7 | class Square(side:Double) extends Shape { 8 | override def area: Double = side * side 9 | 10 | } 11 | 12 | class Circle(radius: Double) extends Shape { 13 | override def area: Double = 3.14 * radius * radius 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/scala/expressiveness/switchcase/Client.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.switchcase 2 | 3 | import ShapeModule._ 4 | object Client { 5 | def printArea(shape: Shape) = area(shape) 6 | } 7 | -------------------------------------------------------------------------------- /src/main/scala/expressiveness/switchcase/ShapeModule.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.switchcase 2 | 3 | object ShapeModule { 4 | 5 | trait Shape 6 | 7 | case class Square(side: Double) extends Shape 8 | case class Circle(radius: Double) extends Shape 9 | 10 | def area(shape: Shape):Double = shape match { 11 | case Square(side) => side * side 12 | case Circle(radius) => 3.14 * radius * radius 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/scala/expressiveness/typeclass/Client.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.typeclass 2 | 3 | import ShapeModule._ 4 | 5 | object Client { 6 | def printArea[T](shape: T)(implicit m: HaveArea[T]) = println(m.area(shape)) 7 | def printPerimeter[T](shape: T)(implicit m: HavePerimeter[T]) = println(m.perimeter(shape)) 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/expressiveness/typeclass/ShapeModule.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.typeclass 2 | 3 | object ShapeModule { 4 | case class Square(side: Double) 5 | case class Circle(radius: Double) 6 | 7 | trait HaveArea[T]{ 8 | def area(shape: T): Double 9 | } 10 | 11 | implicit object squareHaveArea extends HaveArea[Square] { 12 | override def area(square: Square): Double = square.side * square.side 13 | } 14 | implicit object circleHaveArea extends HaveArea[Circle] { 15 | override def area(circle: Circle): Double = 3.14 * circle.radius * circle.radius 16 | } 17 | 18 | trait HavePerimeter[T]{ 19 | def perimeter(shape: T): Double 20 | } 21 | 22 | implicit object squareHavePerimeter extends HavePerimeter[Square] { 23 | override def perimeter(square: Square): Double = square.side * 4 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/expressiveness/typeclass/mptc/ConsModule.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.typeclass.mptc 2 | 3 | object ConsModule { 4 | 5 | trait Cons[A[_], B] { 6 | def cons(b: B,a:A[B]): A[B] 7 | 8 | def head(a: A[B]): B 9 | 10 | def tail(a:A[B]): A[B] 11 | 12 | def isEmpty(a: A[B]): Boolean 13 | } 14 | 15 | class ListIsCons[B] extends Cons[List, B] { 16 | override def cons(b: B,xs: List[B]): List[B] = b :: xs 17 | 18 | override def head(xs: List[B]): B = xs.head 19 | 20 | override def tail(xs:List[B]): List[B] = xs.tail 21 | 22 | override def isEmpty(xs: List[B]): Boolean = xs.isEmpty 23 | } 24 | } 25 | 26 | object ConsClient extends App { 27 | import ConsModule._ 28 | 29 | def snd[A[_], B](a: A[B])(implicit c: Cons[A, B]): B = c.head(c.tail(a)) 30 | 31 | implicit def lcons[A]: ListIsCons[A] = new ListIsCons[A] 32 | 33 | println(snd(List(1,2,3))) 34 | } 35 | -------------------------------------------------------------------------------- /src/main/scala/fibs/FibsModule.scala: -------------------------------------------------------------------------------- 1 | package fibs 2 | 3 | object FibsModule { 4 | 5 | // def fibs(length: Int): List[Int] = 6 | // length match { 7 | // case 1 => 1 :: Nil 8 | // case 2 => 1 :: 1 :: Nil 9 | // case n => { 10 | // val prev = fibs(n - 1) 11 | // prev match { 12 | // case (x :: y :: _) => (x + y) :: prev 13 | // } 14 | // } 15 | // } 16 | // 17 | // def fibsMk2(length: Int) = fibs(length).reverse 18 | 19 | // def fibs(length: Int): List[Int] = 20 | // length match { 21 | // case 1 => 1 :: Nil 22 | // case 2 => 1 :: 1 :: Nil 23 | // case n => { 24 | // val prev = fibs(n - 1) 25 | // (prev.head + fibs(n - 2).head) :: prev 26 | // } 27 | // } 28 | 29 | // def fibs(length: Int): List[Int] = length match { 30 | // case 1 => List(1) 31 | // case 2 => List(1,1) 32 | // case n => { 33 | // val prev = fibs(n - 1) 34 | // prev :+ (prev.last + fibs(n-2).last) 35 | // } 36 | // } 37 | 38 | // def fibs(length: Int): List[Int] = length match { 39 | // case 1 => List(1) 40 | // case 2 => List(1, 1) 41 | // case n => fibs(n - 1) :+ (fibs(n - 1).last + fibs(n - 2).last) 42 | // } 43 | 44 | // val fibs: Stream[Int] = 1 #:: 1 #:: (fibs zip fibs.tail).map { t => t._1 + t._2} 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/fold/fold.scala: -------------------------------------------------------------------------------- 1 | package fold 2 | 3 | object fold extends App{ 4 | def fold[A,B](xs: List[A])(acc: B)(f: (B,A) => B): B = { 5 | var rs = acc 6 | for(i <- xs) rs = f(rs,i) 7 | rs 8 | } 9 | 10 | def reduce[A](xs: List[A])(f: (A,A) => A): A = fold(xs.tail)(xs.head)(f) 11 | 12 | def reverse[A](xs: List[A]): List[A] = fold(xs)(List[A]())((acc, i) => i :: acc) 13 | 14 | val l = List(1,2,3) 15 | println(s"reverse of $l is ${reverse(l)}") 16 | 17 | def sum: List[Int] => Int = reduce(_)(_ + _) 18 | def product: List[Int] => Int = reduce(_)(_ * _) 19 | 20 | println(s"sum = ${sum(List(3,4,5))}") 21 | println(s"product = ${product(List(3,4,5))}") 22 | 23 | 24 | val conditions = List("xx = 1","yy > 2","zz < 3") 25 | def concat: List[String] => String = reduce(_)((acc,i) => s"$acc AND $i") 26 | println(s"SELECT * FROM user WHERE ${concat(conditions)}") 27 | 28 | // @annotation.tailrec 29 | // def foldLeft[A, B](l: List[A], z: B)(f: (B, A) => B): B = l match { 30 | // case Nil => z 31 | // case Cons(h, t) => foldLeft(t, f(z, h))(f) 32 | // } 33 | // 34 | // def foldRight[A, B](l: List[A], z: B)(f: (A, B) => B): B = 35 | // foldLeft(l, (b: B) => b)((g, a) => b => g(f(a, b)))(z) 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/fold/sum.scala: -------------------------------------------------------------------------------- 1 | package fold 2 | 3 | object sum extends App { 4 | def sum(xs:List[Int]):Int = { 5 | var rs = 0 6 | for(i <- xs) rs += i 7 | rs 8 | } 9 | 10 | def product(xs:List[Int]):Int = { 11 | var rs = 1 12 | for(i <- xs) rs = rs * i 13 | rs 14 | } 15 | 16 | println(s"sum = ${sum(List(3,4,5))}") 17 | println(s"product = ${product(List(3,4,5))}") 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/fpbasic/MyFunctor.scala: -------------------------------------------------------------------------------- 1 | package fpbasic 2 | 3 | object MyFunctor { 4 | def map[A,B](xs: List[A], f: A => B): List[B] = xs match { 5 | case Nil => Nil 6 | case (h :: t) => f(h) :: map(t, f) 7 | } 8 | 9 | def filter[A](xs: List[A], f: A => Boolean): List[A] = xs match { 10 | case Nil => Nil 11 | case (h :: t) => if(f(h)) h :: filter(t, f) else filter(t,f) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/akka/HSS.scala: -------------------------------------------------------------------------------- 1 | package funcserv.akka 2 | 3 | import akka.actor.Actor 4 | import akka.actor.Actor.Receive 5 | 6 | class HSS extends Actor{ 7 | override def receive: Receive = ??? 8 | } 9 | 10 | object HSS { 11 | case class GetAuthVector(imsi: String) 12 | case class GetAuthVectorResp(imsi: String) 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/akka/MME.scala: -------------------------------------------------------------------------------- 1 | package funcserv.akka 2 | 3 | import akka.actor.{ActorRef, Actor} 4 | import akka.actor.Actor.Receive 5 | import funcserv.akka.HSS.{GetAuthVectorResp, GetAuthVector} 6 | import funcserv.akka.MME.{AuthRequestNoImsi, AuthRequest} 7 | import funcserv.akka.UE.{GetImsi, UEAuth} 8 | 9 | class MME(hss: ActorRef, ue: ActorRef) extends Actor{ 10 | 11 | override def receive: Receive = waitAttachRequest 12 | 13 | def waitAttachRequest: Receive = { 14 | case AuthRequestNoImsi => { 15 | ue ! GetImsi 16 | context become waitIMSI 17 | } 18 | case AuthRequest(imsi) => { 19 | hss ! GetAuthVector(imsi) 20 | context become waitGetAuthVectorResp 21 | } 22 | } 23 | 24 | def waitGetAuthVectorResp: Receive = { 25 | case GetAuthVectorResp(imsi) => { 26 | ue ! UEAuth(imsi) 27 | context become waitUEAuthResp 28 | } 29 | } 30 | 31 | def waitUEAuthResp: Receive = ??? 32 | def waitIMSI: Receive = ??? 33 | } 34 | 35 | object MME{ 36 | case class AuthRequest(imsi: String) 37 | case object AuthRequestNoImsi 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/akka/UE.scala: -------------------------------------------------------------------------------- 1 | package funcserv.akka 2 | 3 | import akka.actor.Actor 4 | import akka.actor.Actor.Receive 5 | 6 | class UE extends Actor{ 7 | override def receive: Receive = ??? 8 | } 9 | 10 | object UE { 11 | case class UEAuth(imsi: String) 12 | case class UEAuthResp(imsi: String) 13 | case object GetImsi 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/prototype/HSS.scala: -------------------------------------------------------------------------------- 1 | package funcserv.prototype 2 | 3 | import scala.concurrent.ExecutionContext.Implicits.global 4 | import scala.concurrent.Future 5 | 6 | object HSS { 7 | 8 | case class AuthVector(ueID: String) 9 | 10 | def getAuthVector(ueID: String, imsi: String): Future[AuthVector] = Future { 11 | println(s"getAuthVector for ueID: $ueID, imsi: $imsi") 12 | AuthVector(ueID) 13 | throw new IllegalStateException("Get AuthVector Error!") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/prototype/MME.scala: -------------------------------------------------------------------------------- 1 | package funcserv.prototype 2 | 3 | import scala.concurrent.ExecutionContext.Implicits.global 4 | import scala.concurrent.Future 5 | 6 | 7 | object MME { 8 | 9 | case class AuthRequest(ueID: String, imsi: Option[String]) 10 | 11 | case class AuthResponse(ueID: String) 12 | 13 | def processAuthReq(authRequest: AuthRequest): Future[AuthResponse] = { 14 | println(s"processingAuthRequest $authRequest") 15 | for { 16 | i <- if (authRequest.imsi.isEmpty) { 17 | UE.getImsi(authRequest.ueID) 18 | } else Future { 19 | authRequest.imsi.get 20 | } 21 | av <- HSS.getAuthVector(authRequest.ueID, i) 22 | } yield AuthResponse(av.ueID) 23 | // fImsi.flatMap(i => HSS.getAuthVector(authRequest.ueID, i)).map(av => AuthResponse(av.ueID)) 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/prototype/MMEApp.scala: -------------------------------------------------------------------------------- 1 | package funcserv.prototype 2 | 3 | import funcserv.prototype.UE.{ConnectionFailed, ConnectionOK} 4 | 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | 7 | 8 | object MMEApp extends App { 9 | // UE.createConnectionWithImsi("ue0001", "imsi0001").onSuccess { 10 | // case ConnectionOK(ueID) => println(s"$ueID successfully connected") 11 | // case ConnectionFailure(ueID, cause) => println(s"$ueID failed to connect because $cause") 12 | // } 13 | 14 | println("-------------------sep-------------------") 15 | val conn = UE.createConnectionNoImsi("ue0001") 16 | conn.onSuccess { 17 | case ConnectionOK(ueID) => println(s"$ueID successfully connected") 18 | case ConnectionFailed(ueID, cause) => println(s"$ueID failed to connect because $cause") 19 | } 20 | conn.onFailure { case ex: Throwable => println(s"error occurs:${ex.getMessage}") } 21 | 22 | Thread.sleep(1000) 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/funcserv/prototype/UE.scala: -------------------------------------------------------------------------------- 1 | package funcserv.prototype 2 | 3 | import funcserv.prototype.MME.AuthRequest 4 | 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | import scala.concurrent.Future 7 | 8 | 9 | object UE { 10 | trait ConnectionStatus 11 | case class ConnectionOK(ueID: String) extends ConnectionStatus 12 | case class ConnectionFailed(ueID: String, cause: String) extends ConnectionStatus 13 | 14 | def createConnectionWithImsi(ueID: String, imsi: String): Future[ConnectionStatus] = { 15 | println(s"creating connection: ueID = $ueID, imsi = $imsi") 16 | MME.processAuthReq(AuthRequest(ueID, Some(imsi))).map(_ => ConnectionOK(ueID)) 17 | } 18 | 19 | def createConnectionNoImsi(ueID: String): Future[ConnectionStatus] = { 20 | println(s"creating connection without imsi: ueID = $ueID") 21 | MME.processAuthReq(AuthRequest(ueID, None)).map(_ => ConnectionOK(ueID)) 22 | } 23 | 24 | def getImsi(ueID: String): Future[String] = Future{ 25 | println(s"getImsi for ueID: $ueID") 26 | "imsi"+ueID.drop(2) 27 | // throw new IllegalStateException(s"GET IMSI ERROR for ueID:$ueID") 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/scala/hoi4/Hoi4Helper.scala: -------------------------------------------------------------------------------- 1 | package hoi4 2 | 3 | object Hoi4Helper { 4 | 5 | case class Equipment(name: String, cost: Double) 6 | 7 | val smallArms2 = Equipment("small arms2", 0.60) 8 | val artillery2 = Equipment("artillery2", 4.0) 9 | val antiTank1 = Equipment("anti tank gun1", 4.0) 10 | val antiTank2 = Equipment("anti tank gun2", 5.0) 11 | val mech = Equipment("mech infantry1", 8.0) 12 | val support = Equipment("support", 4.0) 13 | val lightArmor2 = Equipment("light armor2", 9.0) 14 | val lightArmor3 = Equipment("light armor3", 10.0) 15 | val mediumTank1 = Equipment("medium tank1", 12.0) 16 | val mediumTank3 = Equipment("medium tank3", 13.0) 17 | val mediumSelfArtillery1 = Equipment("medium self artillery1", 12.0) 18 | val mediumSelfArtillery3 = Equipment("medium self artillery3", 13.0) 19 | val lightSelfArtillery2 = Equipment("lightSelfArtillery2", 9.0) 20 | val lightSelfArtillery3 = Equipment("lightSelfArtillery3", 10.0) 21 | val selfRocket = Equipment("self rocket", 12.0) 22 | val motorized = Equipment("motorized", 2.50) 23 | val carrierFighter1 = Equipment("carrierFighter1", 28.40) 24 | val carrierFighter2 = Equipment("carrierFighter2", 30.40) 25 | 26 | val basicProduct: Double = 5 * (1+ 0.15 + 0.189 + 0.60) * 0.9009 27 | 28 | case class DivisionType(name: String, equipments: Map[Equipment, Int]) 29 | 30 | def requiredFactoryToProduceInOneYear(equipment: Equipment, quantity: Int): Double = { 31 | quantity / (basicProduct / equipment.cost * 365) 32 | } 33 | 34 | def planFactories(divisions: Map[DivisionType, Int]): Map[String, Double] = { 35 | totalEquipments(divisions.foldLeft(List[Map[Equipment, Int]]()) { case (acc, (k, v)) => 36 | divisionEquiptments(k, v) :: acc 37 | }).map { 38 | case (equipment, quantity) => equipment.name -> requiredFactoryToProduceInOneYear(equipment, quantity) 39 | } 40 | } 41 | 42 | def totalEquipments(equipments: Seq[Map[Equipment, Int]]): Map[Equipment, Int] = { 43 | equipments.foldLeft(Map[Equipment, Int]()) { (acc, partEquipments) => 44 | partEquipments.foldLeft(acc) { case (outerAcc, (equipment, num)) => 45 | if (outerAcc.contains(equipment)) { 46 | outerAcc.updated(equipment, outerAcc(equipment) + num) 47 | } else { 48 | outerAcc.updated(equipment, num) 49 | } 50 | } 51 | } 52 | } 53 | 54 | def divisionEquiptments(divisionType: DivisionType, howManyDivisions: Int): Map[Equipment, Int] = { 55 | divisionType.equipments.mapValues(_ * howManyDivisions) 56 | } 57 | 58 | } 59 | 60 | object Hoi4HelperApp extends App { 61 | import Hoi4Helper._ 62 | 63 | //define Division types 64 | val infantry37 = DivisionType("infantry37", Map( 65 | smallArms2 -> 750, 66 | artillery2 -> 84, 67 | support -> 40 68 | )) 69 | val marine40 = DivisionType("marine", Map( 70 | smallArms2 -> 1100, 71 | artillery2 -> 84, 72 | support -> 70, 73 | motorized -> 20 74 | )) 75 | val motorized41 = DivisionType("motorized41", Map( 76 | smallArms2 -> 710, 77 | artillery2 -> 12, 78 | motorized -> 410, 79 | support -> 80, 80 | selfRocket -> 40 81 | )) 82 | val tank40 = DivisionType("tank40", Map( 83 | artillery2 -> 12, 84 | smallArms2 -> 410, 85 | motorized -> 210, 86 | support -> 50, 87 | mediumTank1 -> 150, 88 | mediumSelfArtillery1 -> 72 89 | )) 90 | 91 | //define armies 92 | val asiaDefendArmy = Map( 93 | infantry37 -> 12, 94 | marine40 -> 3, 95 | tank40 -> 4, 96 | motorized41 -> 5 97 | ) 98 | 99 | val japanArmy = Map( 100 | tank40 -> 8, 101 | motorized41 -> 16 102 | ) 103 | 104 | import concurrency.akkaStream.MapUtil._ 105 | val needToProduce = mergeMaps(asiaDefendArmy,japanArmy)(_ + _) 106 | 107 | val title: String = needToProduce.toSet[(DivisionType,Int)].map { 108 | case (divisionType:DivisionType,quantity:Int) => s"$quantity ${divisionType.name}" 109 | }.reduce((s1,s2) => s"$s1 and $s2") 110 | 111 | println(s"in order to produce $title divisions") 112 | 113 | planFactories(needToProduce).foreach{ case (equipment, factoryNum) => 114 | println(s"$factoryNum $equipment factories") 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/scala/hotelPractice/fp/HotelReservationService.scala: -------------------------------------------------------------------------------- 1 | package hotelPractice.fp 2 | 3 | import akka.io.Inet.SO.ReuseAddress 4 | 5 | object HotelReservationService { 6 | /* 7 | Problem Four: Hotel Reservation Problem 8 | A hotel chain operating in Miami wishes to offer room reservation services over the internet. 9 | They have three hotels in Miami: Lakewood, Bridgewood and Ridgewood. Each hotel has 10 | separate weekday and weekend(Saturday and Sunday) rates. There are special rates for 11 | rewards customer as a part of loyalty program. Each hotel has a rating assigned to it. 12 | 13 | ● Lakewood with a rating of 3 has weekday rates as 110$ for regular customer and 80$ for 14 | rewards customer. The weekend rates are 90$ for regular customer and 80$ for a rewards 15 | customer. 16 | ● Bridgewood with a rating of 4 has weekday rates as 160$ for regular customer and 110$ for 17 | rewards customer. The weekend rates are 60$ for regular customer and 50$ for a rewards 18 | customer. 19 | ● Ridgewood with a rating of 5 has weekday rates as 220$ for regular customer and 100$ for 20 | rewards customer. The weekend rates are 150$ for regular customer and 40$ for a rewards 21 | customer. 22 | Write a program to help an online customer find the cheapest hotel. 23 | The input to the program will be a range of dates for a regular or rewards customer. The output should 24 | be the cheapest available hotel. In case of a tie, the hotel with highest rating should be returned. 25 | 26 | INPUT FORMAT: 27 | : , , , … 28 | OUTPUT FORMAT: 29 | 30 | INPUT 1: 31 | Regular: 16Mar2009(mon), 17Mar2009(tues), 18Mar2009(wed) 32 | OUTPUT 1: 33 | Lakewood 34 | INPUT 2: 35 | Regular: 20Mar2009(fri), 21Mar2009(sat), 22Mar2009(sun) 36 | OUTPUT 2: 37 | Bridgewood 38 | INPUT 3: 39 | Rewards: 26Mar2009(thur), 27Mar2009(fri), 28Mar2009(sat) 40 | OUTPUT 3: 41 | Ridgewood 42 | */ 43 | def recommendHotel: Seq[Hotel] => String => String = { hotels => input => 44 | (parse andThen calcPrice(hotels) andThen selectHotel andThen (_.name))(input) 45 | } 46 | 47 | //Regular: 20Mar2009(fri), 21Mar2009(sat), 22Mar2009(sun) 48 | def parse: String => Agenda = { input => 49 | val arr = input.split(":") 50 | val customerType = CustomerType.fromString(arr.head.trim) 51 | val dates = arr.last.split(",").map(_.split("\\(|\\)")).map(ds => (ds.head.trim, ds.last.trim)) 52 | Agenda(customerType, dates) 53 | } 54 | 55 | type Date = String 56 | type Day = String 57 | 58 | case class Agenda(customerType: CustomerType, dates: Seq[(Date, Day)]) 59 | 60 | trait CustomerType 61 | object CustomerType{ 62 | def fromString(str:String): CustomerType = str match { 63 | case "Regular" => Regular 64 | case "Rewards" => Rewards 65 | case x => throw new IllegalArgumentException(s"unknown customer type: $x") 66 | } 67 | } 68 | 69 | case object Regular extends CustomerType 70 | 71 | case object Rewards extends CustomerType 72 | 73 | type Price = Double 74 | 75 | def calcPrice: Seq[Hotel] => Agenda => Seq[(Hotel, Price)] = { hotels => agenda => 76 | hotels.map(hotel => calcPriceSingle(hotel)(agenda)) 77 | } 78 | 79 | def calcPriceSingle: Hotel => Agenda => (Hotel, Price) = { hotel => agenda => 80 | val customerType = agenda.customerType 81 | val price = agenda.dates.map{ case (_,day) => dayToDayType(day)}.map { 82 | case Weekday if customerType == Regular => hotel.regularWeekdayPrice 83 | case Weekday if customerType == Rewards => hotel.rewardsWeekdayPrice 84 | case Weekend if customerType == Regular => hotel.regularWeekendPrice 85 | case Weekend if customerType == Rewards => hotel.rewardsWeekendPrice 86 | }.sum 87 | (hotel, price) 88 | } 89 | 90 | trait DayType 91 | case object Weekday extends DayType 92 | case object Weekend extends DayType 93 | 94 | def dayToDayType: Day => DayType = { 95 | case ("mon"|"tues"|"wed"|"thur"|"fri") => Weekday 96 | case ("sat"|"sun") => Weekend 97 | case x => throw new IllegalArgumentException(s"unknown daytype $x") 98 | } 99 | 100 | case class Hotel(name: String, rating: Int, 101 | regularWeekdayPrice: Price, rewardsWeekdayPrice: Price, 102 | regularWeekendPrice: Price, rewardsWeekendPrice: Price 103 | ) 104 | 105 | def selectHotel: Seq[(Hotel, Price)] => Hotel = _.sortWith{ 106 | case ((hotel1,price1),(hotel2,price2)) => { 107 | if(price1 == price2) hotel1.rating > hotel2.rating else price1 < price2 108 | } 109 | }.head._1 110 | } 111 | -------------------------------------------------------------------------------- /src/main/scala/hr/ExCalculator.scala: -------------------------------------------------------------------------------- 1 | package hr 2 | 3 | object ExCalculator { 4 | def f(x: Float): Float = ff(BigDecimal(x),9).setScale(4, BigDecimal.RoundingMode.HALF_UP).toFloat 5 | 6 | def ff(x: BigDecimal, n: Int): BigDecimal = n match{ 7 | case 0 => 1 8 | case i => (times(x, n) / factorial(n)) + ff(x, n-1) 9 | } 10 | 11 | def times(x:BigDecimal, n: Int) = List.fill(n)(x).product 12 | 13 | def factorial(n:Int): Int = n match { 14 | case 1 => 1 15 | case x => x * factorial(x - 1) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/implicitSample/ImplicitSample.scala: -------------------------------------------------------------------------------- 1 | package implicitSample 2 | 3 | object ImplicitSample extends App { 4 | implicit class PoliteInt(value: Int) { 5 | def sayHello():Unit = println(s"hello, I am $value") 6 | } 7 | 8 | 42.sayHello() 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/main/scala/lift/liftModule.scala: -------------------------------------------------------------------------------- 1 | package lift 2 | 3 | object liftModule extends App{ 4 | def add(x:Int)(y:Int):Int = x + y 5 | 6 | def lift[A,B,C](f: A => B => C): Option[A] => Option[B] => Option[C] = { 7 | // o1 => o2 => o1.flatMap(x => o2.map(y => f(x)(y))) 8 | o1 => o2 => for{ 9 | x <- o1 10 | y <- o2 11 | } yield f(x)(y) 12 | } 13 | 14 | val fadd = lift(add) 15 | 16 | add(1)(2) 17 | 18 | fadd(Some(1))(Some(2)) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/loanPattern/FileReadSupport.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | import java.io.{FileReader, BufferedReader} 4 | 5 | trait FileReadSupport { 6 | def withReader[T](fileName: String)(f: BufferedReader => T): T = { 7 | //purposely use java style file processing instead of scala.io.Source.fromFile 8 | var reader: BufferedReader = null 9 | try { 10 | reader = new BufferedReader(new FileReader(fileName)) 11 | f(reader) 12 | }finally{ 13 | if(reader != null){ 14 | reader.close() 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/loanPattern/FileTraverseSupport.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | import java.io.BufferedReader 4 | 5 | trait FileTraverseSupport { 6 | def fold[A](reader: BufferedReader)(init: A)(f: (A, String) => A): A = { 7 | var line = reader.readLine() 8 | var acc = init 9 | while (line != null) { 10 | acc = f(acc, line) 11 | line = reader.readLine() 12 | } 13 | acc 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/loanPattern/SampleTxtProcessor.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | import java.io.{BufferedReader, FileReader} 4 | 5 | object SampleTxtProcessor { 6 | def countLines(fileName: String): Int = { 7 | //purposely use java style file processing instead of scala.io.Source.fromFile 8 | var reader: BufferedReader = null 9 | try { 10 | reader = new BufferedReader(new FileReader(fileName)) 11 | var count = 0 12 | while (reader.readLine() != null) { 13 | count += 1 14 | } 15 | count 16 | } finally { 17 | if (reader != null) { 18 | reader.close() 19 | } 20 | } 21 | } 22 | 23 | def countFunctions(fileName: String): Int = { 24 | //purposely use java style file processing instead of scala.io.Source.fromFile 25 | var reader: BufferedReader = null 26 | try { 27 | reader = new BufferedReader(new FileReader(fileName)) 28 | var count = 0 29 | var line = reader.readLine() 30 | while (line != null && line.startsWith("def")) { 31 | count += 1 32 | line = reader.readLine() 33 | } 34 | count 35 | } finally { 36 | if (reader != null) { 37 | reader.close() 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/loanPattern/SampleTxtProcessorLoanImpl.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | trait SampleTxtProcessorLoanImpl { 4 | this: FileReadSupport => 5 | 6 | def countLines(fileName: String): Int = withReader(fileName){ reader => 7 | var count = 0 8 | while (reader.readLine() != null) { 9 | count += 1 10 | } 11 | count 12 | } 13 | 14 | def countFunctions(fileName: String): Int = withReader(fileName){ reader => 15 | var count = 0 16 | var line = reader.readLine() 17 | while (line != null && line.startsWith("def")) { 18 | count += 1 19 | line = reader.readLine() 20 | } 21 | count 22 | } 23 | } 24 | 25 | object SampleTxtProcessorLoanImpl extends SampleTxtProcessorLoanImpl with FileReadSupport 26 | -------------------------------------------------------------------------------- /src/main/scala/loanPattern/SampleTxtProcessorLoanImplMk1.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | trait SampleTxtProcessorLoanImplMk1 { 4 | this: FileReadSupport with FileTraverseSupport => 5 | 6 | def countLines(fileName: String): Int = countBy(fileName)(_ => true) 7 | 8 | def countFunctions(fileName: String): Int = countBy(fileName)(_.startsWith("def")) 9 | 10 | def countBy(fileName: String)(f: String => Boolean): Int = withReader(fileName){ reader => 11 | fold(reader)(0){ 12 | (count, line) => if(f(line)) count + 1 else count 13 | } 14 | } 15 | } 16 | 17 | object SampleTxtProcessorLoanImplMk1 extends SampleTxtProcessorLoanImplMk1 with FileReadSupport with FileTraverseSupport 18 | -------------------------------------------------------------------------------- /src/main/scala/monad/FileWriteSupport.scala: -------------------------------------------------------------------------------- 1 | package monad 2 | 3 | import java.io.{FileWriter, File, BufferedWriter} 4 | 5 | trait FileWriteSupport { 6 | def withWriter(path: FilePath)(f: BufferedWriter => Unit): Unit = { 7 | var writer: BufferedWriter = null 8 | try { 9 | val file = new File(path.value) 10 | if (!file.exists() || file.isDirectory) { 11 | file.createNewFile() 12 | } 13 | writer = new BufferedWriter(new FileWriter(file)) 14 | f(writer) 15 | } finally { 16 | if(writer != null) writer.close() 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/monad/Persisted.scala: -------------------------------------------------------------------------------- 1 | package monad 2 | 3 | import monad.StringPresentable.StringPresentable 4 | 5 | import scala.io.Source 6 | 7 | case class FilePath(value: String) extends AnyVal 8 | 9 | trait Persisted[A] { 10 | def path: FilePath 11 | 12 | def get: A 13 | 14 | def map[B](f: A => B)(implicit m: StringPresentable[B]): Persisted[B] 15 | } 16 | 17 | case class PersistedImpl[A](path: FilePath, v: A)(implicit m: StringPresentable[A]) extends Persisted[A] { 18 | override def map[B](f: (A) => B)(implicit m: StringPresentable[B]): Persisted[B] = Persisted(path, f(v)) 19 | 20 | override def get: A = v 21 | } 22 | 23 | object Persisted extends FileWriteSupport { 24 | 25 | private def write(path: FilePath, value : String) = { 26 | withWriter(path) { writer => 27 | writer.write(value) 28 | } 29 | } 30 | 31 | def read[T](path: FilePath)(implicit m: StringPresentable[T]): T = { 32 | m.fromString(Source.fromFile(path.value).getLines().mkString("\n")) 33 | } 34 | 35 | def readList[T](path: FilePath)(implicit m: StringPresentable[T]): List[T] = { 36 | Source.fromFile(path.value).getLines().map(m.fromString).toList 37 | } 38 | 39 | def apply[T](path: FilePath, v: T)(implicit m: StringPresentable[T]): Persisted[T] = { 40 | write(path, m.toString(v)) 41 | PersistedImpl(path, v) 42 | } 43 | 44 | def apply[T](path: FilePath, v: List[T])(implicit m: StringPresentable[T]): Persisted[List[T]] = { 45 | write(path, v.map(m.toString).mkString("\n")) 46 | 47 | val pathTemp = path 48 | new Persisted[List[T]] { 49 | override def get: List[T] = v 50 | 51 | override def path: FilePath = pathTemp 52 | 53 | override def map[B](f: (List[T]) => B)(implicit m: StringPresentable[B]): Persisted[B] = Persisted(path, f(v)) 54 | } 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/main/scala/monad/StringPresentable.scala: -------------------------------------------------------------------------------- 1 | package monad 2 | 3 | object StringPresentable { 4 | 5 | trait StringPresentable[T] { 6 | def toString(value: T): String 7 | 8 | def fromString(value: String): T 9 | } 10 | 11 | implicit object stringIsStringPresentable extends StringPresentable[String] { 12 | override def toString(value: String): String = value.toString 13 | 14 | override def fromString(value: String): String = value 15 | } 16 | 17 | // implicit object ListIsStringPresentable[T] extends StringPresentable[List[T]] { 18 | // 19 | // override def toString(value: List[T])(implicit m: StringPresentable[T]): String = ??? 20 | // 21 | // override def fromString(value: String)(implicit m: StringPresentable[T]): List[T] = ??? 22 | // } 23 | 24 | case class Account(owner: String, balance: Double) 25 | 26 | implicit object accountIsStringPresentable extends StringPresentable[Account]{ 27 | override def toString(value: Account): String = s"${value.owner},${value.balance}" 28 | 29 | override def fromString(value: String): Account = { 30 | val values = value.split(",") 31 | Account(values(0), values(1).toDouble) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/scala/myList/MyList.scala: -------------------------------------------------------------------------------- 1 | package myList 2 | 3 | sealed trait MyList[+A] 4 | case object Nil extends MyList[Nothing] 5 | case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A] 6 | 7 | object MyList { 8 | def sum(ints: MyList[Int]): Int = ??? 9 | 10 | def product(ds: MyList[Double]): Double = ??? 11 | 12 | def apply[A](as: A*): MyList[A] = 13 | if (as.isEmpty) Nil 14 | else Cons(as.head, apply(as.tail: _*)) 15 | 16 | val example = Cons(1, Cons(2, Cons(3, Nil))) 17 | val example2 = MyList(1, 2, 3) 18 | val total = sum(example) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/option/OptionModule.scala: -------------------------------------------------------------------------------- 1 | package option 2 | 3 | /** 4 | * this exercise show usage of Option instead of null 5 | * 1. let use implement ??? methods to return null in some condition 6 | * 2. show how complex it could be to do those null checking when implement fetch email 7 | * 3. don't forget to write unit tests! 8 | * 4. use Option instead of null 9 | * 5. show possible usage of Option in fetch email function 10 | * 5.1 use pattern matching 11 | * 5.2 use flatMap 12 | * 5.3 use for expression 13 | */ 14 | object OptionModule { 15 | 16 | case class User(name: String, age: Int) 17 | 18 | case class Connection(conn: String) extends AnyVal 19 | 20 | case class Email(value: String) extends AnyVal 21 | 22 | def getConnection(connStr: String): Connection = ??? 23 | 24 | def getUserInfo(conn: Connection, name: String): User = ??? 25 | 26 | def getEmail(user: User): Email = ??? 27 | 28 | def fetchEmail(connStr: String, name: String): Email = ??? 29 | } 30 | -------------------------------------------------------------------------------- /src/main/scala/optionSample/OptionFuncs.scala: -------------------------------------------------------------------------------- 1 | package optionSample 2 | 3 | object OptionFuncs { 4 | def map2[A,B,C](a: Option[A], b: Option[B])(f: (A,B) => C): Option[C] = { 5 | a.flatMap(x => b.map(y => f(x,y))) 6 | } 7 | 8 | 9 | def sequence[A](a : List[Option[A]]): Option[List[A]] = { 10 | a.foldLeft(Option(List[A]()))((acc,i) => map2(acc,i)((x,y) => x :+ y)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/optional/Optional.scala: -------------------------------------------------------------------------------- 1 | package optional 2 | 3 | trait Optional[+A] { 4 | def map[B](f: A => B): Optional[B] 5 | def flatMap[B](f: A => Optional[B]): Optional[B] 6 | def getOrElse[B >: A](default: => B): B 7 | def orElse[B >: A](ob: => Optional[B]): Optional[B] 8 | def filter(f: A => Boolean): Optional[A] 9 | } 10 | 11 | case class Some[+A](get: A) extends Optional[A] { 12 | override def map[B](f: (A) => B): Optional[B] = Some(f(get)) 13 | 14 | override def flatMap[B](f: (A) => Optional[B]): Optional[B] = f(get) 15 | 16 | override def filter(f: (A) => Boolean): Optional[A] = if(f(get)) this else None 17 | 18 | override def getOrElse[B >: A](default: => B): B = get 19 | 20 | override def orElse[B >: A](ob: => Optional[B]): Optional[B] = this 21 | } 22 | 23 | case object None extends Optional[Nothing] { 24 | override def map[B](f: (Nothing) => B): Optional[B] = None 25 | 26 | override def flatMap[B](f: (Nothing) => Optional[B]): Optional[B] = None 27 | 28 | override def filter(f: (Nothing) => Boolean): Optional[Nothing] = None 29 | 30 | override def getOrElse[B >: Nothing](default: => B): B = default 31 | 32 | override def orElse[B >: Nothing](ob: => Optional[B]): Optional[B] = ob 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/patternMatch/ifversion/BinarySearchWithIf.scala: -------------------------------------------------------------------------------- 1 | package patternMatch.ifversion 2 | 3 | object BinarySearchWithIf extends App { 4 | // demo from <<> 5 | def binarySearch(ds: Array[Double], key: Double): Int = { 6 | @annotation.tailrec 7 | def go(low: Int, mid: Int, high: Int): Int = { 8 | // if (low > high) -mid - 1 9 | // else { 10 | val mid2 = (low + high) / 2 11 | val d = ds(mid2) 12 | if (d == key) mid2 13 | else if (d > key) go(low, mid2, mid2 - 1) 14 | else go(mid2 + 1, mid2, high) 15 | // } 16 | } 17 | go(0, 0, ds.length - 1) 18 | } 19 | 20 | def isSorted[A](as: Array[A])(gt: (A,A) => Boolean): Boolean={ 21 | 22 | val leng=as.length 23 | 24 | def getItem(start:Int):Boolean={ 25 | if(gt(as(start),as(start+1))){ 26 | if(start<=leng-2) 27 | getItem(start+1) 28 | else 29 | true 30 | }else{ 31 | false 32 | } 33 | } 34 | getItem(0) 35 | } 36 | 37 | val doubles: Array[Double] = Array(1.0, 2.0, 3.0, 4.0, 5.0) 38 | val doubles1: Array[Double] = Array(5.0,4.0,3.0,2.0,1.0) 39 | val idx = binarySearch(doubles, 3.0) 40 | println(s"index of 3.0 is $idx") 41 | 42 | println(s"sorted: ${isSorted(doubles)(_ > _)}") 43 | println(s"sorted: ${isSorted(doubles1)(_ > _)}") 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/patternMatch/sample/PatternMatchingMain.scala: -------------------------------------------------------------------------------- 1 | package patternMatch.sample 2 | 3 | object PatternMatchingMain extends App { 4 | val x: String = "2" 5 | x match { 6 | case "1" => println("its 1") 7 | case _ => println("don'nt know") 8 | } 9 | 10 | case class User(name: String, email: String, address: Address) 11 | 12 | case class Address(lane: String, no: String) 13 | 14 | val damotou = User("damotou", "xx@xx.xx", Address("xx lane", "xx no")) 15 | damotou match { 16 | case User(_, _, addr@Address(_, no)) => println(s"address is $addr no is $no") 17 | } 18 | 19 | val list = List(1, 2, 3) 20 | 21 | list match { 22 | case List(1, _, n) => println(n) 23 | case _ => println("no match") 24 | } 25 | 26 | val pair = (2, 2, 3) 27 | 28 | pair match { 29 | case (1, _, n) => println(n) 30 | case _ => println("no match") 31 | } 32 | 33 | val n: Any = 1 34 | n match { 35 | case x: Int if x > 1 => println("its a big int") 36 | case x: Int => println("its a small int") 37 | case x: String => println("its a string") 38 | } 39 | 40 | val (i, j) = (1, 2) 41 | println(i) 42 | println(j) 43 | 44 | val map = Map(1 -> "a", 2 -> "b") 45 | map.map { case (k, v) => s"key = $k, value = $v" }.foreach(println) 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/patterns/FileTransformer.scala: -------------------------------------------------------------------------------- 1 | package patterns 2 | 3 | import java.io.{FileWriter, BufferedWriter, File} 4 | 5 | import scala.io.Source 6 | 7 | case class Path(value: String) extends AnyVal 8 | 9 | class FileTransformer extends WriteSupport with ReadSupport{ 10 | def toUpperCase(path: Path): Unit = { 11 | val content = read(path) 12 | withWriter(path){ w => 13 | w.write(content.toUpperCase) 14 | } 15 | } 16 | 17 | def toLowerCase(path: Path): Unit = { 18 | val content = read(path) 19 | withWriter(path){ w => 20 | w.write(content.toLowerCase) 21 | } 22 | } 23 | 24 | // def separate(path: Path, separator: String): Unit = ??? 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/patterns/Persist.scala: -------------------------------------------------------------------------------- 1 | package patterns 2 | 3 | trait Persist[String] { 4 | def get: String 5 | 6 | def map(f: String => String): Persist[String] 7 | } 8 | 9 | object Persist { 10 | 11 | def apply(path: Path, content: String): Persist[String] = ??? 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/patterns/ReadSupport.scala: -------------------------------------------------------------------------------- 1 | package patterns 2 | 3 | import scala.io.Source 4 | 5 | trait ReadSupport { 6 | def read(path:Path): String = Source.fromFile(path.value).mkString 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/patterns/WriteSupport.scala: -------------------------------------------------------------------------------- 1 | package patterns 2 | 3 | import java.io.{BufferedWriter, File, FileWriter} 4 | 5 | trait WriteSupport { 6 | def withWriter[A](path: Path)(f: BufferedWriter => A): A = { 7 | var writer: BufferedWriter = null 8 | try { 9 | val file = new File(path.value) 10 | writer = new BufferedWriter(new FileWriter(file)) 11 | f(writer) 12 | } finally { 13 | writer.close() 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/queryOptimizer/QueryOptimizer.scala: -------------------------------------------------------------------------------- 1 | package queryOptimizer 2 | 3 | object QueryOptimizer { 4 | case class SQL(str: String) 5 | 6 | def optimize(sql: SQL): SQL = ??? 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/Platform.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent 2 | 3 | import reactiveComponent.framework._ 4 | 5 | import scala.collection.concurrent.TrieMap 6 | import scala.concurrent.Future 7 | import scala.concurrent.ExecutionContext.Implicits.global 8 | 9 | object Platform { 10 | 11 | val cache: TrieMap[String, TrieMap[String, String]] = new TrieMap[String, TrieMap[String, String]] 12 | 13 | def run[A, B](simpleTransformation: SimpleTransformation[A, B])(input: A): Future[B] = { 14 | simpleTransformation.update(input) 15 | } 16 | 17 | def run[A, B](flow: Flow[A, B], input: A): Future[B] = { 18 | flow.runThrough(input) 19 | } 20 | 21 | def run[A <: KeyedInput, B, M](statefulComponent: => StatefulComponent[A, B, M])(input: A, model: Option[M]): Future[B] = { 22 | val optModel: Option[M] = for { 23 | processModelMap <- cache.get(statefulComponent.processName) 24 | model <- processModelMap.get(input.key) 25 | } yield statefulComponent.extract(model) 26 | 27 | //TODO ugly 28 | statefulComponent.update(optModel, input).map { 29 | case (Some(m), output) => { 30 | if (cache.contains(statefulComponent.processName)) { 31 | cache(statefulComponent.processName).update(input.key, statefulComponent.modelSerialize(m)) 32 | } else { 33 | cache.update(statefulComponent.processName, TrieMap((input.key, statefulComponent.modelSerialize(m)))) 34 | } 35 | output 36 | } 37 | case (None, output) => { 38 | if (cache.contains(statefulComponent.processName)) { 39 | cache(statefulComponent.processName) -= input.key 40 | } 41 | output 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/framework/Flow.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.framework 2 | 3 | import scala.concurrent.Future 4 | import scala.concurrent.ExecutionContext.Implicits.global 5 | 6 | trait Flow[A, B] { 7 | def append[C](simpleTransformation: SimpleTransformation[B, C]): Flow[A, C] 8 | def runThrough(input: A):Future[B] 9 | } 10 | 11 | case class LastStep[A, B](simpleTransformation: SimpleTransformation[A, B]) extends Flow[A, B] { 12 | override def append[C](that: SimpleTransformation[B, C]): Flow[A, C] = 13 | CombinedSteps(simpleTransformation, LastStep(that)) 14 | 15 | override def runThrough(input: A): Future[B] = simpleTransformation.update(input) 16 | } 17 | 18 | case class CombinedSteps[A, B, C](head: SimpleTransformation[A, B], tail: Flow[B, C]) extends Flow[A, C] { 19 | override def append[D](simpleTransformation: SimpleTransformation[C, D]): Flow[A, D] = 20 | CombinedSteps(head, tail.append(simpleTransformation)) 21 | 22 | override def runThrough(input: A): Future[C] = { 23 | val b = head.update(input) 24 | b.flatMap(tail.runThrough) 25 | }//tail.runThrough(head.update(input)) 26 | } 27 | 28 | object Flow { 29 | def connect[A, B, C](simpleTransformation: SimpleTransformation[A, B], 30 | simpleTransformation1: SimpleTransformation[B, C]): Flow[A, C] = { 31 | CombinedSteps(simpleTransformation, LastStep(simpleTransformation1)) 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/framework/ReactiveComponent.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.framework 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import reactiveComponent.framework.ComponentWithSideEffect.Result 5 | 6 | import scala.concurrent.duration._ 7 | import scala.concurrent.{Await, Future} 8 | import scala.language.postfixOps 9 | 10 | trait ReactiveComponent[A, B] { 11 | def processName: String 12 | } 13 | 14 | trait SimpleTransformation[A, B] extends ReactiveComponent[A, B] with StrictLogging { 15 | def update(input: A): Future[B] = { 16 | logger.info(s"$processName started, input: $input") 17 | val rs = Await.ready(doUpdate(input), 3 seconds) 18 | logger.info(s"$processName completed, result: $rs") 19 | rs 20 | } 21 | 22 | def doUpdate(input: A): Future[B] 23 | } 24 | 25 | // extends Result[A, B] 26 | 27 | trait KeyedInput { 28 | def key: String 29 | } 30 | 31 | trait StatefulComponent[A <: KeyedInput, B, M] extends ReactiveComponent[A, B] with StrictLogging { 32 | 33 | def update(model: Option[M], input: A): Future[(Option[M], B)] = { 34 | logger.info(s"$processName started, input: $input, model: $model") 35 | val rs = Await.ready(doUpdate(model, input), 3 seconds) 36 | logger.info(s"$processName completed, result: $rs") 37 | rs 38 | } 39 | 40 | def doUpdate(model: Option[M], input: A): Future[(Option[M], B)] 41 | 42 | def extract(model: String): M 43 | 44 | def modelSerialize(model: M): String 45 | 46 | // def run(initModel: M, input: A): Future[B] = { 47 | // runIt(initModel, input) 48 | // } 49 | // 50 | // def runIt(model: KeyedModel[K, M], input: A): Future[B] = { 51 | // update(model, input).flatMap { 52 | // case (newModel, result) => result match { 53 | // case Output(output) => Future { 54 | // output 55 | // } 56 | // case (FutureAction(futureAction)) => 57 | // futureAction.flatMap { 58 | // newInput => runIt(newModel, newInput) 59 | // } 60 | // } 61 | // } 62 | // } 63 | } 64 | 65 | trait ComponentWithSideEffect[A, B] extends ReactiveComponent[A,B] with StrictLogging { 66 | def doUpdate(input: A): Result[A,B] 67 | } 68 | 69 | object ComponentWithSideEffect { 70 | 71 | trait Result[FutureInput, Output] 72 | 73 | case class FutureAction[A, B](futureAction: () => Future[A]) extends Result[A, B] 74 | 75 | case class Output[A, B](output: B) 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/framework/Source.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.framework 2 | 3 | trait Source[T] { 4 | //will block current thread, if there is no item remains in Source. 5 | def next: T 6 | def isComplete: Boolean 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/dependency/L2Service.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.dependency 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | //import reactiveComponent.nbiot.flow.RRCRejectL2Notify 5 | //import reactiveComponent.nbiot.flow.RRCRejectL2Notify.{L2Timeout, RRCConnReject} 6 | 7 | object L2Service extends StrictLogging { 8 | // def rejectNotify: (RRCConnReject => Future[RRCRejectL2Notify.L2Timeout]) = rrcReject => { 9 | // logger.info(s"sending reject notification to L2: $rrcReject") 10 | // Thread.sleep(300) 11 | // Future { 12 | // L2Timeout() 13 | // } 14 | // } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/dependency/RBService.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.dependency 2 | 3 | import reactiveComponent.nbiot.flow._ 4 | 5 | import scala.concurrent.Future 6 | import scala.concurrent.ExecutionContext.Implicits.global 7 | 8 | 9 | object RBService { 10 | 11 | def setupRB(ueId: UeId, cellId: CellId): Future[RBSetupResult] = Future { 12 | RBSetupResult(RLC("rlc"), PDCP("pdcp"), Mac("mac"), ueId, cellId) 13 | } 14 | 15 | case class RBSetupResult(rlc: RLC, pdcp: PDCP, mac: Mac, ueId: UeId, cellId: CellId) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/CellLoadBalanceCheck.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.framework.SimpleTransformation 4 | import reactiveComponent.nbiot.flow.CellLoadBalanceCheck.{CellUECount, CheckResult} 5 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 6 | 7 | import scala.concurrent.ExecutionContext.Implicits.global 8 | import scala.concurrent.Future 9 | 10 | class CellLoadBalanceCheck extends SimpleTransformation[(UL_CCCH_MSG, CellUECount), CheckResult] { 11 | 12 | override def doUpdate(input: (UL_CCCH_MSG, CellUECount)): Future[CheckResult] = { 13 | // logger.info(Future { 14 | // CheckResult("xx", allow = true 15 | // })) 16 | input match { 17 | case (msg, CellUECount(count)) if count > CellLoadBalanceCheck.MAX_RCC_PER_CELL => { 18 | Future { 19 | CheckResult(msg, allow = false) 20 | } 21 | } 22 | case (msg, _) => { 23 | Future { 24 | CheckResult(msg, allow = true) 25 | } 26 | } 27 | } 28 | } 29 | 30 | override def processName: String = "CellLoadBalanceCheck" 31 | } 32 | 33 | 34 | object CellLoadBalanceCheck { 35 | val MAX_RCC_PER_CELL = 5 36 | 37 | case class CheckResult(ul_ccch_msg: UL_CCCH_MSG, allow: Boolean) 38 | 39 | case class CellUECount(value: Int) extends AnyVal 40 | 41 | case class Output() 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RBSetup.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.framework.SimpleTransformation 4 | import reactiveComponent.nbiot.dependency.RBService 5 | import reactiveComponent.nbiot.dependency.RBService.RBSetupResult 6 | import reactiveComponent.nbiot.flow.RBSetup.RBSetupReq 7 | import reactiveComponent.nbiot.flow.RRCProcessing.RRCInstance 8 | 9 | import scala.concurrent.Future 10 | 11 | class RBSetup extends SimpleTransformation[RBSetupReq, RBSetupResult] { 12 | 13 | 14 | override def processName: String = "RBSetup" 15 | 16 | override def doUpdate(input: RBSetupReq): Future[RBSetupResult] = { 17 | RBService.setupRB(input.rrcInstance.ueId, input.rrcInstance.cellId) 18 | } 19 | } 20 | 21 | object RBSetup { 22 | 23 | case class RBSetupReq(rrcInstance: RRCInstance) 24 | 25 | case class Success() 26 | 27 | case class Failure(reason: String) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCConnectionReject.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.framework.SimpleTransformation 4 | 5 | import scala.concurrent.Future 6 | 7 | class RRCConnectionReject extends SimpleTransformation[UeIdentity, Boolean]{ 8 | override def doUpdate(input: UeIdentity): Future[Boolean] = ??? 9 | 10 | override def processName: String = "RRCConnectionReject" 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCConnectionSetup.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.Platform 4 | import reactiveComponent.framework.SimpleTransformation 5 | import reactiveComponent.nbiot.flow.CellLoadBalanceCheck.CellUECount 6 | import reactiveComponent.nbiot.flow.RRCProcessing.RRCInstance 7 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 8 | 9 | import scala.concurrent.ExecutionContext.Implicits.global 10 | import scala.concurrent.Future 11 | import scala.util.{Failure, Success, Try} 12 | 13 | class RRCConnectionSetup extends SimpleTransformation[(UL_CCCH_MSG, CellUECount), Try[RRCInstance]] { 14 | override def doUpdate(input: (UL_CCCH_MSG, CellUECount)): Future[Try[RRCInstance]] = { 15 | val (uL_CCCH_MSG, cellUECount) = input 16 | val ueId = uL_CCCH_MSG.ueId 17 | val cellId = uL_CCCH_MSG.cellId 18 | 19 | val fRRCInstance = Platform.run(new CellLoadBalanceCheck())(input).flatMap { checkResult => 20 | if (checkResult.allow) { 21 | Platform.run(new RRCInstanceSetup)(uL_CCCH_MSG).map { 22 | rRCInstance => Success(rRCInstance) 23 | } 24 | } else { 25 | Platform.run(new RRCConnectionReject)(UeIdentity(ueId, cellId)). 26 | map(_ => Failure(new IllegalStateException("exceed cell load capacity"))) 27 | } 28 | } 29 | fRRCInstance 30 | } 31 | 32 | override def processName: String = "RRCConnectionSetup" 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCInstanceSetup.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.framework.SimpleTransformation 4 | import reactiveComponent.nbiot.flow.RRCProcessing.RRCInstance 5 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 6 | 7 | import scala.concurrent.ExecutionContext.Implicits.global 8 | import scala.concurrent.Future 9 | 10 | class RRCInstanceSetup extends SimpleTransformation[UL_CCCH_MSG, RRCInstance] { 11 | override def doUpdate(input: UL_CCCH_MSG): Future[RRCInstance] = { 12 | Future(RRCInstance(input.ueId, "some reason", input.cellId,0.50)) 13 | } 14 | 15 | override def processName: String = "RRCInstanceSetup" 16 | } 17 | 18 | object RRCInstanceSetup { 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCLocalRelease.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | class RRCLocalRelease extends { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCProcessing.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import reactiveComponent.Platform 5 | import reactiveComponent.framework.{KeyedInput, StatefulComponent} 6 | import reactiveComponent.nbiot.flow.CellLoadBalanceCheck.CellUECount 7 | import reactiveComponent.nbiot.flow.RRCProcessing._ 8 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 9 | import utils.JSONUtil 10 | 11 | import scala.concurrent.Future 12 | import scala.util.{Failure, Success} 13 | import scala.concurrent.ExecutionContext.Implicits.global 14 | 15 | class RRCProcessing extends StatefulComponent[Input, Option[RRCInstance], RRCInstance] with StrictLogging { 16 | 17 | override def processName: String = "RRCProcess" 18 | 19 | override def modelSerialize(model: RRCInstance): String = { 20 | logger.info(s"serialize model $model") 21 | val json = JSONUtil.toJSON(model) 22 | logger.info(s"json for model $model is $json") 23 | json 24 | } 25 | 26 | 27 | override def extract(model: String): RRCInstance = { 28 | logger.info(s"extract model from json $model") 29 | val rsModel = JSONUtil.fromJSONOption[RRCInstance](model).get 30 | logger.info(s"model is $rsModel") 31 | rsModel 32 | } 33 | 34 | override def doUpdate(model: Option[RRCInstance], input: Input): Future[(Option[RRCInstance], Option[RRCInstance])] = { 35 | input match { 36 | case RRCConnReq(ulccchmsg) => { 37 | logger.info("processing RRCConnReq") 38 | Platform.run(new RRCConnectionSetup)(ulccchmsg, CellUECount(3)).map { 39 | case Success(rRCInstance) => (Some(rRCInstance), Some(rRCInstance)) 40 | case Failure(e) => { 41 | e.printStackTrace() 42 | (None, None) 43 | } 44 | } 45 | } 46 | case NasTransport(ueId, cellId, content) => { 47 | logger.info("processing NasTransport") 48 | Future{ (model, model) } 49 | } 50 | case RRCRelease(ueId, cellId) => { 51 | logger.info("processing RRCRelease") 52 | Future(None,None) 53 | } 54 | } 55 | } 56 | } 57 | 58 | object RRCProcessing { 59 | 60 | //Model 61 | case class RRCInstance(ueId: UeId, rrcConnReason: String, cellId: CellId, coverRate: Double) 62 | 63 | //Input 64 | trait Input extends KeyedInput 65 | 66 | case class RRCConnReq(uL_CCCH_MSG: UL_CCCH_MSG) extends Input { 67 | override def key: String = s"s{ueId: ${uL_CCCH_MSG.ueId}, cellId: ${uL_CCCH_MSG.cellId}" 68 | } 69 | 70 | case class NasTransport(ueId: UeId, cellId: CellId, content: String) extends Input { 71 | override def key: String = s"s{ueId: $ueId, cellId: $cellId" 72 | } 73 | 74 | case class RRCRelease(ueId: UeId, cellId: CellId) extends Input { 75 | override def key: String = s"s{ueId: $ueId, cellId: $cellId" 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCProtoType.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import reactiveComponent.nbiot.dependency.RBService.RBSetupResult 4 | import reactiveComponent.nbiot.flow.RBSetup.RBSetupReq 5 | import reactiveComponent.nbiot.flow.RRCProcessing.RRCInstance 6 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 7 | 8 | import scala.util.Try 9 | 10 | object RRCProtoType extends App { 11 | 12 | case class RRCConnReq(uL_CCCH_MSG: UL_CCCH_MSG) 13 | 14 | case class MT_TCL2_DL_CCCH_MSG(ueId: UeId, cellId: CellId) 15 | 16 | def processRRCConnectionReq: RRCConnReq => Try[(RRCInstance, MT_TCL2_DL_CCCH_MSG)] = rrcConnReq => { 17 | val uL_CCCH_MSG = rrcConnReq.uL_CCCH_MSG 18 | val ueId = uL_CCCH_MSG.ueId 19 | val cellId = uL_CCCH_MSG.cellId 20 | 21 | if (cellLBCheck(ueId, cellId)) { 22 | rrcInstanceSetup(uL_CCCH_MSG).flatMap { rrcInstance => 23 | rbSetup(RBSetupReq(rrcInstance)).map { rbSetupResult => 24 | val mT_TCL2_DL_CCCH_MSG = constructRRCConnectionSetupMsg(ueId, cellId, rbSetupResult) 25 | (rrcInstance, mT_TCL2_DL_CCCH_MSG) 26 | } 27 | } 28 | } else { 29 | rrcConnReject(ueId, cellId).map { _ => 30 | throw new IllegalStateException("exceed load capacity") 31 | } 32 | } 33 | } 34 | 35 | def cellLBCheck: (UeId, CellId) => Boolean = (_, _) => true 36 | 37 | def rrcConnReject: (UeId, CellId) => Try[Unit] = (_, _) => Try(()) 38 | 39 | def rrcInstanceSetup: UL_CCCH_MSG => Try[RRCInstance] = ul_ccch_msg => Try { 40 | RRCInstance(ul_ccch_msg.ueId, "some reason", ul_ccch_msg.cellId, 0.5) 41 | // throw new IllegalArgumentException("can't setup rrcInstance") 42 | } 43 | 44 | def rbSetup: RBSetupReq => Try[RBSetupResult] = rbSetupReq => Try { 45 | val rRCInstance = rbSetupReq.rrcInstance 46 | RBSetupResult(RLC("rlc"), PDCP("pdcp"), Mac("mac"), rRCInstance.ueId, rRCInstance.cellId) 47 | } 48 | 49 | def constructRRCConnectionSetupMsg: (UeId, CellId, RBSetupResult) => MT_TCL2_DL_CCCH_MSG = (u, c, rr) => MT_TCL2_DL_CCCH_MSG(u, c) 50 | 51 | val processResult = processRRCConnectionReq(RRCConnReq(UL_CCCH_MSG("content", CellId("cell001"), UeId("ue0001")))) 52 | println(processResult) 53 | } 54 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/RRCRejectL2Notify.scala: -------------------------------------------------------------------------------- 1 | //package reactiveComponent.nbiot.flow 2 | // 3 | //import reactiveComponent.framework.{FutureAction, Output, Result, StatefulComponent} 4 | //import reactiveComponent.nbiot.flow.RRCRejectL2Notify._ 5 | // 6 | //import scala.concurrent.Future 7 | //import scala.concurrent.ExecutionContext.Implicits.global 8 | // 9 | //class RRCRejectL2Notify(val rejectNotify: RRCConnReject => Future[RRCRejectL2Notify.L2Timeout]) extends StatefulComponent[Model, Input, Boolean] { 10 | // override def doUpdate(model: Model, input: Input): Future[(Model, Result[Input, Boolean])] = input match { 11 | // case Reject(ueId) => { 12 | // Future { 13 | // (model, FutureAction(rejectNotify(RRCConnReject(ueId)))) 14 | // } 15 | // } 16 | // case (RRCRejectL2Notify.L2Timeout()) => { 17 | // Future { 18 | // (model, Output(true)) 19 | // } 20 | // } 21 | // } 22 | // 23 | // override def processName: String = "RRCRejectL2Notify" 24 | //} 25 | // 26 | //object RRCRejectL2Notify { 27 | // 28 | // trait Input 29 | // 30 | // case class Reject(ueId: UeId) extends Input 31 | // 32 | // case class L2Timeout() extends Input 33 | // 34 | // case class RRCConnReject(ueId: UeId) 35 | // 36 | // case class Model(ueId: UeId, cellId: CellId) 37 | // 38 | //} 39 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/flow/package.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot 2 | 3 | package object flow { 4 | case class CellId(value: String) extends AnyVal 5 | case class UeId(value: String) extends AnyVal 6 | case class UeIdentity(ueId: UeId, cellId: CellId) 7 | case class Mac(value: String) extends AnyVal 8 | case class RLC(value: String) extends AnyVal 9 | case class PDCP(value: String) extends AnyVal 10 | } 11 | -------------------------------------------------------------------------------- /src/main/scala/reactiveComponent/nbiot/source/L2Source.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.source 2 | 3 | import reactiveComponent.framework.Source 4 | import reactiveComponent.nbiot.flow.{CellId, UeId} 5 | 6 | trait L2Message 7 | case class UL_CCCH_MSG(content: String, cellId: CellId, ueId: UeId ) extends L2Message 8 | 9 | class L2Source[T] extends Source[T]{ 10 | 11 | private var buffer: Seq[T] = Nil 12 | 13 | def this(msgs: T *) = { 14 | this() 15 | buffer = msgs.toSeq 16 | } 17 | 18 | //will block current thread, if there is no item remains in Source. 19 | override def next: T = { 20 | Thread.sleep(1000) 21 | val rs = buffer.head 22 | buffer = buffer.tail 23 | rs 24 | } 25 | 26 | override def isComplete: Boolean = buffer.isEmpty 27 | } 28 | 29 | object L2Source { 30 | def apply(msgs: String *): L2Source[L2Message] = new L2Source[L2Message]() 31 | } 32 | -------------------------------------------------------------------------------- /src/main/scala/sample/Account.scala: -------------------------------------------------------------------------------- 1 | package sample 2 | import org.slf4j.Logger 3 | import org.slf4j.LoggerFactory 4 | 5 | class Account(val owner: String, var balance: Double) 6 | 7 | object Account { 8 | val logger = LoggerFactory.getLogger(Account.getClass()) 9 | def transfer(from: Account, to: Account, amount: Double) = { 10 | logger.info(s"tranfering from ${from.owner} to=${to.owner}") //TODO: more than two argument needs java array 11 | from.balance -= amount 12 | to.balance += amount 13 | logger.info(s"tranfer of amount $amount completed") 14 | } 15 | 16 | def credit(to: Account, amount: Double) { to.balance += amount } 17 | 18 | def valid(account: Account): Boolean = false //TODO: waiting to be implemented 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/sample/Segment.scala: -------------------------------------------------------------------------------- 1 | package sample 2 | 3 | object Segment { 4 | 5 | trait Expression 6 | 7 | case class <(value: Expression, variable: Expression) extends Expression { 8 | def <(right: Expression) = new <(this, right) 9 | } 10 | 11 | case class Variable(name: String) extends Expression 12 | 13 | case class Value(value: Int) extends Expression { 14 | def <(variable: Variable): (<) = new <(this, variable) 15 | def <(str: String):(<) = <(Variable(str)) 16 | } 17 | 18 | implicit def int2Value(value: Int):Value = Value(value) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/scripting/ScriptLoader.scala: -------------------------------------------------------------------------------- 1 | package scripting 2 | 3 | import java.io.File 4 | 5 | import com.googlecode.scalascriptengine.ScalaScriptEngine 6 | import com.typesafe.scalalogging.StrictLogging 7 | 8 | object ScriptLoader extends App with StrictLogging { 9 | logger.info("starting") 10 | val sourceDir = new File("src/test/script") 11 | val sse = ScalaScriptEngine.onChangeRefresh(sourceDir) 12 | val sqlGen = sse.newInstance[Service]("SQLGen") 13 | val sql = sqlGen.execute("xx", "yy", "sybase101", "xyz") 14 | logger.info(s"sqlGen: $sql") 15 | } 16 | -------------------------------------------------------------------------------- /src/main/scala/scripting/Service.scala: -------------------------------------------------------------------------------- 1 | package scripting 2 | 3 | trait Service { 4 | def execute(arg1: String, arg2: String, dbConn: String, tableName: String): String 5 | // = { 6 | // s"SELECT * FROM $tableName WHERE arg1='$arg1' AND arg2='$arg2'" 7 | // } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/scala/slick/DBConfigProvider.scala: -------------------------------------------------------------------------------- 1 | package slick 2 | 3 | import slick.basic.DatabaseConfig 4 | import slick.jdbc.JdbcProfile 5 | 6 | trait DBConfigProvider { 7 | def getDatabaseConfig(dbName: String): DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig(dbName) 8 | } -------------------------------------------------------------------------------- /src/main/scala/slick/Database.scala: -------------------------------------------------------------------------------- 1 | package slick 2 | 3 | import java.sql.Timestamp 4 | import java.util.Date 5 | 6 | import slick.domain._ 7 | 8 | import scala.concurrent.Future 9 | 10 | trait Database { 11 | this: DBConfigProvider => 12 | 13 | val dbConfig = getDatabaseConfig("h2mem1") 14 | 15 | lazy val databaseApi = dbConfig.profile.api 16 | 17 | import dbConfig.profile.api._ 18 | 19 | def run[T](action: slick.dbio.DBIOAction[T, NoStream, Nothing]): Future[T] = { 20 | dbConfig.db.run(action) 21 | } 22 | 23 | implicit def mapDate = MappedColumnType.base[Date, java.sql.Timestamp]( 24 | d => new Timestamp(d.getTime), 25 | ts => new Date(ts.getTime) 26 | ) 27 | 28 | abstract class AuditTable[T](tag: Tag, tableName: String) extends Table[T](tag: Tag, tableName: String) { 29 | def created = column[Option[Date]]("CREATED", O.SqlType("TIMESTAMP AS CURRENT_TIMESTAMP NOT NULL")) 30 | 31 | def createdBy = column[Option[String]]("CREATED_BY") 32 | 33 | def updated = column[Option[Date]]("UPDATED", O.SqlType("TIMESTAMP AS CURRENT_TIMESTAMP NOT NULL")) 34 | 35 | def updatedBy = column[Option[String]]("UPDATED_BY") 36 | } 37 | 38 | implicit val userTypeColumnType = MappedColumnType.base[UserType, Char]( 39 | { 40 | case SuperUser => 'S' 41 | case CommonUser => 'C' 42 | }, 43 | { 44 | case 'S' => SuperUser 45 | case 'C' => CommonUser 46 | } 47 | ) 48 | 49 | class CustomerTable(tag: Tag) extends AuditTable[Customer](tag, "customer") { 50 | def id = column[Option[String]]("ID", O.PrimaryKey, O.AutoInc) 51 | 52 | def name = column[String]("NAME", O.Unique) 53 | 54 | def birthday = column[Option[String]]("BIRTHDAY") 55 | 56 | def userType = column[UserType]("USER_TYPE") 57 | 58 | def * = (id, name, birthday, userType, (created, createdBy, updated, updatedBy)) <> 59 | ( { 60 | case (id, name, birthday, userType, audit) => 61 | Customer(id, name, birthday, userType, AuditInfo.tupled.apply(audit)) 62 | }, { 63 | c: Customer => Some(c.id, c.name, c.birthday, c.userType, AuditInfo.unapply(c.auditInfo).get) 64 | } 65 | ) 66 | } 67 | 68 | val customers = TableQuery[CustomerTable] 69 | 70 | class ProductTable(tag: Tag) extends Table[Product](tag, "product") { 71 | def id = column[Option[String]]("ID", O.PrimaryKey, O.AutoInc) 72 | 73 | def name = column[String]("NAME", O.Unique) 74 | 75 | def * = (id, name) <> (Product.tupled, Product.unapply) 76 | } 77 | 78 | val products = TableQuery[ProductTable] 79 | 80 | class OrderTable(tag: Tag) extends Table[(Option[String], String, String)](tag, "order") { 81 | def id = column[Option[String]]("ID", O.PrimaryKey, O.AutoInc) 82 | 83 | def customerId = column[String]("CUSTOMER_ID") 84 | 85 | def productId = column[String]("PRODUCT_ID") 86 | 87 | def * = (id, customerId, productId) // <> (Order.tupled,Order.unapply) 88 | 89 | def customerIdFK = foreignKey("FK_CUSTOMER", customerId, customers)(customer => customer.id.get) 90 | 91 | def productIdFK = foreignKey("FK_PRODUCT", productId, products)(product => product.id.get) 92 | } 93 | 94 | val orders = TableQuery[OrderTable] 95 | 96 | 97 | def setupDB(): Future[Unit] = { 98 | println("create tables:") 99 | customers.schema.createStatements.foreach(println) 100 | val setUp = DBIO.seq( 101 | customers.schema.create, 102 | products.schema.create, 103 | orders.schema.create 104 | ) 105 | run(setUp) 106 | } 107 | 108 | def dropDB(): Future[Unit] = { 109 | println("delete tables:") 110 | val drop = DBIO.seq( 111 | orders.schema.drop, 112 | customers.schema.drop, 113 | products.schema.drop 114 | ) 115 | run(drop) 116 | } 117 | } 118 | 119 | object Database extends Database with DBConfigProvider 120 | -------------------------------------------------------------------------------- /src/main/scala/slick/domain/Order.scala: -------------------------------------------------------------------------------- 1 | package slick.domain 2 | 3 | import java.util.Date 4 | 5 | case class AuditInfo ( 6 | created: Option[Date] = None, 7 | createdBy: Option[String] = None, 8 | updated: Option[Date] = None, 9 | updatedBy: Option[String] = None 10 | ) 11 | 12 | sealed trait UserType 13 | case object SuperUser extends UserType 14 | case object CommonUser extends UserType 15 | 16 | case class Customer(id: Option[String], name: String, birthday: Option[String], userType: UserType, auditInfo: AuditInfo) 17 | case class Product(id: Option[String], name: String) 18 | // for demo reason, only allow 1 product 1 customer in 1 order 19 | case class Order(id: Option[String], customer: Customer, product: Product) -------------------------------------------------------------------------------- /src/main/scala/slick/repo/CustomerRepo.scala: -------------------------------------------------------------------------------- 1 | package slick.repo 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import slick.Database 5 | import slick.domain._ 6 | 7 | import scala.concurrent.Future 8 | 9 | trait CustomerRepo extends StrictLogging { 10 | val database: Database 11 | 12 | import database.customers 13 | import database.databaseApi._ 14 | import database.userTypeColumnType 15 | 16 | def register(name: String,userType: UserType): Future[Customer] = { 17 | database.run(registerAction(name, userType)) 18 | } 19 | 20 | def registerAction(name: String,userType: UserType): DBIOAction[Customer, NoStream, Effect.Write] = { 21 | val q = (customers returning customers.map(_.id) 22 | into ((customer, id) => customer.copy(id = id)) 23 | ) += Customer(None, name, None,userType,AuditInfo()) 24 | q 25 | } 26 | 27 | def nextId(seqName: String): Future[Int] = { 28 | val rs = database.run[Int](Sequence[Int](seqName).next.result) 29 | rs 30 | } 31 | 32 | def listAll: Future[Seq[Customer]] = database.run(customers.result) 33 | 34 | def findByNameLike(name: String): Future[Seq[Customer]] = { 35 | val q = customers.filter(_.name like "%notyy%") 36 | database.run(q.result) 37 | } 38 | 39 | def findByUserType(userType: UserType): Future[Seq[Customer]] = { 40 | val q = customers.filter(_.userType === userType) 41 | database.run(q.result) 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/scala/slick/repo/OrderRepo.scala: -------------------------------------------------------------------------------- 1 | package slick.repo 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import slick.Database 5 | 6 | import scala.concurrent.Future 7 | 8 | trait OrderRepo extends StrictLogging { 9 | val database: Database 10 | 11 | import database._ 12 | import database.databaseApi._ 13 | 14 | def createOrder(customerId: String, productId: String): Future[String] = { 15 | database.run((orders returning orders.map(_.id) 16 | into ((_,id) => id.get) 17 | ) += (None, customerId, productId)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/scala/slick/repo/ProductRepo.scala: -------------------------------------------------------------------------------- 1 | package slick.repo 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import slick.Database 5 | import slick.domain.Product 6 | 7 | import scala.concurrent.Future 8 | 9 | trait ProductRepo extends StrictLogging { 10 | val database: Database 11 | 12 | import database._ 13 | import database.databaseApi._ 14 | 15 | def addProduct(name: String): Future[Product] = { 16 | database.run((products returning products.map(_.id) 17 | into ((product, id) => product.copy(id = id)) 18 | ) += Product(None, name)) 19 | } 20 | 21 | def listProducts(): Future[Seq[Product]] = { 22 | database.run(products.result) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/scala/slick/service/OrderService.scala: -------------------------------------------------------------------------------- 1 | package slick.service 2 | 3 | import slick.domain.{Customer, Order, Product} 4 | import slick.repo.OrderRepo 5 | 6 | import scala.concurrent.ExecutionContext.Implicits.global 7 | import scala.concurrent.Future 8 | 9 | trait OrderService { 10 | this: OrderRepo => 11 | 12 | def createOrder(customer: Customer, product: Product): Future[Order] = { 13 | createOrder(customer.id.get, product.id.get).map( 14 | oid => Order(Some(oid), customer,product) 15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/smallPractice/MyMaths.scala: -------------------------------------------------------------------------------- 1 | package smallPractice 2 | 3 | import scala.annotation.tailrec 4 | 5 | object MyMaths { 6 | @tailrec 7 | def maxDiviser(x: Int, y: Int): Int = { 8 | if (x == y) x 9 | else maxDiviser(math.abs(x - y), math.min(x, y)) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/sqlGen/DBConfigLoader.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | import sqlGen.Domain.SQLPart 4 | 5 | trait DBConfigLoader { 6 | def loadConfig: SQLPart = ??? 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/sqlGen/Domain.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | object Domain { 4 | trait Granularity 5 | case object RNCGranularity extends Granularity 6 | case object CELLGranularity extends Granularity 7 | 8 | case class TimeSegment(start: String, end: String) 9 | 10 | case class SQL(str: String) extends AnyVal 11 | case class SQLPart(str: String) extends AnyVal 12 | } 13 | -------------------------------------------------------------------------------- /src/main/scala/sqlGen/GranularitySQLGenerator.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | import sqlGen.Domain.SQLPart 4 | 5 | trait GranularitySQLGenerator { 6 | def genGranularitySQL: SQLPart 7 | } 8 | 9 | trait RNCGranularitySQLGenerator extends GranularitySQLGenerator{ 10 | override def genGranularitySQL: SQLPart = SQLPart("'RNC'") 11 | } 12 | 13 | trait CELLGranularitySQLGenerator extends GranularitySQLGenerator{ 14 | override def genGranularitySQL: SQLPart = SQLPart("'CELL'") 15 | } -------------------------------------------------------------------------------- /src/main/scala/sqlGen/ReportSQLGeneratorImpl.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | import sqlGen.Domain.{SQL, TimeSegment} 3 | 4 | trait ReportSQLGenerator { 5 | def genSQL(timeSegments: List[TimeSegment]): SQL 6 | } 7 | 8 | trait ReportSQLGeneratorImpl extends ReportSQLGenerator { 9 | this: GranularitySQLGenerator with TimeSegmentSQLGenerator with DBConfigLoader => 10 | 11 | override def genSQL(timeSegments: List[TimeSegment]): SQL = { 12 | SQL(s"SELECT * FROM $calls WHERE granularity = ${genGranularitySQL.str}" + 13 | s" AND ${genTimeSegmentsSQL(timeSegments).str} AND configInDB = ${loadConfig.str}") 14 | } 15 | 16 | def calls = "calls" 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/sqlGen/TimeSegmentSQLGenerator.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | import sqlGen.Domain.{SQLPart, TimeSegment} 4 | 5 | trait TimeSegmentSQLGenerator { 6 | def genTimeSegmentsSQL(segments: List[TimeSegment]): SQLPart = { 7 | SQLPart(segments.map(genSingleTimeSegmentSQL).reduce((s1,s2) => s"$s1 OR $s2")) 8 | } 9 | 10 | private def genSingleTimeSegmentSQL(segment: TimeSegment): String = { 11 | val TimeSegment(start, end) = segment 12 | s"(timeSegments < '$end' AND timeSegments > '$start')" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/state/RNG.scala: -------------------------------------------------------------------------------- 1 | //package state 2 | // 3 | //import state.RNG.Rand 4 | // 5 | //trait RNG { 6 | // val int: Rand[Int] = _.nextInt 7 | // 8 | // def nextInt: (Int, RNG) 9 | //} 10 | // 11 | //case class State[S,+A](run: S => (A,S)) { 12 | // 13 | // def unit(a: A): S => (A,S) = s => (a,s) 14 | // 15 | // def map[B](f: A => B): S => (B,S) = s => { 16 | // val (a, s1) = run(s) 17 | // (f(a),s1) 18 | // } 19 | //} 20 | // 21 | //object RNG { 22 | // type State[S,+A] = S => (A, S) 23 | // type Rand[A] = State[RNG, A] 24 | // 25 | // def simple(seed: Long): RNG = new RNG { 26 | // def nextInt = { 27 | // val seed2 = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1) 28 | // ((seed2 >>> 16).asInstanceOf[Int], 29 | // simple(seed2)) 30 | // } 31 | // } 32 | // 33 | // def positiveInt: Rand[Int] = rng => { 34 | //// map(rng.int){ i => 35 | //// if (i != Int.MinValue) i.abs else positiveInt(rng) 36 | //// } 37 | //// rng.nextInt match { 38 | //// case (v, r) => if (v != Int.MinValue) (v.abs, r) else positiveInt(r) 39 | //// } 40 | // ??? 41 | // } 42 | // 43 | // def double: Rand[Double] = { rng => 44 | // val (v, r) = positiveInt(rng) 45 | // (v / Int.MaxValue, r) 46 | // } 47 | // 48 | // def intDouble: Rand[(Int, Double)] = { rng => 49 | // val (i, r1) = positiveInt(rng) 50 | // val (d, r2) = double(r1) 51 | // ((i, d), r2) 52 | // } 53 | // 54 | // def doubleInt: Rand[(Double, Int)] = { rng => 55 | // intDouble(rng) match { 56 | // case ((i, d), r) => ((d, i), r) 57 | // } 58 | // } 59 | // 60 | // def double3: Rand[(Double, Double, Double)] = { rng => 61 | // double(rng) match { 62 | // case (d1, r1) => double(r1) match { 63 | // case (d2, r2) => double(r2) match { 64 | // case (d3, r3) => ((d1, d2, d3), r3) 65 | // } 66 | // } 67 | // } 68 | // } 69 | // 70 | // def ints(count: Int): Rand[List[Int]] = rng => (count, rng) match { 71 | // case (0, _) => (Nil, rng) 72 | // case (i, r) => positiveInt(rng) match { 73 | // case (x, r1) => ints(i - 1)(r1) match { 74 | // case (l, r2) => (x :: l, r2) 75 | // } 76 | // } 77 | // } 78 | // 79 | // def unit[S,A](a: A): S => (A,S) = rng => (a, rng) 80 | // 81 | // 82 | // def positiveMax(n: Int): Rand[Int] = map(positiveInt)(_ / Int.MaxValue * n) 83 | // 84 | // def doubleByMap: Rand[Double] = map(positiveInt)(_ / Int.MaxValue) 85 | // 86 | // def intDoubleByMap2:Rand[(Int,Double)] = map2(positiveInt, doubleByMap)((_,_)) 87 | // 88 | // def sequence[A](fs: List[Rand[A]]): Rand[List[A]] = { 89 | // fs.foldLeft(unit[RNG,List[A]](List[A]()))((acc, r) => map2(acc, r)((l, a) => a :: l)) 90 | // } 91 | // 92 | // def map[S,A, B](s:S => (A,S))(f: A => B): S => (B,S) = r => { 93 | // val (v, r1) = s(r) 94 | // (f(v), r1) 95 | // } 96 | // 97 | // def flatMap[S,A,B](f: S => (A,S))(g: A => (S => (B,S))): S => (B,S) = rng => { 98 | // val (a,r1) = f(rng) 99 | // g(a)(r1) 100 | // } 101 | // 102 | // def mapByFlatMap[S,A, B](a: S => (A,S))(f: A => B): S => (B,S) = flatMap(a)(f andThen unit) 103 | // 104 | // def map2[A,B,C](r1: Rand[A], r2: Rand[B])(f: (A,B) => C) : Rand[C] = r => { 105 | // val (a, rg1) = r1(r) 106 | // val (b, rg2) = r2(rg1) 107 | // (f(a,b), rg2) 108 | // } 109 | // 110 | //// def map2ByFlatMap[A,B,C](r1: Rand[A], r2: Rand[B])(f: (A,B) => C) : Rand[C] = r => { 111 | //// val (a, rg1) = r1(r) 112 | //// flatMap(r1)(x => r2(rg1)) 113 | //// } 114 | //} 115 | -------------------------------------------------------------------------------- /src/main/scala/stats/pregnent/PregnancyAnalyze.scala: -------------------------------------------------------------------------------- 1 | package stats.pregnent 2 | 3 | object PregnancyAnalyze { 4 | case class Pregnancy(caseId:Int, prgLength: Int, outcome: Int, birthOrd: Int, finalWgt: Float) 5 | 6 | def extract(str: String): Pregnancy = { 7 | Pregnancy( 8 | transform(str, 0,12, _.toInt).get, 9 | transform(str,274,276,_.toInt).get, 10 | transform(str,276,277,_.toInt).get, 11 | transform(str,277,279,_.toInt).getOrElse(-1), 12 | str.substring(422,440).trim.toFloat 13 | ) 14 | } 15 | 16 | private def transform[A](src: String,startIdx: Int, endIdx: Int, f: String => A):Option[A] = { 17 | val v = src.substring(startIdx, endIdx).trim 18 | if(v.isEmpty) None else Some(f(v)) 19 | } 20 | 21 | def liveBirthCount(pregnancies: List[Pregnancy]): Int = pregnancies.count(_.outcome == 1) 22 | 23 | def liveBirthGroupByBirthOrder(pregnancies: List[Pregnancy]): (List[Pregnancy], List[Pregnancy]) = { 24 | val lives = pregnancies.filter(_.outcome >= 1) 25 | (lives.filter(_.birthOrd == 1), lives.filter(_.birthOrd != 1)) 26 | } 27 | 28 | def avgPrgLength(pregnancies: List[Pregnancy]): Float = pregnancies.map(_.prgLength).sum / pregnancies.size 29 | } 30 | -------------------------------------------------------------------------------- /src/main/scala/streaming/CellStream.scala: -------------------------------------------------------------------------------- 1 | package streaming 2 | 3 | object CellStream extends App { 4 | 5 | case class Cell(state: Int) { 6 | def update(f: Int => Int) = Cell(f(state)) 7 | } 8 | 9 | def cellStream(startFrom: Cell, updateFunc: Int => Int): Stream[Cell] = startFrom #:: { 10 | var curr = startFrom 11 | Stream.continually { 12 | val rs = curr.update(updateFunc) 13 | curr = rs 14 | rs 15 | } 16 | } 17 | 18 | println(cellStream(Cell(1), _ + 1)) 19 | cellStream(Cell(1), _ + 1).take(10).foreach(println) 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/scala/temp/Codec.scala: -------------------------------------------------------------------------------- 1 | package temp 2 | 3 | class Message[T](val cmd: String, val data: T) { 4 | 5 | } 6 | 7 | trait ICodec[T <: Message[_]] { 8 | def getMessage: T 9 | } 10 | 11 | 12 | //fixme 这子类不知道怎么定义,反正是错的 13 | class StringCodec extends ICodec[Message[_]] { 14 | //class StringCodec extends ICodec[Message[String]]{ 15 | override def getMessage: Message[String] = { 16 | new Message[String]("cmd", "msg") 17 | } 18 | } 19 | 20 | object Tester { 21 | //fixme 这个也是错的 22 | def getCodec: ICodec[Message[_]] = new StringCodec 23 | 24 | def useCodec(codec: ICodec[Message[_]]) = codec.getMessage 25 | } 26 | 27 | object Main extends App { 28 | println(Tester.useCodec(new StringCodec)) 29 | } 30 | -------------------------------------------------------------------------------- /src/main/scala/temp/UglyJavaVsScala.scala: -------------------------------------------------------------------------------- 1 | package temp 2 | 3 | object UglyJavaVsScala { 4 | def sum(xs: List[Int]): Int = xs.foldLeft(0)(_ + _) 5 | 6 | def sum1(xs: List[Int]): Int = xs.reduce(_ + _) 7 | 8 | def sum2(xs: List[Int]): Int = xs.sum 9 | 10 | def add(x:Int, y: Int): Int = x + y 11 | 12 | def sum3(xs: List[Int]): Int = xs.foldLeft(0)(add) 13 | } -------------------------------------------------------------------------------- /src/main/scala/temp/UnitList.scala: -------------------------------------------------------------------------------- 1 | package temp 2 | 3 | object UnitList extends App{ 4 | var list = List(()) 5 | (1 to 10).foreach{ _ => 6 | list = (1,2,3):: list 7 | } 8 | println(list) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/traitSample/武将.scala: -------------------------------------------------------------------------------- 1 | package traitSample 2 | 3 | trait 武将 { 4 | def 杀():Unit = ??? 5 | def 闪():Unit = ??? 6 | } 7 | 8 | trait 枪将{ 9 | def 突刺(): Unit = ??? 10 | } 11 | 12 | object 张飞 extends 武将 with 枪将 13 | 14 | object 三国游戏 extends App { 15 | 张飞.突刺() 16 | } -------------------------------------------------------------------------------- /src/main/scala/typeParameter/InstanceTypeCheck.scala: -------------------------------------------------------------------------------- 1 | package typeParameter 2 | 3 | import scala.reflect.ClassTag 4 | 5 | object InstanceTypeCheck extends App{ 6 | def isInstanceOf[T: ClassTag](x: Any): Boolean = x match { 7 | case (x: T) => true 8 | case _ => false 9 | } 10 | 11 | println(isInstanceOf[Int]("x")) 12 | println(isInstanceOf[Int](1:Int)) 13 | println(isInstanceOf[List[Int]](List("x"))) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/utils/Combinator.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import scala.io._ 4 | import java.io._ 5 | 6 | object Combinator { 7 | type Line = String 8 | 9 | def doOver(inputFile: String, outputFile: String)(f: Line => Line): Unit = { 10 | doOver(Source.fromFile(inputFile).getLines())(f) { rs => 11 | val pw = new PrintWriter(outputFile) 12 | pw.write(rs.mkString("\n")) 13 | pw.close() 14 | } 15 | } 16 | 17 | def doOver[A, B](in: => Iterator[A])(f: A => B)(out: Iterator[B] => Unit): Unit = { 18 | out(in.map(f)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/scala/utils/JSONUtil.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | 4 | import org.json4s._ 5 | import org.json4s.native.Serialization 6 | import scala.util.Try 7 | 8 | object JSONUtil { 9 | 10 | implicit val formats = DefaultFormats 11 | 12 | def toJSON(objectToWrite: AnyRef): String = Serialization.write(objectToWrite) 13 | 14 | def fromJSONOption[T](jsonString: String)(implicit mf: Manifest[T]): Option[T] = Try(Serialization.read(jsonString)).toOption 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/utils/StreamBenchmark.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import scala.io.Source 4 | 5 | object StreamBenchmark extends App { 6 | val runtime: Runtime = Runtime.getRuntime 7 | println(s"max memory ${b2m(runtime.maxMemory())}MB") 8 | println(s"total memory ${b2m(runtime.totalMemory())}") 9 | println(s"init free memory ${b2m(runtime.freeMemory())}") 10 | val file = Source.fromFile("/Users/twer/source/bigdata/data/new2.dat") 11 | var size = 0 12 | file.getLines().toStream.foreach(_ => size += 1) 13 | //file.getLines().toList.foreach(_ => size += 1) 14 | //file.getLines().foreach(_ => size += 1) 15 | println(s"data size: $size") 16 | 17 | //println(s"data size: ${file.getLines().toList.size}") 18 | //println(s"data size: ${file.getLines().size}") 19 | //runtime.gc() 20 | println(s"remain total memory ${b2m(runtime.totalMemory())}") 21 | println(s"remain free memory ${b2m(runtime.freeMemory())}") 22 | 23 | 24 | def b2m(byte: Long): String = s"${byte / 1024 /1024}MB" 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/variants/Chef.scala: -------------------------------------------------------------------------------- 1 | package variants 2 | 3 | object Chef extends App { 4 | val fruit = new Fruit 5 | val apple = new Apple 6 | 7 | def cutFruit: Fruit => FruitPiece = { fruit => 8 | println(s"cutting ${fruit.name}") 9 | new FruitPiece 10 | } 11 | 12 | def cutApple: Apple => ApplePiece = {apple => 13 | println(s"cutting ${apple.name}") 14 | new ApplePiece 15 | } 16 | 17 | def cutIt(f: Apple => FruitPiece): FruitPiece = f(apple) 18 | 19 | cutIt(cutFruit) 20 | cutIt(cutApple) 21 | } 22 | -------------------------------------------------------------------------------- /src/main/scala/variants/Fruit.scala: -------------------------------------------------------------------------------- 1 | package variants 2 | 3 | class Fruit{ 4 | val name: String = "Fruit" 5 | } 6 | class FruitPiece{ 7 | val name: String = "FruitPiece" 8 | } 9 | class Apple extends Fruit{ 10 | override val name: String = "Apple" 11 | } 12 | class ApplePiece extends FruitPiece{ 13 | override val name: String = "ApplePiece" 14 | } 15 | -------------------------------------------------------------------------------- /src/main/scala/withLog/WithLogModule.scala: -------------------------------------------------------------------------------- 1 | package withLog 2 | 3 | object WithLogModule extends App{ 4 | def withLog[A,B](funcName: String)(f: A => B): A => B = { x => 5 | println(s"calling $funcName with $x") 6 | val rs = f(x) 7 | println(s"result is $rs") 8 | rs 9 | } 10 | 11 | def add1:Int => Int = withLog("add1"){x:Int => x + 1} 12 | 13 | add1(1) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/thrift/BinaryService.thrift: -------------------------------------------------------------------------------- 1 | #@namespace scala notyy.github.thrift 2 | 3 | service BinaryService { 4 | string fetchBlob(1: i64 id) 5 | } -------------------------------------------------------------------------------- /src/main/thrift/DicService.thrift: -------------------------------------------------------------------------------- 1 | #@namespace scala in.xnnyygn.dictservice 2 | 3 | exception DictServiceException { 4 | 1: string description 5 | } 6 | 7 | service DictService { 8 | 9 | string get(1: string key) throws(1: DictServiceException ex) 10 | 11 | void put(1: string key, 2: string value) 12 | } -------------------------------------------------------------------------------- /src/test/fixture/words.txt: -------------------------------------------------------------------------------- 1 | hello world are you ok ? 2 | yes 3 | I am ok and you ? -------------------------------------------------------------------------------- /src/test/java/ListUtilJavaTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import static org.hamcrest.CoreMatchers.is; 7 | import static org.junit.Assert.assertThat; 8 | 9 | public class ListUtilJavaTest { 10 | @Test 11 | public void testFilter() throws Exception { 12 | List list = Arrays.asList(1,2,3,4,5); 13 | List rs = ListUtil.filter(list, new FilterFunction() { 14 | @Override 15 | public boolean filter(Integer item) { 16 | return item > 2; 17 | } 18 | }); 19 | assertThat(rs.size(), is(3)); 20 | assertThat(rs, is(Arrays.asList(3, 4, 5))); 21 | } 22 | 23 | @Test 24 | public void testMap() throws Exception { 25 | List list = Arrays.asList(1,2,3,4,5); 26 | List rs = ListUtil.map(list, new MapFunction() { 27 | @Override 28 | public Integer map(Integer item) { 29 | return item * 2; 30 | } 31 | }); 32 | assertThat(rs.size(), is(5)); 33 | assertThat(rs, is(Arrays.asList(2,4,6,8,10))); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/MyMapTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import org.mockito.ArgumentCaptor; 3 | import org.mockito.InOrder; 4 | import org.mockito.Mockito; 5 | 6 | import static org.hamcrest.core.Is.is; 7 | import static org.junit.Assert.assertNull; 8 | import static org.junit.Assert.assertThat; 9 | import static org.mockito.Mockito.*; 10 | 11 | public class MyMapTest { 12 | @Test 13 | public void mockito_can_set_when_return_value_multiple_times() { 14 | MyMap mockMap = mock(MyMap.class); 15 | SomeParameter expectedParameter = new SomeParameter("value1", "value2"); 16 | when(mockMap.get("key1")).thenReturn(null).thenReturn(expectedParameter); 17 | 18 | SomeProcessor someProcessor = new SomeProcessor(); 19 | someProcessor.doProcess(mockMap); 20 | 21 | InOrder inOrder = inOrder(mockMap); 22 | ArgumentCaptor argument = ArgumentCaptor.forClass(SomeParameter.class); 23 | inOrder.verify(mockMap).put(eq("key1"), argument.capture()); 24 | assertThat(argument.getValue().getValue1(), is(expectedParameter.getValue1())); 25 | assertThat(argument.getValue().getValue2(), is(expectedParameter.getValue2())); 26 | 27 | inOrder.verify(mockMap).put(eq("key2"), argument.capture()); 28 | assertThat(argument.getValue().getValue1(), is(expectedParameter.getValue1())); 29 | assertThat(argument.getValue().getValue2(), is(expectedParameter.getValue2())); 30 | } 31 | 32 | //this is the class to be tested 33 | class SomeProcessor { 34 | public void doProcess(MyMap myMap) { 35 | if (myMap.get("key1") == null) { 36 | myMap.put("key1", new SomeParameter("value1", "value2")); 37 | } 38 | 39 | SomeParameter someParameter = (SomeParameter) myMap.get("key1"); 40 | if (someParameter.getValue1().equals("value1")) { 41 | myMap.put("key2", someParameter); 42 | } 43 | } 44 | } 45 | 46 | class SomeParameter { 47 | 48 | public SomeParameter(String value1, String value2) { 49 | this.value1 = value1; 50 | this.value2 = value2; 51 | } 52 | 53 | public String getValue1() { 54 | return value1; 55 | } 56 | 57 | public String getValue2() { 58 | return value2; 59 | } 60 | 61 | private String value1; 62 | private String value2; 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/java/UglyJavaTest.scala: -------------------------------------------------------------------------------- 1 | import java.util 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class UglyJavaTest extends FunSpec with Matchers { 6 | describe("UglyJava"){ 7 | ignore("sum a given List"){ 8 | val uj = new UglyJava 9 | val list = new util.ArrayList[Integer](util.Arrays.asList[Integer](1, 2, 3, 4, 5)) 10 | uj.getSum(list) shouldBe 24 11 | // list shouldBe util.Arrays.asList[Integer](1, 2, 3, 4, 5) 12 | } 13 | it("can sum a given list in a pure way"){ 14 | val uj = new UglyJava 15 | val list = new util.ArrayList[Integer](util.Arrays.asList[Integer](1, 2, 3, 4, 5)) 16 | uj.getSum1(list) shouldBe 15 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/doOverSample.txt: -------------------------------------------------------------------------------- 1 | hello 2 | world -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | logs/sbtTemplate.log 10 | 11 | %d{HH:mm:ss} %level %logger{36} - %msg%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/test/resources/sample.txt: -------------------------------------------------------------------------------- 1 | 张国荣 2 | 林青霞 3 | 我老土 -------------------------------------------------------------------------------- /src/test/resources/test.conf: -------------------------------------------------------------------------------- 1 | h2mem1 { 2 | profile = "slick.jdbc.H2Profile$" 3 | db { 4 | // connectionPool = disabled 5 | driver = "org.h2.Driver" 6 | url = "jdbc:h2:mem:test2;DB_CLOSE_DELAY=-1" 7 | keepAliveConnection = true 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/scala/ListUtilTest.scala: -------------------------------------------------------------------------------- 1 | import org.scalatest.{FunSpec, Matchers} 2 | 3 | import scala.collection.JavaConversions._ 4 | 5 | class ListUtilTest extends FunSpec with Matchers { 6 | describe("ListUtil") { 7 | it("allows to apply filter function to a List") { 8 | val list = List(1, 2, 3, 4, 5) 9 | val result = ListUtil.filter(list, new FilterFunction[Int] { 10 | def filter(item: Int): Boolean = item > 2 11 | }) 12 | result.size() should be(3) 13 | result.toList should be(List(3, 4, 5)) 14 | } 15 | 16 | it("allows to apply map function to a list") { 17 | val list = List(1, 2, 3, 4, 5) 18 | val result = ListUtil.map(list, new MapFunction[Int, Int] { 19 | def map(item: Int): Int = item * 2 20 | }) 21 | result.size() should be (5) 22 | result.toList should be(List(2,4,6,8,10)) 23 | } 24 | it("generate result as list, so it can be combined"){ 25 | val list = List[Integer](1,2,3,4,5) 26 | val rs1 = ListUtil.filter(list, new FilterFunction[Integer] { 27 | def filter(item: Integer): Boolean = item > 2 28 | }) 29 | val rs2 = ListUtil.map(rs1, new MapFunction[Integer,Integer] { 30 | def map(item: Integer): Integer = item * 2 31 | }) 32 | rs2.size() should be (3) 33 | rs2.toList should be (List(6,8,10)) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/scala/MapSampleTest.scala: -------------------------------------------------------------------------------- 1 | import org.scalatest.{FunSpec, Matchers} 2 | 3 | import scala.collection.JavaConversions._ 4 | 5 | class MapSampleTest extends FunSpec with Matchers { 6 | describe("a MapSample"){ 7 | it("should select element that is >2 , then do * 2 to each element"){ 8 | val mapSample = new MapSample() 9 | val list = List[Integer](1,2,3,4,5) 10 | val rs = mapSample.process(list) 11 | rs.size() should be (3) 12 | rs.toList should be (List(6,8,10)) 13 | } 14 | it("should select element that is >2 , then do * 2 to each element, with functional programming"){ 15 | val mapSample = new MapSample() 16 | val list = List[Integer](1,2,3,4,5) 17 | val rs = mapSample.funcProcess(list) 18 | rs.size() should be (3) 19 | rs.toList should be (List(6,8,10)) 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/scala/ScalaMapSampleSpec.scala: -------------------------------------------------------------------------------- 1 | import org.scalatest.{FunSpec, Matchers} 2 | 3 | class ScalaMapSampleSpec extends FunSpec with Matchers { 4 | describe("a MapSample") { 5 | it("should select element that is >2 , then do * 2 to each element") { 6 | val list = List(1, 2, 3, 4, 5) 7 | val rs = ScalaMapSample.process(list) 8 | rs should have size 3 9 | rs.toList shouldBe List(6, 8, 10) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/cakePatternSimple/UserServiceTest.scala: -------------------------------------------------------------------------------- 1 | package cakePatternSimple 2 | 3 | import org.scalatest.FunSpec 4 | 5 | class UserServiceTest extends FunSpec { 6 | describe("UserService"){ 7 | it("can find all users"){ 8 | // val userService = new DefaultUserService with UserRepositoryImpl with DefaultTransactionManager 9 | val userService = new UserServiceImpl with UserRepositoryImpl with TransactionManagerImpl 10 | // userService.findAll 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/akkaStream/MapUtilTest.scala: -------------------------------------------------------------------------------- 1 | package concurrency.akkaStream 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class MapUtilTest extends FunSpec with Matchers { 6 | describe("MapUtil"){ 7 | it("can merge two maps"){ 8 | val map1 = Map("a" -> 1,"b" -> 1) 9 | val map2 = Map("b" -> 1, "c" -> 1) 10 | val result = MapUtil.mergeMaps(map1, map2)(_ + _) 11 | result should have size 3 12 | result("a") shouldBe 1 13 | result("b") shouldBe 2 14 | result("c") shouldBe 1 15 | } 16 | it("can merge map by implicit"){ 17 | val map1 = Map("a" -> 1,"b" -> 1) 18 | val map2 = Map("b" -> 1, "c" -> 1) 19 | import MapUtil._ 20 | val result = map1.merge(map2)(_ + _) 21 | result should have size 3 22 | result("a") shouldBe 1 23 | result("b") shouldBe 2 24 | result("c") shouldBe 1 25 | } 26 | it("can merge more than 2 maps"){ 27 | val map1 = Map("a" -> 1,"b" -> 1) 28 | val map2 = Map("b" -> 1, "c" -> 1) 29 | val map3 = Map("c" -> 1, "d" -> 1) 30 | val result = MapUtil.mergeMaps(map1, map2, map3)(_ + _) 31 | result should have size 4 32 | result("a") shouldBe 1 33 | result("b") shouldBe 2 34 | result("c") shouldBe 2 35 | result("d") shouldBe 1 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/par/DataAggregatorSpec.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class DataAggregatorSpec extends FunSpec with Matchers { 6 | describe("DataAggregatorSpec") { 7 | it("can bind order amount and customer name") { 8 | val dataAggregator = new Object with DataAggregator with MockCustomerRepository with MockOrderRepository { 9 | val customerData: Set[(CustomerId, Name)] = Set("1" -> "xx", "2" -> "yy", "3" -> "zz") 10 | val orderData: Set[(CustomerId, OrderAmount)] = Set("1" -> 30, "1" -> 50, "2" -> 10, "3" -> 100) 11 | } 12 | 13 | val rs = dataAggregator.aggregate(_ > 10) 14 | rs should have size 3 15 | rs should contain("xx" -> 30) 16 | rs should contain("xx" -> 50) 17 | rs should contain("zz" -> 100) 18 | rs should not contain ("yy" -> 10) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/par/MockCustomerRepository.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | trait MockCustomerRepository extends CustomerRepository{ 4 | def customerData: Set[(CustomerId, Name)] 5 | 6 | override def fetch(cid: CustomerId): Option[Name] = { 7 | logger.info(s"getting customer name for cid:$cid") 8 | Thread.sleep(1000) 9 | val rs = customerData.find(_._1 == cid).map(_._2) 10 | logger.info(s"customer name for cid:$cid is $rs") 11 | rs 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/par/MockCustomerRepositorySpec.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class MockCustomerRepositorySpec extends FunSpec with Matchers{ 6 | describe("MockCustomerRepository"){ 7 | it("can get customer name by id"){ 8 | val customerDataProvider = new MockCustomerRepository { 9 | override def customerData: Set[(CustomerId, Name)] = Set("1" -> "xx", "2" -> "yy", "3" -> "zz") 10 | } 11 | customerDataProvider.fetch("1").get shouldBe "xx" 12 | customerDataProvider.fetch("2").get shouldBe "yy" 13 | customerDataProvider.fetch("3").get shouldBe "zz" 14 | customerDataProvider.fetch("4") shouldBe None 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/par/MockOrderRepository.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | trait MockOrderRepository extends OrderRepository{ 4 | def orderData: Set[(CustomerId, OrderAmount)] 5 | 6 | override def filterByAmount(f: OrderAmount => Boolean): Set[(CustomerId, OrderAmount)] = { 7 | orderData.filter { case (_, amount) => f(amount)} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/par/OrderDataSelectorSpec.scala: -------------------------------------------------------------------------------- 1 | package concurrency.par 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class OrderDataSelectorSpec extends FunSpec with Matchers{ 6 | describe("MasterDataProvider"){ 7 | it("can filter data by order amount"){ 8 | val orderDataProvider = new MockOrderRepository { 9 | override val orderData: Set[(CustomerId, OrderAmount)] = Set("1" -> 30, "1" -> 50, "2" -> 10, "3" -> 100) 10 | } 11 | val customerIds = orderDataProvider.filterByAmount(_ > 10).map(_._1) 12 | customerIds.size shouldBe 2 13 | customerIds should contain ("1") 14 | customerIds should contain ("3") 15 | customerIds shouldNot contain ("2") 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/concurrency/promise/Double11.scala: -------------------------------------------------------------------------------- 1 | package concurrency.promise 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | import scala.concurrent._ 7 | 8 | case class Money(amount: Double) 9 | 10 | case class Shoe(brand: String) 11 | 12 | object Double11 extends App with StrictLogging { 13 | logger.info("演出开始") 14 | val p = Promise[Money]() 15 | val f = p.future 16 | 17 | val 大雄的剧本 = Future { 18 | logger.info("大雄去给小静打钱") 19 | Thread.sleep(2000) 20 | p.success(Money(500)) 21 | logger.info("大雄出去玩了") 22 | Thread.sleep(2000) 23 | } 24 | 25 | val 小静的剧本 = Future { 26 | logger.info("小静在逛淘宝") 27 | Thread.sleep(3000) 28 | f.onSuccess { 29 | case money => buyShoesFromHongkong(money) 30 | } 31 | logger.info("小静给大雄做晚饭") 32 | Thread.sleep(2000) 33 | } 34 | 35 | 大雄的剧本.onSuccess{ 36 | case _ => logger.info("大雄回家了") 37 | } 38 | 39 | 小静的剧本.onSuccess{ 40 | case _ => logger.info("小静和大雄高兴的一起吃饭") 41 | } 42 | 43 | Thread.sleep(6000) 44 | logger.info("演出结束") 45 | 46 | def buyShoesFromHongkong(money: Money): Shoe = { 47 | logger.info("buying shoes from hongkong") 48 | val shoes = Shoe("Asics") 49 | logger.info(s"shoes bought from hongkong: $shoes") 50 | shoes 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/scala/diamondProblem/DTest.scala: -------------------------------------------------------------------------------- 1 | package diamondProblem 2 | 3 | import org.scalatest.FunSpec 4 | 5 | class DTest extends FunSpec { 6 | D.hello() 7 | } 8 | -------------------------------------------------------------------------------- /src/test/scala/excercise/fp/FactorySpec.scala: -------------------------------------------------------------------------------- 1 | package excercise.fp 2 | 3 | import excercise.fp.Factory._ 4 | import org.scalatest.tags.Slow 5 | import org.scalatest.{FunSpec, Matchers} 6 | import org.slf4j.LoggerFactory 7 | import tags.Tags.{DbTest, FastTest} 8 | 9 | @Slow 10 | class FactorySpec extends FunSpec with Matchers { 11 | val logger = LoggerFactory.getLogger(this.getClass) 12 | 13 | describe("object Factory defines many functions") { 14 | describe("createPlan") { 15 | it("should create order processing plan" + 16 | " for given ProductionResource and OrderRequest",DbTest) { 17 | val request = """G: 2 18 | |M: 1 19 | |R: 1 20 | |P: 1 21 | |Order: zteT zteW zteX""".stripMargin('|').lines.toList 22 | val expectedResult = """Order#1 23 | |G1: zteT zteW 24 | |G2: zteX 25 | |M: zteX zteW zteT 26 | |R: zteX zteW zteT 27 | |P: zteX zteW zteT 28 | |Total: 17 hours""".stripMargin('|').lines.toList 29 | pending 30 | createPlan(request) shouldBe expectedResult 31 | } 32 | 33 | describe("parseResourceDesc") { 34 | it("can parse G: 2 to (G,2)") { 35 | parseResourceDesc("G: 2") shouldBe(GMachine, Quantity(2)) 36 | } 37 | } 38 | 39 | describe("initializeMachine") { 40 | it("can convert machineType&quantity to machine instance",FastTest) { 41 | val rd: ResourceDesc = (GMachine, Quantity(2)) 42 | val machines = initializeMachine(rd) 43 | machines.size shouldBe 2 44 | machines(0).machine.id shouldBe 1 45 | machines(0).products shouldBe empty 46 | machines(1).machine.id shouldBe 2 47 | machines(1).products shouldBe empty 48 | } 49 | } 50 | describe("arrangeProduction") { 51 | it("can assign product to machine") { 52 | val workProcesses: List[WorkProcess] = List( 53 | WorkProcess(Machine(GMachine, 1), Nil), 54 | WorkProcess(Machine(GMachine, 2), Nil), 55 | WorkProcess(Machine(MMachine, 1), Nil), 56 | WorkProcess(Machine(RMachine, 1), Nil), 57 | WorkProcess(Machine(PMachine, 1), Nil) 58 | ) 59 | 60 | val zteTArranged = arrangeProduction(workProcesses)(Product("zteT")) 61 | zteTArranged(0).products shouldBe List(Product("zteT")) 62 | zteTArranged(1).products shouldBe Nil 63 | zteTArranged(2).products shouldBe List(Product("zteT")) 64 | zteTArranged(3).products shouldBe List(Product("zteT")) 65 | zteTArranged(4).products shouldBe List(Product("zteT")) 66 | 67 | val zteWArranged = arrangeProduction(zteTArranged)(Product("zteW")) 68 | zteWArranged.foreach(x => logger.info(x.toString)) 69 | zteWArranged(0).products shouldBe List(Product("zteT")) 70 | zteWArranged(1).products shouldBe List(Product("zteW")) 71 | zteWArranged(2).products shouldBe List(Product("zteT"), Product("zteW")) 72 | zteWArranged(3).products shouldBe List(Product("zteT"), Product("zteW")) 73 | zteWArranged(4).products shouldBe List(Product("zteT"), Product("zteW")) 74 | } 75 | } 76 | 77 | describe("formatShowPlan"){ 78 | it("should pretty print a plan"){ 79 | 80 | val workProcess = List( 81 | WorkProcess(Machine(GMachine, 1), List(Product("zteT"))), 82 | WorkProcess(Machine(GMachine, 2), List(Product("zteW"))), 83 | WorkProcess(Machine(MMachine, 1), List(Product("zteT"), Product("zteW"))), 84 | WorkProcess(Machine(PMachine, 1), List(Product("zteT"), Product("zteW"))), 85 | WorkProcess(Machine(RMachine, 1), List(Product("zteT"), Product("zteW")))) 86 | val plan = Plan(1, workProcess) 87 | logger.warn(formatShowPlan(plan)) 88 | } 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/scala/expressiveness/typeclass/ClientTest.scala: -------------------------------------------------------------------------------- 1 | package expressiveness.typeclass 2 | 3 | import expressiveness.typeclass.ShapeModule.{Circle, Square} 4 | import org.scalatest.{FunSpec, Matchers} 5 | 6 | class ClientTest extends FunSpec with Matchers{ 7 | describe("Client"){ 8 | it("should print area of shape"){ 9 | Client.printArea(Square(5.0)) 10 | Client.printArea(Circle(5.0)) 11 | } 12 | it("should print perimeter of shape"){ 13 | Client.printPerimeter(Square(5.0)) 14 | // Client.printPerimeter(Circle(5.0)) 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/ft/sample/AccountAcceptSpec.scala: -------------------------------------------------------------------------------- 1 | package ft.sample 2 | 3 | import org.scalatest.{Matchers, FeatureSpec, GivenWhenThen} 4 | import sample.Account 5 | import tags.Tags.FunctionTest 6 | 7 | class AccountAcceptSpec extends FeatureSpec with GivenWhenThen with Matchers { 8 | feature("Account can be created,checked,and transfer with each other") { 9 | info("As Account Manager") 10 | info("I want account system can make sure money in accounts be transfered safely,account status can be checked") 11 | info("to ensure the stable and accurate of whole accounting system") 12 | 13 | scenario("money can transfer between accounts",FunctionTest) { 14 | Given("Account A,amount 100") 15 | val accountA = new Account("A", 100.00) 16 | And("Account B,amount 50") 17 | val accountB = new Account("B", 50.00) 18 | When("transfer 50 from account A to account B") 19 | Account.transfer(accountA, accountB, 50.00) 20 | Then("amount in account A becomes 50") 21 | accountA.balance should be (50) 22 | And("amount in account B becomes 100") 23 | accountB.balance should be (100) 24 | } 25 | 26 | scenario("Account can be created,Account must have owner and initialization amount must be > 0")(pending) 27 | scenario("can not transfer more money than balance of the account")(pending) 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/scala/hoi4/Hoi4HelperTest.scala: -------------------------------------------------------------------------------- 1 | package hoi4 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import Hoi4Helper._ 5 | 6 | class Hoi4HelperTest extends FunSpec with Matchers { 7 | 8 | val infantry37 = DivisionType("infantry37", Map( 9 | smallArms2 -> 750, 10 | artillery2 -> 84, 11 | support -> 40 12 | )) 13 | 14 | val motorized41 = DivisionType("motorized41", Map( 15 | smallArms2 -> 710, 16 | artillery2 -> 12, 17 | motorized -> 410, 18 | support -> 80, 19 | selfRocket -> 40 20 | )) 21 | 22 | describe("Hoi4Helper") { 23 | it("can calc how many equipment it needs for a given number of divisions") { 24 | val equipments = divisionEquiptments(infantry37, 2) 25 | equipments should have size 3 26 | equipments(smallArms2) shouldBe 1500 27 | equipments(artillery2) shouldBe 168 28 | equipments(support) shouldBe 80 29 | } 30 | it("can calc total equipments requirement by equipment types") { 31 | val division1Equipments: Map[Equipment, Int] = infantry37.equipments 32 | val division2Equipments: Map[Equipment, Int] = motorized41.equipments 33 | val total = totalEquipments(List(division1Equipments,division2Equipments)) 34 | total should have size 5 35 | total(smallArms2) shouldBe 1460 36 | total(artillery2) shouldBe 96 37 | total(motorized) shouldBe 410 38 | total(selfRocket) shouldBe 40 39 | total(support) shouldBe 120 40 | } 41 | it("can calc required factory number for a given equipment to be produce in one year"){ 42 | requiredFactoryToProduceInOneYear(carrierFighter1, 100) shouldBe 0.8908428020101175 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/scala/hotelPractice/fp/HotelReservationServiceTest.scala: -------------------------------------------------------------------------------- 1 | package hotelPractice.fp 2 | 3 | import hotelPractice.fp.HotelReservationService.{Agenda, Hotel, Regular} 4 | import org.scalatest.{FunSpec, Matchers} 5 | 6 | class HotelReservationServiceTest extends FunSpec with Matchers { 7 | private val lakewood: Hotel = Hotel( 8 | name = "LakeWood", rating = 3, 9 | regularWeekdayPrice = 110.0, 10 | rewardsWeekdayPrice = 80, 11 | regularWeekendPrice = 90, 12 | rewardsWeekendPrice = 80 13 | ) 14 | private val bridgewood: Hotel = Hotel( 15 | name = "Bridgewood", rating = 4, 16 | regularWeekdayPrice = 160.0, 17 | rewardsWeekdayPrice = 110, 18 | regularWeekendPrice = 60, 19 | rewardsWeekendPrice = 50 20 | ) 21 | private val ridgewood: Hotel = Hotel( 22 | name = "Ridgewood", rating = 5, 23 | regularWeekdayPrice = 220.0, 24 | rewardsWeekdayPrice = 100, 25 | regularWeekendPrice = 150, 26 | rewardsWeekendPrice = 40 27 | ) 28 | 29 | val hotels: Seq[Hotel] = List( 30 | lakewood, 31 | bridgewood, 32 | ridgewood 33 | ) 34 | 35 | describe("HotelReservationService") { 36 | 37 | it("can select hotel for regular customer in weekday") { 38 | HotelReservationService.recommendHotel(hotels)("Regular: 16Mar2009(mon), 17Mar2009(tues), 18Mar2009(wed)") shouldBe "LakeWood" 39 | } 40 | 41 | it("can select hotel for regular customer containing weekday and weekend") { 42 | HotelReservationService.recommendHotel(hotels)("Regular: 20Mar2009(fri), 21Mar2009(sat), 22Mar2009(sun)") shouldBe "Bridgewood" 43 | } 44 | 45 | it("can select hotel for rewards customer containing weekday and weekend") { 46 | HotelReservationService.recommendHotel(hotels)("Rewards: 26Mar2009(thur), 27Mar2009(fri), 28Mar2009(sat)") shouldBe "Ridgewood" 47 | } 48 | 49 | it("can parse input to Agenda") { 50 | val input = "Regular: 16Mar2009(mon), 17Mar2009(tues), 18Mar2009(wed)" 51 | val agenda = HotelReservationService.parse(input) 52 | agenda.customerType shouldBe Regular 53 | agenda.dates should have size 3 54 | agenda.dates.head._1 shouldBe "16Mar2009" 55 | agenda.dates.head._2 shouldBe "mon" 56 | } 57 | 58 | it("can calculate price for a agenda in a single hotel") { 59 | val agenda = Agenda(Regular, List(("16Mar2009", "mon"))) 60 | HotelReservationService.calcPriceSingle(lakewood)(agenda) shouldBe (lakewood,110) 61 | } 62 | 63 | it("should select cheapest hotel"){ 64 | HotelReservationService.selectHotel(List((lakewood, 100.0), (bridgewood,200.0))) shouldBe lakewood 65 | } 66 | 67 | it("should select higher rate if price is same"){ 68 | HotelReservationService.selectHotel(List((lakewood, 100.0), (bridgewood,100.0))) shouldBe bridgewood 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/scala/hr/ExCalculatorSpec.scala: -------------------------------------------------------------------------------- 1 | package hr 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class ExCalculatorSpec extends FunSpec with Matchers { 6 | describe("Excalculator"){ 7 | it("can calculator e^x"){ 8 | ExCalculator.f(20.0000f) shouldBe (2423600.1887f +- 0.0001f) 9 | ExCalculator.f(5.0000f) shouldBe (143.6895f +- 0.0001f) 10 | ExCalculator.f(0.5000f) shouldBe (1.6487f +- 0.0001f) 11 | ExCalculator.f(-0.5000f) shouldBe (0.6065f +- 0.0001f) 12 | } 13 | it("can calculator e^x given any terms"){ 14 | ExCalculator.ff(1,1) shouldBe 2 15 | ExCalculator.ff(1,2) shouldBe 2.5 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/scala/it/sample/AccountScalaCheckSpec.scala: -------------------------------------------------------------------------------- 1 | package it.sample 2 | 3 | import org.scalatest.prop.GeneratorDrivenPropertyChecks 4 | import org.scalatest.{FeatureSpec, GivenWhenThen, Matchers} 5 | import sample.Account 6 | 7 | class AccountScalaCheckSpec extends FeatureSpec with GivenWhenThen with Matchers with GeneratorDrivenPropertyChecks { 8 | feature("Account can be created,checked,and transfer with each other") { 9 | info("As Account Manager") 10 | info("I want account system can make sure money in accounts be transfered safely,account status can be checked") 11 | info("to ensure the stable and accurate of whole accunting system") 12 | 13 | scenario("Account can be created,Account must have owner and initialization amount must be > 0")(pending) 14 | scenario("money can transfer between account") { 15 | Given("Account A,amount > 0") 16 | And("Account B,amount > 0") 17 | When("transfer from account A to account B,amount < balance of account A") 18 | Then("balance in account A = init amount - transfer amount") 19 | And("balance in account B = init amount + transfer amount") 20 | And("balance in account A and account are both >= 0") 21 | And("sum of balance in account A and account B are same as before transfer") 22 | 23 | forAll("balanceA", "balanceB", "transferAmount", minSuccessful(50), maxDiscarded(5000)) { 24 | (balanceA: Double, balanceB: Double, transferAmount: Double) => 25 | whenever(balanceA > 0.00 && balanceB > 0.00 26 | && transferAmount <= balanceA && transferAmount >= 0.00) { 27 | val accountA = new Account("A", balanceA) 28 | val accountB = new Account("B", balanceB) 29 | val (oldA, oldB) = (accountA.balance, accountB.balance) 30 | Account.transfer(accountA, accountB, transferAmount) 31 | accountA.balance should be (oldA - transferAmount) 32 | accountB.balance should be (oldB + transferAmount) 33 | accountA.balance should be >= 0.00 34 | accountB.balance should be >= 0.00 35 | (accountA.balance + accountB.balance) shouldBe (oldA + oldB) 36 | } 37 | } 38 | } 39 | scenario("amount can transfer between account, but transfer amount can't > it's balance")(pending) 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/scala/loanPattern/SampleTxtProcessorLoanImplTest.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class SampleTxtProcessorLoanImplTest extends FunSpec with Matchers { 6 | describe("SampleTxtProcessorLoanImpl"){ 7 | it("can count how many lines are there in a file"){ 8 | val txtProcessor = new SampleTxtProcessorLoanImpl with FileReadSupport 9 | txtProcessor.countLines("src/test/resources/sample.txt") shouldBe 3 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/scala/loanPattern/SampleTxtProcessorTest.scala: -------------------------------------------------------------------------------- 1 | package loanPattern 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class SampleTxtProcessorTest extends FunSpec with Matchers { 6 | describe("SampleTxtProcessor"){ 7 | it("can count how many lines are there in a file"){ 8 | SampleTxtProcessor.countLines("src/test/resources/sample.txt") shouldBe 3 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/scala/microbenchmarks/CaseClassCollectionToListListStringBenchmark.scala: -------------------------------------------------------------------------------- 1 | package microbenchmarks 2 | 3 | import org.scalameter.api._ 4 | 5 | object CaseClassCollectionToListListStringBenchmark extends PerformanceTest.Quickbenchmark{ 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/test/scala/microbenchmarks/CollectionAppendBenchmark.scala: -------------------------------------------------------------------------------- 1 | package microbenchmarks 2 | 3 | import org.scalameter.api._ 4 | 5 | object CollectionAppendBenchmark extends PerformanceTest.OfflineReport { 6 | // val sizes: Gen[Int] = Gen.range("size")(10000, 50000, 10000) 7 | // 8 | // var list = List.empty[Int] 9 | // var array = ArrayBuffer.empty[Int] 10 | // var vector = Vector.empty[Int] 11 | // 12 | // performance of "Vector" in { 13 | // measure method ":+" in { 14 | // using(sizes) in { s => 15 | // var max = 0 16 | // while(max < s) { 17 | // vector = vector :+ 1 18 | // max += 1 19 | // } 20 | // } 21 | // } 22 | // } 23 | // 24 | // performance of "List" in { 25 | // //can't 26 | //// measure method ":+" in { 27 | //// using(sizes) in { s => 28 | //// var max = 0 29 | //// while(max < s) { 30 | //// list = list :+ 1 31 | //// max += 1 32 | //// } 33 | //// } 34 | //// } 35 | // measure method ":: then reverse" in { 36 | // using(sizes) in { s => 37 | // var max = 0 38 | // while(max < s) { 39 | // list = 1 :: list 40 | // max += 1 41 | // } 42 | // list.reverse 43 | // } 44 | // } 45 | // } 46 | // 47 | // performance of "ArrayBuffer" in { 48 | // measure method "+=" in { 49 | // using(sizes) in { s => 50 | // var max = 0 51 | // while(max < s) { 52 | // array += 1 53 | // max += 1 54 | // } 55 | // } 56 | // } 57 | // } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/scala/microbenchmarks/PerfOfWhile.scala: -------------------------------------------------------------------------------- 1 | package microbenchmarks 2 | 3 | import org.scalameter.api._ 4 | 5 | object PerfOfWhile extends PerformanceTest.OfflineReport { 6 | def whileLoop(size: Int): Int = { 7 | var c = 0 8 | while(c < size){ 9 | { 10 | if ( c % 19 == 0) c+=3 else c+=1 11 | } 12 | } 13 | c 14 | } 15 | 16 | def foreachLoop(size: Int): Int = { 17 | var c = 0 18 | (1 to size).foreach(_ => c += 1) 19 | (1 to 10).indexOf(1) 20 | c 21 | } 22 | 23 | val sizes: Gen[Int] = Gen.range("size")(10000000, 100000000, 10000000) 24 | 25 | performance of "whileLoop" in { 26 | measure method "while" in { 27 | using(sizes) in { whileLoop } 28 | } 29 | } 30 | 31 | performance of "foreachLoop" in { 32 | measure method "foreach" in { 33 | using(sizes) in { foreachLoop } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/scala/monad/PersistedTest.scala: -------------------------------------------------------------------------------- 1 | package monad 2 | 3 | import java.io.File 4 | 5 | import monad.StringPresentable.Account 6 | import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} 7 | 8 | import scala.io.Source 9 | 10 | class PersistedTest extends FunSpec with Matchers with BeforeAndAfter { 11 | 12 | val path = FilePath("./temp/test.txt") 13 | val content = "hello,world\n" 14 | 15 | before { 16 | val tempDir = new File("./temp") 17 | if(!tempDir.exists() || !tempDir.isDirectory){ 18 | tempDir.mkdir() 19 | } 20 | new File(path.value).delete() 21 | } 22 | 23 | describe("Persisted monad") { 24 | it("can put value inside persisted context, value will be saved to given file path") { 25 | Persisted(path, content) shouldBe PersistedImpl(path, content) 26 | Source.fromFile(path.value).getLines().toList should contain("hello,world") 27 | } 28 | it("can take value out of context") { 29 | Persisted(path, content).get shouldBe content 30 | } 31 | it("can change value inside persisted context without take it out") { 32 | Persisted(path, content).map(_.toUpperCase).get shouldBe content.toUpperCase 33 | Source.fromFile(path.value).getLines().toList should not contain "hello,world" 34 | Source.fromFile(path.value).getLines().toList should contain("HELLO,WORLD") 35 | } 36 | it("can persist any type T, as long as T is StringPresentable") { 37 | val persistedAccount = Persisted(path, Account("yy",500.0)) 38 | Source.fromFile(path.value).getLines().toList should contain("yy,500.0") 39 | } 40 | it("can read back object from file"){ 41 | val persistedAccount = Persisted(path, Account("yy",500.0)) 42 | Persisted.read[Account](path) shouldBe persistedAccount.get 43 | } 44 | it("can write and read back list of objects"){ 45 | val persistedAccounts = Persisted(path, List(Account("xx",200.0), Account("yy", 300.0))) 46 | Source.fromFile(path.value).getLines().toList should contain("xx,200.0") 47 | Source.fromFile(path.value).getLines().toList should contain("yy,300.0") 48 | val readValues: List[Account] = Persisted.readList[Account](path) 49 | readValues should contain(Account("xx",200.0)) 50 | readValues should contain(Account("yy",300.0)) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/scala/optionSample/OptionFuncsTest.scala: -------------------------------------------------------------------------------- 1 | package optionSample 2 | 3 | import optionSample.OptionFuncs._ 4 | import org.scalatest.{FunSpec, Matchers} 5 | 6 | class OptionFuncsTest extends FunSpec with Matchers { 7 | describe("map2"){ 8 | it("should combines two options"){ 9 | map2(Some(List(1)), Some(2))((a,b) => a :+ b) shouldBe Some(List(1,2)) 10 | map2(Some(List(1)), None)((a,b) => a :+ b) shouldBe None 11 | } 12 | } 13 | 14 | describe("sequence"){ 15 | it("should extract values from option list"){ 16 | sequence(List(Some(1),None,Some(2))) shouldBe None 17 | sequence(List(Some(1),Some(2))) shouldBe Some(List(1,2)) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/scala/queryOptimizer/QueryOptimizerSpec.scala: -------------------------------------------------------------------------------- 1 | package queryOptimizer 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import queryOptimizer.QueryOptimizer.SQL 5 | 6 | class QueryOptimizerSpec extends FunSpec with Matchers{ 7 | describe("QueryOptimizer"){ 8 | it("should optimize a raw sql, generate better sql"){ 9 | pending 10 | val rawSQL = SQL("SELECT name from (SELECT id,name FROM person) p WHERE p.id=1") 11 | QueryOptimizer.optimize(rawSQL) shouldBe SQL("SELECT name FROM person WHERE id=1") 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/scala/reactiveComponent/framework/FlowTest.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.framework 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | import scala.concurrent.ExecutionContext.Implicits.global 6 | import scala.concurrent.duration._ 7 | import scala.concurrent.{Await, Future} 8 | import scala.language.postfixOps 9 | 10 | class FlowTest extends FunSpec with Matchers { 11 | describe("Flow") { 12 | it("can combine small component and run") { 13 | val step1 = new SimpleTransformation[Int, Int] { 14 | override def doUpdate(input: Int): Future[Int] = Future { 15 | input + 1 16 | } 17 | 18 | override def processName: String = "Step1" 19 | } 20 | 21 | val step2 = new SimpleTransformation[Int, String] { 22 | override def doUpdate(input: Int): Future[String] = Future { 23 | input.toString 24 | } 25 | 26 | override def processName: String = "Step2" 27 | } 28 | 29 | Await.result(CombinedSteps(step1, LastStep(step2)).runThrough(1), 1 seconds) shouldBe "2" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/scala/reactiveComponent/nbiot/flow/CellLoadBalanceCheckTest.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import org.scalatest.{FunSpec, Matchers} 5 | import reactiveComponent.Platform 6 | import reactiveComponent.nbiot.flow.CellLoadBalanceCheck.CellUECount 7 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 8 | 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration._ 11 | import scala.language.postfixOps 12 | 13 | class CellLoadBalanceCheckTest extends FunSpec with Matchers with StrictLogging { 14 | describe("CellLoadBalanceCheck") { 15 | it("should check cell load balance") { 16 | val checkResult = (new CellLoadBalanceCheck).update(UL_CCCH_MSG("content", CellId("1"), UeId("5")), CellUECount(4)) 17 | val future = Await.ready(checkResult, 3 seconds) 18 | logger.info(s"checkResult: $future") 19 | } 20 | it("can also be run from Platform") { 21 | val checkResult = Platform.run(new CellLoadBalanceCheck)(UL_CCCH_MSG("content", CellId("1"), UeId("5")), CellUECount(4)) 22 | val future = Await.ready(checkResult, 3 seconds) 23 | logger.info(s"checkResult: $future") 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/scala/reactiveComponent/nbiot/flow/RRCProcessingTest.scala: -------------------------------------------------------------------------------- 1 | package reactiveComponent.nbiot.flow 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import org.scalatest.{FunSpec, Matchers} 5 | import reactiveComponent.Platform 6 | import reactiveComponent.nbiot.flow.RRCProcessing.{NasTransport, RRCConnReq} 7 | import reactiveComponent.nbiot.source.UL_CCCH_MSG 8 | 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration._ 11 | import scala.language.postfixOps 12 | 13 | class RRCProcessingTest extends FunSpec with Matchers with StrictLogging { 14 | describe("RRCProcessing") { 15 | it("can process rrc connection req") { 16 | val ueId: UeId = UeId("U1001") 17 | val cellId: CellId = CellId("C1001") 18 | 19 | val rrcInstance = Await.result( 20 | Platform.run(new RRCProcessing)(RRCConnReq(UL_CCCH_MSG("some content", cellId, ueId)), None), 21 | 3 seconds 22 | ) 23 | logger.info(s"rrcInstance is: $rrcInstance") 24 | logger.info(s"platform cache has data: ${Platform.cache}") 25 | rrcInstance.get.ueId shouldBe ueId 26 | rrcInstance.get.cellId shouldBe cellId 27 | 28 | val nasTransportResult = Await.result( 29 | Platform.run(new RRCProcessing)(NasTransport(ueId,cellId,"some content"), None), 30 | 3 seconds 31 | ) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/scala/sample/AccountSpec.scala: -------------------------------------------------------------------------------- 1 | package sample 2 | import org.scalatest.{FunSpec, Matchers} 3 | 4 | class AccountSpec extends FunSpec with Matchers { 5 | describe("An Account") { 6 | it("should have owner when initialized,and balance >= 0") { 7 | val account = new Account("notyy", 100) 8 | account.owner should not be null 9 | account.balance should be > 0.00 10 | } 11 | 12 | it("amount can be transfer between accounts,total balance should be same after transfer") { 13 | val accountA = new Account("A", 100.00) 14 | val accountB = new Account("B", 50.00) 15 | val sum = accountA.balance + accountB.balance 16 | Account.transfer(accountA, accountB, 50) 17 | accountA.balance should be (50.00) 18 | accountB.balance should be (100.00) 19 | val newSum = accountA.balance + accountB.balance 20 | sum should be (newSum) 21 | } 22 | 23 | it("Legality of account can be checked")(pending) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/sample/SegmentTest.scala: -------------------------------------------------------------------------------- 1 | package sample 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import sample.Segment._ 5 | 6 | class SegmentTest extends FunSpec with Matchers { 7 | describe("segment"){ 8 | it("can be expressed by UnOp"){ 9 | val expr = 5 < "EcIo" 10 | val expr1 = 5 < "EcIo" < 10 11 | expr1 match { 12 | case (Value(left) < Variable(name)) => println(s"$left < $name") 13 | case (Value(left) < Variable(name) < Value(right)) => println(s"$left < $name < $right") 14 | case _ => println("don't know") 15 | } 16 | } 17 | it("expression can be regexed"){ 18 | val BinOpLT = """(\d+)(<|<=|=)(\w+)""".r 19 | val Between = """(\d+)(<|<=|=)(\w+)(<|<=|=)(\d+)""".r 20 | val BinOpGT = """(\w+)(>|>=|=)(\d+)""".r 21 | 22 | val expr1 = "5 println(s"$left $op $variable") 25 | case Between(left,op1,variable, op2, right) => println(s"$left $op1 $variable $op2 $right") 26 | case BinOpGT(variable, op, right) => println(s"$variable $op $right") 27 | case _ => println(s"can't parse expression:$expr1") 28 | } 29 | } 30 | // it("a list can be pattern matching"){ 31 | // val list = List(1,2,3) 32 | // list match { 33 | // case 1:: 2:: x :: Nil => println(s"x=$x") 34 | // case _ => println("nothing") 35 | // } 36 | // } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/scala/slick/repo/CustomerRepoTest.scala: -------------------------------------------------------------------------------- 1 | package slick.repo 2 | 3 | import java.sql.SQLException 4 | 5 | import com.typesafe.scalalogging.StrictLogging 6 | import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} 7 | import slick.domain.{CommonUser, SuperUser} 8 | import slick.{DBConfigProvider, Database} 9 | 10 | import scala.concurrent.Await 11 | import scala.concurrent.duration._ 12 | import scala.language.postfixOps 13 | import scala.util.{Failure, Success} 14 | 15 | class CustomerRepoTest extends FunSpec with Matchers with BeforeAndAfter with StrictLogging with TestDatabase { 16 | val customerRepo = new CustomerRepo with DBConfigProvider { 17 | override val database: Database = myDatabase 18 | } 19 | 20 | before { 21 | Await.result(myDatabase.setupDB(), 5 seconds) 22 | } 23 | 24 | after { 25 | Await.result(myDatabase.dropDB(), 5 seconds) 26 | } 27 | 28 | describe("CustomerRepo") { 29 | it("allow user to register customer into database") { 30 | Await.result(customerRepo.listAll, 5 seconds).length shouldBe 0 31 | val customer = Await.result(customerRepo.register("notyy", SuperUser), 5 seconds) 32 | customer.id should not be empty 33 | Await.result(customerRepo.listAll, 5 seconds).length shouldBe 1 34 | } 35 | 36 | it("can query user by name fuzzily") { 37 | Await.result(customerRepo.listAll, 5 seconds).length shouldBe 0 38 | Await.result(customerRepo.register("notyyXXXzz", SuperUser), 5 seconds) 39 | Await.result(customerRepo.register("notyyYYYzz", SuperUser), 5 seconds) 40 | Await.result(customerRepo.register("xxxxYYYzz", CommonUser), 5 seconds) 41 | Await.result(customerRepo.listAll, 5 seconds) should have size 3 42 | Await.result(customerRepo.listAll, 5 seconds).foreach(println) 43 | 44 | println("find by name like notyy") 45 | val customers = Await.result(customerRepo.findByNameLike("notyy"), 5 seconds) 46 | println("find by name like notyy complete") 47 | customers should have size 2 48 | customers.foreach(println) 49 | customers.forall(_.name.contains("notyy")) shouldBe true 50 | customers.forall(_.auditInfo.created.isDefined) shouldBe true 51 | } 52 | it("can query by user type") { 53 | Await.result(customerRepo.listAll, 5 seconds).length shouldBe 0 54 | Await.result(customerRepo.register("notyyXXXzz", SuperUser), 5 seconds) 55 | Await.result(customerRepo.register("notyyYYYzz", SuperUser), 5 seconds) 56 | Await.result(customerRepo.register("xxxxYYYzz", CommonUser), 5 seconds) 57 | Await.result(customerRepo.listAll, 5 seconds) should have size 3 58 | 59 | val customers = Await.result(customerRepo.findByUserType(SuperUser), 5 seconds) 60 | customers should have size 2 61 | customers.foreach(println) 62 | customers.forall(_.name.contains("notyy")) shouldBe true 63 | customers.forall(_.auditInfo.created.isDefined) shouldBe true 64 | } 65 | it("supports transaction") { 66 | import myDatabase.databaseApi._ 67 | 68 | val actions = DBIO.seq( 69 | customerRepo.registerAction("notyy", CommonUser), 70 | customerRepo.registerAction("notyy", SuperUser) //name is unique, so it should fail 71 | ).transactionally 72 | import scala.concurrent.ExecutionContext.Implicits.global 73 | val rs = myDatabase.run(actions) 74 | rs.onComplete { 75 | case Success(_) => fail("should not success") 76 | case Failure(ex) => logger.error("error occur with sql {}", ex) 77 | } 78 | Await.ready(rs, 5 seconds) 79 | Await.result(customerRepo.listAll, 5 seconds).length shouldBe 0 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/scala/slick/repo/TestDatabase.scala: -------------------------------------------------------------------------------- 1 | package slick.repo 2 | 3 | import com.typesafe.config.ConfigFactory 4 | import com.typesafe.scalalogging.StrictLogging 5 | import slick.basic.DatabaseConfig 6 | import slick.{DBConfigProvider, Database} 7 | 8 | trait TestDatabase { 9 | lazy val myDatabase = TestDatabaseInstance 10 | } 11 | 12 | object TestDatabaseInstance extends Database with DBConfigProvider with StrictLogging { 13 | override def getDatabaseConfig(dbName: String) = { 14 | val testConfig = ConfigFactory.load("test") 15 | DatabaseConfig.forConfig(dbName, testConfig) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/test/scala/slick/service/OrderServiceSpec.scala: -------------------------------------------------------------------------------- 1 | package slick.service 2 | 3 | import com.typesafe.scalalogging.StrictLogging 4 | import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} 5 | import slick.domain.CommonUser 6 | import slick.{DBConfigProvider, Database} 7 | import slick.repo.{CustomerRepo, OrderRepo, ProductRepo, TestDatabase} 8 | 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration._ 11 | import scala.language.postfixOps 12 | 13 | class OrderServiceSpec extends FunSpec with Matchers with BeforeAndAfter with StrictLogging with TestDatabase { 14 | 15 | val customerRepo = new CustomerRepo with DBConfigProvider { 16 | override val database: Database = myDatabase 17 | } 18 | 19 | val productRepo = new ProductRepo with DBConfigProvider { 20 | override val database: Database = myDatabase 21 | } 22 | 23 | before{ 24 | Await.result(myDatabase.setupDB(), 5 seconds) 25 | } 26 | 27 | after { 28 | Await.result(myDatabase.dropDB(), 5 seconds) 29 | } 30 | 31 | describe("OrderService"){ 32 | it("can create order"){ 33 | val orderService:OrderService = new OrderService with OrderRepo with DBConfigProvider { 34 | override val database = myDatabase 35 | } 36 | val customer = Await.result(customerRepo.register("notyy",CommonUser), 5 seconds) 37 | val product = Await.result(productRepo.addProduct("iphoneX"), 5 seconds) 38 | val order = Await.result(orderService.createOrder(customer,product), 5 seconds) 39 | order.id shouldBe defined 40 | order.customer shouldBe customer 41 | order.product shouldBe product 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/scala/smallPractice/MyMathsSpec.scala: -------------------------------------------------------------------------------- 1 | package smallPractice 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | 5 | class MyMathsSpec extends FunSpec with Matchers{ 6 | describe("MyMaths"){ 7 | it("can calculate max diviser of two ints"){ 8 | MyMaths.maxDiviser(98, 63) shouldBe 7 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/scala/sqlGen/ReportSQLGeneratorImplTest.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import sqlGen.Domain._ 5 | 6 | class ReportSQLGeneratorImplTest extends FunSpec with Matchers { 7 | 8 | trait SampleDBConfigLoader extends DBConfigLoader{ 9 | override def loadConfig: SQLPart = SQLPart("'dbproperties'") 10 | } 11 | 12 | describe("ReportSQLGenerator"){ 13 | it("should generate sql for producing report"){ 14 | val granularity:Granularity = RNCGranularity 15 | 16 | val reportGenerator = granularity match { 17 | case RNCGranularity => new ReportSQLGeneratorImpl with TimeSegmentSQLGenerator with RNCGranularitySQLGenerator with SampleDBConfigLoader {} 18 | case CELLGranularity => new ReportSQLGeneratorImpl with TimeSegmentSQLGenerator with CELLGranularitySQLGenerator with SampleDBConfigLoader {} 19 | } 20 | 21 | val sql = reportGenerator.genSQL(List(TimeSegment("2014-03-04", "2014-04-05"))) 22 | sql shouldBe SQL("SELECT * FROM calls WHERE granularity = 'RNC' " + 23 | "AND (timeSegments < '2014-04-05' AND timeSegments > '2014-03-04') AND configInDB = 'dbproperties'") 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/scala/sqlGen/TimeSegmentSQLGeneratorTest.scala: -------------------------------------------------------------------------------- 1 | package sqlGen 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import sqlGen.Domain.{SQLPart, TimeSegment} 5 | 6 | class TimeSegmentSQLGeneratorTest extends FunSpec with Matchers { 7 | describe("genTimeSegmentsSQL") { 8 | it("should generate sql for time segment parameter") { 9 | val timeSegmentSQLGenerator = new TimeSegmentSQLGenerator {} 10 | val sql = timeSegmentSQLGenerator.genTimeSegmentsSQL(List(TimeSegment("2014-03-04", "2014-04-05"))) 11 | sql shouldBe SQLPart("(timeSegments < '2014-04-05' AND timeSegments > '2014-03-04')") 12 | } 13 | it("should generator OR expression for multiple time segments") { 14 | val timeSegmentSQLGenerator = new TimeSegmentSQLGenerator {} 15 | val sql = timeSegmentSQLGenerator.genTimeSegmentsSQL( 16 | List( 17 | TimeSegment("2014-03-04", "2014-04-05"), 18 | TimeSegment("2012-05-06", "2013-01-01") 19 | ) 20 | ) 21 | sql shouldBe SQLPart("(timeSegments < '2014-04-05' AND timeSegments > '2014-03-04') OR" + 22 | " (timeSegments < '2013-01-01' AND timeSegments > '2012-05-06')") 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/scala/state/RNGTest.scala: -------------------------------------------------------------------------------- 1 | //package state 2 | // 3 | //import org.scalatest.{ShouldMatchers, FunSpec} 4 | // 5 | //class RNGTest extends FunSpec with ShouldMatchers { 6 | // describe("RNG"){ 7 | // it("should generate list of ints"){ 8 | // val ints: (List[Int], RNG) = RNG.ints(4)(RNG.simple(1000)) 9 | // ints._1.size shouldBe 4 10 | // ints._1.foreach(println) 11 | // } 12 | // 13 | // it("can generate int up to max parameter") { 14 | // val (i,_) = RNG.positiveMax(5)(RNG.simple(600)) 15 | // i should be <= 5 16 | // } 17 | // } 18 | //} 19 | -------------------------------------------------------------------------------- /src/test/scala/stats/pregnent/PregnancyAnalyzeSpec.scala: -------------------------------------------------------------------------------- 1 | package stats.pregnent 2 | 3 | import org.scalatest.{FunSpec, Matchers} 4 | import PregnancyAnalyze._ 5 | 6 | class PregnancyAnalyzeSpec extends FunSpec with Matchers { 7 | describe("PregnancyAnalyze"){ 8 | it("can extract Pregnancy instance from string presentation"){ 9 | val s = " 1 1 6 1 11093 1084 9 039 9 0 1 813 1093 13837 1 5 116610931166 9201093 111 3 1 12 11 5391 110933316108432411211 2995 1212 69544441116122222 2 2224693215 000000000000000000000000000000000000003410.38939935294273869.3496019830486 6448.2711117047512 91231" 10 | val p = extract(s) 11 | p.caseId shouldBe 1 12 | p.prgLength shouldBe 39 13 | p.outcome shouldBe 1 14 | p.birthOrd shouldBe 1 15 | p.finalWgt shouldBe 6448.271F 16 | } 17 | it("if birth order string is empty, result should be -1"){ 18 | val s = " 1 1 6 1 11093 1084 9 039 9 0 1 813 1093 13837 1 5 116610931166 9201093 111 3 1 12 11 5391 10933316108432411211 2995 1212 69544441116122222 2 2224693215 000000000000000000000000000000000000003410.38939935294273869.3496019830486 6448.2711117047512 91231" 19 | val p = extract(s) 20 | p.birthOrd shouldBe -1 21 | } 22 | it("can calculate times of live birth"){ 23 | liveBirthCount(List( 24 | Pregnancy(1,1,outcome = 1,1,1), 25 | Pregnancy(1,1,outcome = 0,1,1) 26 | )) shouldBe 1 27 | } 28 | it("can split live birth records to first birth group and others"){ 29 | val pregnancies = List( 30 | Pregnancy(1,1,outcome = 1,birthOrd = 1,1), 31 | Pregnancy(2,1,outcome = 1,birthOrd = 2,1), 32 | Pregnancy(3,1,outcome = 1,birthOrd = 1,1), 33 | Pregnancy(3,1,outcome = 1,birthOrd = 3,1), 34 | Pregnancy(3,1,outcome = 1,birthOrd = 4,1), 35 | Pregnancy(4,1,outcome = 0,1,1) 36 | ) 37 | val (firstLives, others) = liveBirthGroupByBirthOrder(pregnancies) 38 | firstLives should have size 2 39 | others should have size 3 40 | } 41 | it("can calculate avg pregLength"){ 42 | val pregnancies = List( 43 | Pregnancy(1,prgLength = 30,1,1,1), 44 | Pregnancy(2,prgLength = 40,1,2,1) 45 | ) 46 | avgPrgLength(pregnancies) shouldBe 35f 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/scala/tags/Tags.scala: -------------------------------------------------------------------------------- 1 | package tags 2 | 3 | import org.scalatest.Tag 4 | 5 | object Tags { 6 | object DbTest extends Tag("DbTest") 7 | object FastTest extends Tag("FastTest") 8 | object FunctionTest extends Tag("FunctionTest") 9 | object IntegrationTest extends Tag("IntegrationTest") 10 | } 11 | -------------------------------------------------------------------------------- /src/test/scala/utils/CombinatorsSpec.scala: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import java.io._ 4 | 5 | import org.scalatest.{BeforeAndAfter, FunSpec, Matchers} 6 | import patterns.{Path, ReadSupport} 7 | import utils.Combinator._ 8 | 9 | class CombinatorsSpec extends FunSpec with Matchers with BeforeAndAfter with ReadSupport { 10 | val input = "src/test/resources/doOverSample.txt" 11 | val output = "tmp/doOverSampleOut.txt" 12 | 13 | before{ 14 | val file = new File(output) 15 | if(file.exists()) file.delete() 16 | } 17 | 18 | describe("doOver combinator"){ 19 | it("can combine input func, outputFunc and a process func"){ 20 | doOver(input,output)(_.toUpperCase) 21 | read(Path(output)) shouldBe "HELLO\nWORLD" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/scala/webtest/BaiduSpec.scala: -------------------------------------------------------------------------------- 1 | //package webtest 2 | // 3 | //import org.openqa.selenium.chrome.ChromeDriver 4 | //import org.scalatest.time.{Millis, Seconds, Span} 5 | //import org.scalatest.{FunSpec, ShouldMatchers} 6 | //import org.scalatest.concurrent.Eventually 7 | //import org.scalatest.selenium.Chrome 8 | // 9 | //class BaiduSpec extends FunSpec with Chrome with Eventually with ShouldMatchers{ 10 | // 11 | // System.setProperty("webdriver.chrome.driver", "/Users/twer/dev/chromedriver") 12 | // override implicit val webDriver = new ChromeDriver() 13 | // 14 | // implicit override val patienceConfig = 15 | // PatienceConfig(timeout = scaled(Span(5, Seconds)), interval = scaled(Span(100, Millis))) 16 | // 17 | // describe("baidu"){ 18 | // it("should be able to search google") { 19 | // go to "http://baidu.com" 20 | // click on "kw" 21 | // textField("kw").value = "google" 22 | // submit() 23 | // eventually { 24 | // pageTitle should be("google_百度搜索") 25 | // } 26 | //// close() 27 | // } 28 | // } 29 | //} 30 | -------------------------------------------------------------------------------- /src/test/script/SQLGen.scala: -------------------------------------------------------------------------------- 1 | import scripting.Service 2 | 3 | class SQLGen extends Service { 4 | override def execute(arg1: String, arg2: String, dbConn: String, tableName: String): String = { 5 | s"test yyy SELECT * FROM $tableName WHERE arg1='$arg1' AND arg2='$arg2'" 6 | } 7 | } 8 | --------------------------------------------------------------------------------