SlideShare a Scribd company logo
1 of 36
Download to read offline
Nitrite
Choosing the “rite” embedded database
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Enthusiast for all things JVM
● Tech Lead @ Correl8
WHOAMI
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Best Jafar Purim custom award winner for 2019
WHAT DO I
WANT
FROM YOU
● Talk about embedded databases and their proper
use-cases
● Demonstrate why we chose Nitrite and how it
help us accomplish our goals
● Survey various aspects and features Nitrite has to
offer
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
WHY
SHOULD
YOU CARE ● Nitrite might prove useful in solving similar
problems you might come across in your
backend/mobile application
● In the long run, it can also help you maintain a
cleaner code-base and evolve your data-model
more easily
● Besides, you’re already here … ;-)
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Embedded Databases
When are they called for?
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Performance
Scalability
/ Simplicity
Flexible Data
Model / Queries
Technological
Diversity
Embedded
Databases !
O ine data
Remote Database Local Storage
TO SUM
THINGS UP ● We’d all rather manage our data somewhere
outside of the application.
● For backend applications requiring
sub-millisecond latency for data operations,
that’s usually not an option
● For mobile applications, it can set the difference
between a sluggish app and a responsive one
○ User-data plans are also a consideration
🐈 And don’t forget that offline-data cat...
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Stock market data, in nature, is
both stateful and mutable
Stock order-books and issued
buy/sell orders are both good
examples. Algorithmic trading
applications are required to
accumulate stock market data
and analyze all of it in realtime.
We’re building an algorithmic trading artificial intelligence meant to
operate in the Israeli stock exchange (in Kotlin, nonetheless).
OUR USE CASE
Application latency measurements
are taken in microseconds
Data access variations are numerous,
even for homogeneous datums
There are many companies out
there listening for the same set of
events, competing amongst
themselves (and with us) on who
reacts and seizes opportunities
fastest.
Each issued order has its own life-cycle:
it transitions between various states,
receiving only a partial subset of the
class fields on each transition.
Business-wise, we need to able to query
orders using a varying set of
parameters, such as stock id, order
state, broker, and so on
⇨ ⇨ ⇨
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Initialization
{
"orderId":"order-1",
"stockId":"TEVA-IL",
"specification":{
"price":100.0,
"quantity":100
},
"orderState":"REQUESTED_ADDITION",
"transmissionState":"INITIAL"
...
}
Order data transitions
OUR USE CASE
SDK Confirmation
{
"orderId":"order-1",
???
???
???
???
???
"brokerOrderState": "Accepted"
"orderState":"REQUESTED_ADDITION",
"transmissionState":"LOCAL"
...
}
Broker Confirmation
{
"orderId":"order-1",
"stockId":"TEVA-IL",
"specification":{
"price":100.0,
"quantity":100
},
"brokerOrderId": "b-o-1"
"brokerOrderState": "Registered"
"orderState":"REQUESTED_ADDITION",
"transmissionState":"BROKER"
...
}
Exchange Confirmation
{
"orderId":"order-1",
"stockId":"TEVA-IL",
"specification":{
"price":100.0,
"qunatity":100
},
"exchangeOrderId": "e-o-1"
"brokerOrderId": "b-o-1"
"brokerOrderState": "Approved"
"orderState":"ADDED",
"transmissionState":"EXCHANGE"
...
}
⇨ ⇨ ⇨
{
"orderId":"order-1",
"stockId":"TEVA-IL",
"specification":{
"price":100.0,
"quantity":100
},
"orderState":"REQUESTED_ADDITION",
"transmissionState":"INITIAL"
...
}
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Order data repository excerpt
OUR USE CASE
interface OrderDataRepository {
fun get(orderId: String): OrderData?
fun get(orderIds: Set<String>): Set<OrderData>
fun getStockOrders(stockId: String, orderStates: Array<OrderState> = ORDER_STATES):Set<OrderData>
fun update(orderId: String, fields: Map<KProperty<*>, Any>)
fun insert(orderData: OrderData)
}
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Our greatest concern - Evolving the data layer
OUR USE CASE
● Surly, we could just implement that repository naively using several
mutableMapOf<K,OrderData>() where K varies based on filter (string, number, etc)
😨 But what happens when we’ll need to query on additional fields?
○ Maintaining a growing number of maps can be cumbersome and error prone
○ Equality is OK, but comparison (greater than, less than) is harder
○ Composite filters (on multiple fields) does not always fit easily into map keys
○ No updates for partial data
😿 We’ll wind up making a poor-man’s database, and a bad one at best
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Technical Considerations
What we care about
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
IT NEEDS
TO BE
FAST AND
FLEXIBLE
● Each library incorporated in our application is
measured in microseconds/operation
● Expected data-set size is 10K-100K objects
● Support “rich” queries - matching on different
fields, multiple fields, array fields, nested fields
and so forth without compromising on speed
(This implies secondary indexing)
● Support partial-updates (to avoid the overhead
of read-modify-writes)
● Memory only (volatile) storage
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
IT NEEDS
TO BE DEAD
SIMPLE
● Short setup times and minimal code to have a
fully working repository/DAO implementation
● No additional query language to learn
● Directly working with objects/classes is always
preferable (including support for nested classes)
● Minimal changes to existing codebase
● All of the above imply minimal vendor lock-in
which is also a crucial consideration
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
IT NEEDS
TO BE
FREE
● Don’t forget about proper software licensing
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● We’re a 6 people (3 employee) startup
Nitrite - Technical Overview
A class is worth a thousand words (or something)
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
DOES NITRITE
MAKE A
GOOD FIT?
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Well, it’s FREE, that’s for sure :)
○ Apache 2.0 is a very permissive license
● As for SIMPLICITY In the next couple of slides ,
we’ll see how very few lines of code are required
to setup a running Nitrite instance.
● We’ll also observe how well Kotlin’s data class plays
with Nitrite, almost as if it was a part of the
standard library
● And of course - FLEXIBLE queries and indexing
● And some other neat features...
UNDER
THE HOOD
● Nitrite is built on top of MVStore (Known for
powering Java H2 embedded database)
● Objects are stored as Documents
○ Can be written/read directly to a collection,
or de/serialized as pure Kotlin class
instances.
● Both indices and documents are stored inside
MVMap maps, which are B+/-Tree,
multi-versioned maps
○ This makes them optimal for all CRUD
operations/queries, while providing good
filesystem I/O performance
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
}
MINIMAL
SETUP
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
data class MyData(@Id val id:String,val number:Int,val flag:Boolean)
fun all(): List<MyData> = repository
.find(ObjectFilters.ALL)
.toList()
fun insert(data:MyData) {
repository.insert(data)
}
fun get(id: String): MyData? = repository
.find(MyData::id eq id)
.let { cursor -> runCatching { cursor.first() } }
.getOrNull()
code sample
INDICES ● Indices can be defined to speed up queries
filtering on fields other than the primary key
(annotated with @Id)
● A field can be indexed as long as:
○ It’s a scalar (doesn’t implement Collection<*>)
○ It’s sortable (implements Comprable<*>)
○ It doesn’t already have an index defined on it
● Composite indices are not supported
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
data class MyData(@Id val id:String,val number:Int,val flag:Boolean)
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
fun insert(data:MyData) {
repository.insert(data)
}
}
SIMPLE
INDICES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
init {
repository.createIndex("number",IndexOptions.indexOptions(IndexType.NonUnique))
}
fun greaterThan(number: Int): List<MyData> = repository
.find(MyData::number gt number)
.let { kotlin.runCatching { it.toList()} }
.getOrElse { emptyList() }
code sample
data class MyData(@Id val id:String,val flag:Boolean, val nested:MyNestedData )
data class MyNestedData(val criteria:Int)
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
fun insert(vararg data:MyData) {
repository.insert(data)
}
}
MULTIPLE
INDICES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
init {
repository.createIndex("flag",indexOptions(IndexType.NonUnique))
repository.createIndex("nested.criteria",indexOptions(IndexType.NonUnique))
}
fun on(number: Int, flag: Boolean): List<MyData> {
val filter = ObjectFilters.eq("nested.criteria", 0) or
(ObjectFilters.gt("nested.criteria", number) and (MyData::flag eq flag))
return repository.find(filter).let { kotlin.runCatching { it.toList() } }
.getOrElse { emptyList() }
}
code sample
data class MyData(@Id val id:String,val number:Int,val flag:Boolean)
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
fun upsert(data:MyData) {
repository.update(data,true)
}
}
FULL
UPDATES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
PARTIAL
UPDATES
● Full updates effectually replace elements in the
database with new ones
● Sometimes we don’t have all of the element data
fields required to generate a full update
● If your kotlin data class contains nonnull val fields
you don’t have, you’re stuck
● One solution would be doing a
read-modify-write: read the old instance from the
database, modify it, and write it again
● But that might prove to be too costly,
performance wise...
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
data class MyData(@Id val id:String,val number:Int,val flag:Boolean)
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
}
PARTIAL
UPDATES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
fun update(id: String, fields: Map<KProperty1<MyData,*>, Any>) {
val document = emptyDocument()
fields.forEach { (field, value) -> document[field.name] = value }
document[MyData::id.name] = id
val options = UpdateOptions.updateOptions(true)
collection.update(MyData::id.name eq id, document,options)
}
…
MyDataRepository.update("id-1", mapOf(MyData::flag,true))
private val collection = repository.documentCollection
code sample
PROJECTED
TYPES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● While stored documents are of type A, sometimes
we need to represent queried data as a sub-type B
where B out A
● Or a completely different type C
● We can always write code to do this manually
outside the scope of the query (copy fields from
queried object A to object B)
● Luckily for us, Nitrite provide a solution OOTB
(without garbage/performance overhead)
data class MyData(@Id val id:String,val number:Int?,val flag:Boolean)
object MyDataRepository {
private val nitrite = Nitrite.builder().openOrCreate()
private val repository = nitrite.getRepository(MyData::class.java)
}
PROJECTED
TYPES
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
fun <P> get(id: String, target:Class<P>):P = repository
.find(MyData::id eq id)
.project(target)
.let { kotlin.runCatching { it.firstOrDefault() } }
.getOrNull()
...
MyDataRepository.get("id-1”,ProjectedData::class.java)
data class ProjectedData(val id:String,val number:Int)
code sample
Indexed field query, 10000 items, index dispersion of 100, us per op
HOW FAST IS IT?
SQLite (File-Storage)
SQLite (In-Memory)
Nitrite (File Storage)
Nitrite (In-Memory)
Nitrite (In-Memory, Optimized Mapper)
(Benchmarks are implemented using JMH, and yes - they are credible)
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Benchmark notes
HOW FAST IS IT?
● The same class (a simple POJO) is used for all of the benchmarks
● SQLite is accessed via JDBC, queries are done using prepared statements.
● Index dispersion indicates value range for the indexed field. The higher that number,
the smaller amounts entities having the same field value we’ll have
● Each measured operation includes only query and result deserialization. Data
generation and insertion take place during the benchmark setup.
● The winner is the In-Memory Nitrite with manual deserialization (matching JDBC
serialization setup). The other Nitrite candidate simply deserialize documents using
Jackson (shorter setup times).
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Indexed field query, 50000 items, index dispersion of 2000, us per op
HOW FAST IS IT?
SQLite (File-Storage)
SQLite (In-Memory)
Nitrite (File Storage)
Nitrite (In-Memory)
Nitrite (In-Memory, Optimized Mapper)
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Additional Benchmark notes
HOW FAST IS IT?
● While the tested data-set is larger for the 2nd benchmark (50000 vs 10000), we can see
that query operation durations are much shorter (~60us vs ~200us)
● The reason for that is the fact that the dispersion for the indexed field value is also
greater (2000 vs 100). that means each query returns less results.
● That gives us a strong indication that the heaviest part in working with these
embedded database (at least for simple indexed queries) is actually object
de/serialization
● Benchmark code is available in here
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Nitrite - Advanced Features
Let’s squeeze that lemon to the end
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Nitrite provides us with the ability to register
callbacks on all document related events taking
place in a collection/repository
● What is it good for?
● One good example could be rolling your own
document expiration/TTL:
○ Add a listener that on document insertion,
schedules a task to remove that same
document from the repository at a later time
○ Fully supporting TTLs is in fact, a much more
complicated task, so tread lightly
EVENT
LISTENERS
ADVANCED
SERIALIZATION
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Nitrite uses Jackson to serialize documents into
objects and vice versa
● Jackson gives us decent performance. However,
we can achieve even better de/serialization
latancies by creating manual serialization code
● While this approach extends the setup time, it
can really speed up database access times for
both read and write operations.
● You can find additional information here and
here
● I eventually came up with my own technique
REMOTE
REPLICATION
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
● Nitrite also provides us with a solution for remote
data replication called DataGate
● Built on top of MongoDB, this add-on allows us to
synchronize events across multiple client
applications (that has Nitrite instances, of course)
○ Replication is selective (on a collection basis)
○ There’s also a neat administrative portal
● Ideal for mobile application remote sync?
○ As of late 2019, not really sure about
scalability/maturity, so test prudently
That’s all folks
Questions?
Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019

More Related Content

Recently uploaded

AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 

Recently uploaded (20)

AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 

Featured

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationErica Santiago
 

Featured (20)

PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy Presentation
 

Nitrite - Choosing the "Rite" Embedded Database

  • 1. Nitrite Choosing the “rite” embedded database Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 2. ● Enthusiast for all things JVM ● Tech Lead @ Correl8 WHOAMI Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● Best Jafar Purim custom award winner for 2019
  • 3. WHAT DO I WANT FROM YOU ● Talk about embedded databases and their proper use-cases ● Demonstrate why we chose Nitrite and how it help us accomplish our goals ● Survey various aspects and features Nitrite has to offer Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 4. WHY SHOULD YOU CARE ● Nitrite might prove useful in solving similar problems you might come across in your backend/mobile application ● In the long run, it can also help you maintain a cleaner code-base and evolve your data-model more easily ● Besides, you’re already here … ;-) Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 5. Embedded Databases When are they called for? Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 6. Performance Scalability / Simplicity Flexible Data Model / Queries Technological Diversity Embedded Databases ! O ine data Remote Database Local Storage
  • 7. TO SUM THINGS UP ● We’d all rather manage our data somewhere outside of the application. ● For backend applications requiring sub-millisecond latency for data operations, that’s usually not an option ● For mobile applications, it can set the difference between a sluggish app and a responsive one ○ User-data plans are also a consideration 🐈 And don’t forget that offline-data cat... Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 8. Stock market data, in nature, is both stateful and mutable Stock order-books and issued buy/sell orders are both good examples. Algorithmic trading applications are required to accumulate stock market data and analyze all of it in realtime. We’re building an algorithmic trading artificial intelligence meant to operate in the Israeli stock exchange (in Kotlin, nonetheless). OUR USE CASE Application latency measurements are taken in microseconds Data access variations are numerous, even for homogeneous datums There are many companies out there listening for the same set of events, competing amongst themselves (and with us) on who reacts and seizes opportunities fastest. Each issued order has its own life-cycle: it transitions between various states, receiving only a partial subset of the class fields on each transition. Business-wise, we need to able to query orders using a varying set of parameters, such as stock id, order state, broker, and so on ⇨ ⇨ ⇨ Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 9. Initialization { "orderId":"order-1", "stockId":"TEVA-IL", "specification":{ "price":100.0, "quantity":100 }, "orderState":"REQUESTED_ADDITION", "transmissionState":"INITIAL" ... } Order data transitions OUR USE CASE SDK Confirmation { "orderId":"order-1", ??? ??? ??? ??? ??? "brokerOrderState": "Accepted" "orderState":"REQUESTED_ADDITION", "transmissionState":"LOCAL" ... } Broker Confirmation { "orderId":"order-1", "stockId":"TEVA-IL", "specification":{ "price":100.0, "quantity":100 }, "brokerOrderId": "b-o-1" "brokerOrderState": "Registered" "orderState":"REQUESTED_ADDITION", "transmissionState":"BROKER" ... } Exchange Confirmation { "orderId":"order-1", "stockId":"TEVA-IL", "specification":{ "price":100.0, "qunatity":100 }, "exchangeOrderId": "e-o-1" "brokerOrderId": "b-o-1" "brokerOrderState": "Approved" "orderState":"ADDED", "transmissionState":"EXCHANGE" ... } ⇨ ⇨ ⇨ { "orderId":"order-1", "stockId":"TEVA-IL", "specification":{ "price":100.0, "quantity":100 }, "orderState":"REQUESTED_ADDITION", "transmissionState":"INITIAL" ... } Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 10. Order data repository excerpt OUR USE CASE interface OrderDataRepository { fun get(orderId: String): OrderData? fun get(orderIds: Set<String>): Set<OrderData> fun getStockOrders(stockId: String, orderStates: Array<OrderState> = ORDER_STATES):Set<OrderData> fun update(orderId: String, fields: Map<KProperty<*>, Any>) fun insert(orderData: OrderData) } Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 11. Our greatest concern - Evolving the data layer OUR USE CASE ● Surly, we could just implement that repository naively using several mutableMapOf<K,OrderData>() where K varies based on filter (string, number, etc) 😨 But what happens when we’ll need to query on additional fields? ○ Maintaining a growing number of maps can be cumbersome and error prone ○ Equality is OK, but comparison (greater than, less than) is harder ○ Composite filters (on multiple fields) does not always fit easily into map keys ○ No updates for partial data 😿 We’ll wind up making a poor-man’s database, and a bad one at best Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 12. Technical Considerations What we care about Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 13. IT NEEDS TO BE FAST AND FLEXIBLE ● Each library incorporated in our application is measured in microseconds/operation ● Expected data-set size is 10K-100K objects ● Support “rich” queries - matching on different fields, multiple fields, array fields, nested fields and so forth without compromising on speed (This implies secondary indexing) ● Support partial-updates (to avoid the overhead of read-modify-writes) ● Memory only (volatile) storage Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 14. IT NEEDS TO BE DEAD SIMPLE ● Short setup times and minimal code to have a fully working repository/DAO implementation ● No additional query language to learn ● Directly working with objects/classes is always preferable (including support for nested classes) ● Minimal changes to existing codebase ● All of the above imply minimal vendor lock-in which is also a crucial consideration Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 15. IT NEEDS TO BE FREE ● Don’t forget about proper software licensing Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● We’re a 6 people (3 employee) startup
  • 16. Nitrite - Technical Overview A class is worth a thousand words (or something) Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 17. DOES NITRITE MAKE A GOOD FIT? Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● Well, it’s FREE, that’s for sure :) ○ Apache 2.0 is a very permissive license ● As for SIMPLICITY In the next couple of slides , we’ll see how very few lines of code are required to setup a running Nitrite instance. ● We’ll also observe how well Kotlin’s data class plays with Nitrite, almost as if it was a part of the standard library ● And of course - FLEXIBLE queries and indexing ● And some other neat features...
  • 18. UNDER THE HOOD ● Nitrite is built on top of MVStore (Known for powering Java H2 embedded database) ● Objects are stored as Documents ○ Can be written/read directly to a collection, or de/serialized as pure Kotlin class instances. ● Both indices and documents are stored inside MVMap maps, which are B+/-Tree, multi-versioned maps ○ This makes them optimal for all CRUD operations/queries, while providing good filesystem I/O performance Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 19. object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) } MINIMAL SETUP Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 data class MyData(@Id val id:String,val number:Int,val flag:Boolean) fun all(): List<MyData> = repository .find(ObjectFilters.ALL) .toList() fun insert(data:MyData) { repository.insert(data) } fun get(id: String): MyData? = repository .find(MyData::id eq id) .let { cursor -> runCatching { cursor.first() } } .getOrNull() code sample
  • 20. INDICES ● Indices can be defined to speed up queries filtering on fields other than the primary key (annotated with @Id) ● A field can be indexed as long as: ○ It’s a scalar (doesn’t implement Collection<*>) ○ It’s sortable (implements Comprable<*>) ○ It doesn’t already have an index defined on it ● Composite indices are not supported Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 21. data class MyData(@Id val id:String,val number:Int,val flag:Boolean) object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) fun insert(data:MyData) { repository.insert(data) } } SIMPLE INDICES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 init { repository.createIndex("number",IndexOptions.indexOptions(IndexType.NonUnique)) } fun greaterThan(number: Int): List<MyData> = repository .find(MyData::number gt number) .let { kotlin.runCatching { it.toList()} } .getOrElse { emptyList() } code sample
  • 22. data class MyData(@Id val id:String,val flag:Boolean, val nested:MyNestedData ) data class MyNestedData(val criteria:Int) object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) fun insert(vararg data:MyData) { repository.insert(data) } } MULTIPLE INDICES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 init { repository.createIndex("flag",indexOptions(IndexType.NonUnique)) repository.createIndex("nested.criteria",indexOptions(IndexType.NonUnique)) } fun on(number: Int, flag: Boolean): List<MyData> { val filter = ObjectFilters.eq("nested.criteria", 0) or (ObjectFilters.gt("nested.criteria", number) and (MyData::flag eq flag)) return repository.find(filter).let { kotlin.runCatching { it.toList() } } .getOrElse { emptyList() } } code sample
  • 23. data class MyData(@Id val id:String,val number:Int,val flag:Boolean) object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) fun upsert(data:MyData) { repository.update(data,true) } } FULL UPDATES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 24. PARTIAL UPDATES ● Full updates effectually replace elements in the database with new ones ● Sometimes we don’t have all of the element data fields required to generate a full update ● If your kotlin data class contains nonnull val fields you don’t have, you’re stuck ● One solution would be doing a read-modify-write: read the old instance from the database, modify it, and write it again ● But that might prove to be too costly, performance wise... Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 25. data class MyData(@Id val id:String,val number:Int,val flag:Boolean) object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) } PARTIAL UPDATES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 fun update(id: String, fields: Map<KProperty1<MyData,*>, Any>) { val document = emptyDocument() fields.forEach { (field, value) -> document[field.name] = value } document[MyData::id.name] = id val options = UpdateOptions.updateOptions(true) collection.update(MyData::id.name eq id, document,options) } … MyDataRepository.update("id-1", mapOf(MyData::flag,true)) private val collection = repository.documentCollection code sample
  • 26. PROJECTED TYPES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● While stored documents are of type A, sometimes we need to represent queried data as a sub-type B where B out A ● Or a completely different type C ● We can always write code to do this manually outside the scope of the query (copy fields from queried object A to object B) ● Luckily for us, Nitrite provide a solution OOTB (without garbage/performance overhead)
  • 27. data class MyData(@Id val id:String,val number:Int?,val flag:Boolean) object MyDataRepository { private val nitrite = Nitrite.builder().openOrCreate() private val repository = nitrite.getRepository(MyData::class.java) } PROJECTED TYPES Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 fun <P> get(id: String, target:Class<P>):P = repository .find(MyData::id eq id) .project(target) .let { kotlin.runCatching { it.firstOrDefault() } } .getOrNull() ... MyDataRepository.get("id-1”,ProjectedData::class.java) data class ProjectedData(val id:String,val number:Int) code sample
  • 28. Indexed field query, 10000 items, index dispersion of 100, us per op HOW FAST IS IT? SQLite (File-Storage) SQLite (In-Memory) Nitrite (File Storage) Nitrite (In-Memory) Nitrite (In-Memory, Optimized Mapper) (Benchmarks are implemented using JMH, and yes - they are credible) Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 29. Benchmark notes HOW FAST IS IT? ● The same class (a simple POJO) is used for all of the benchmarks ● SQLite is accessed via JDBC, queries are done using prepared statements. ● Index dispersion indicates value range for the indexed field. The higher that number, the smaller amounts entities having the same field value we’ll have ● Each measured operation includes only query and result deserialization. Data generation and insertion take place during the benchmark setup. ● The winner is the In-Memory Nitrite with manual deserialization (matching JDBC serialization setup). The other Nitrite candidate simply deserialize documents using Jackson (shorter setup times). Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 30. Indexed field query, 50000 items, index dispersion of 2000, us per op HOW FAST IS IT? SQLite (File-Storage) SQLite (In-Memory) Nitrite (File Storage) Nitrite (In-Memory) Nitrite (In-Memory, Optimized Mapper) Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 31. Additional Benchmark notes HOW FAST IS IT? ● While the tested data-set is larger for the 2nd benchmark (50000 vs 10000), we can see that query operation durations are much shorter (~60us vs ~200us) ● The reason for that is the fact that the dispersion for the indexed field value is also greater (2000 vs 100). that means each query returns less results. ● That gives us a strong indication that the heaviest part in working with these embedded database (at least for simple indexed queries) is actually object de/serialization ● Benchmark code is available in here Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 32. Nitrite - Advanced Features Let’s squeeze that lemon to the end Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019
  • 33. Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● Nitrite provides us with the ability to register callbacks on all document related events taking place in a collection/repository ● What is it good for? ● One good example could be rolling your own document expiration/TTL: ○ Add a listener that on document insertion, schedules a task to remove that same document from the repository at a later time ○ Fully supporting TTLs is in fact, a much more complicated task, so tread lightly EVENT LISTENERS
  • 34. ADVANCED SERIALIZATION Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● Nitrite uses Jackson to serialize documents into objects and vice versa ● Jackson gives us decent performance. However, we can achieve even better de/serialization latancies by creating manual serialization code ● While this approach extends the setup time, it can really speed up database access times for both read and write operations. ● You can find additional information here and here ● I eventually came up with my own technique
  • 35. REMOTE REPLICATION Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019 ● Nitrite also provides us with a solution for remote data replication called DataGate ● Built on top of MongoDB, this add-on allows us to synchronize events across multiple client applications (that has Nitrite instances, of course) ○ Replication is selective (on a collection basis) ○ There’s also a neat administrative portal ● Ideal for mobile application remote sync? ○ As of late 2019, not really sure about scalability/maturity, so test prudently
  • 36. That’s all folks Questions? Idan Sheinberg, Kotlin Everywhere - TLV Edition, 27/10/2019