├── .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 | [ ](https://codeship.io/projects/35587)
3 |
4 | [](https://gitter.im/notyy/scalaSnippet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5 |
6 | [](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 |
--------------------------------------------------------------------------------