SlideShare a Scribd company logo
1 of 51
Download to read offline
Realm
Building a mobile database
Christian Melchior
@chrmelchior
Why a new database?
Once upon a time
Once upon a time
BCNF
Once upon a time
Once upon a time
m:n?
Once upon a time
Once upon a time
SELECT owner.name, dog.name, city.name


FROM owner

INNER JOIN dog ON owner.dog_id = dog.id

INNER JOIN city ON owner.city_id = city.id

WHERE owner.name = 'Frank'
Once upon a time
String query = "SELECT " + Owner.NAME + ", " + Dog.NAME + ", " + City.NAME


+ " FROM " + Owner.TABLE_NAME

+ " INNER JOIN " + Dog.TABLE_NAME + " ON " + Owner.DOG_ID + " = " + Dog.ID

+ " INNER JOIN " + City.TABLE_NAME + " ON " + Owner.CITY_ID + " = " + City.ID

+ " WHERE " + Owner.NAME = "'" + escape(queryName) + "'";

Once upon a time
“Lets use an ORM”
Abstract the problem away
–Joel Spolsky
“All non-trivial abstractions, to some degree,
are leaky.”
Why a new database?
• ActiveRecord
• Androrm
• Blurb
• Cupboard
• DBFlow
• DBQuery
• DBTools
• EasyliteOrm
• GreenDAO
• Ollie
• Orman
• OrmLite
• Persistence
• RushORM
• Shillelagh
• Sprinkles
• SquiDB
• SugarORM
What is Realm?
Zero-copy object store
Designed for mobile devices
Object Store
A
B C
D E F
G
VS
A
B C
D E F
G
Realm.getA().getC().getF()
Object Store references
x
z
y
x y z
SELECT table1.x, table2.y, table3.z

FROM table1

INNER JOIN table2 ON table1.table2_id = table1.id

INNER JOIN table3 ON table1.table3_id = table3.id

References in SQL
What is zero-copy?
• CursorAdapter
• FlatBuffers
public class MyCursorAdapter extends CursorAdapter {



// ...



@Override

public void bindView(View view, Context context, Cursor cursor) {

ViewHolder holder = (ViewHolder) view.getTag();

String foo = cursor.getString(cursor.getColumnIndexOrThrow("foo"));

int bar = cursor.getInt(cursor.getColumnIndexOrThrow("bar"));

holder.fooView.setText(foo);

holder.barView.setText(Integer.toString(bar));

}

}
What is zero-copy?
• CursorAdapter
• FlatBuffers
public long id() {
int o = __offset(4);
return o != 0 ? bb.getLong(o + bb_pos) : 0;
}

public String name() {
int o = __offset(6);
return o != 0 ? __string(o + bb_pos) : null;
}


ByteBuffer bb = ByteBuffer.wrap(bytes);

MyObject obj = MyObject.getRootAsMyObject(bb);

long id = obj.id();

String name = obj.name();

Zero-copy in Realm
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
	
  PersonProxy	
  {	
  
• name	
  
• age	
  
• dog	
  	
  
	
  }
	
  PersonProxy	
  {	
  
• name	
  
• age	
  
• dog	
  	
  
	
  }
	
  Person	
  {	
  
• name	
  =	
  Tommy	
  
• age	
  =	
  8	
  
• dog	
  =	
  {	
  
• name	
  =	
  Lassie	
  	
  
	
  	
  	
  }	
  
	
  }
Realm
ORM Realm
SQLite
Zero-copy in Realm
// Objects

Person javaPerson = new Person(); // Standard Java POJO


Person proxyPerson = realm.copyToRealm(javaPerson); // Convert POJO to Proxy

Person proxyPerson = realm.createObject(Person.class); // Proxy



// Query results are lazy

RealmResults<Person> queryResults = realm.allObjects(Person.class);

queryResults.get(0) != queryResults.get(0); // Different Java objects

queryResults.get(0).equals(queryResults.get(0)); // Same data

Designed for mobile
• Memory-mapped files
• C++ core
• B+ trees
• Column-oriented
• Bit-packing
• Minimize I/O overhead
• Cross-platform
• Faster reads and writes
• Queries > writes
• Smaller file size
Benchmarks
http://static.realm.io/downloads/java/android-benchmark.zip
1.09%
2.26%
3.79%
4.55%
22.85%
13.37%
1% 1% 1% 1% 1% 1%
0%
5%
10%
15%
20%
25%
BatchWrite% SimpleWrite% SimpleQuery% FullScan% Sum% Count%
Speedup&vs.&SQLite&
Tests&/&1000&objects&
Realm%
SQLite%
Implementing
Realm Android
Architecture
JNI
Realm Internal API
Realm Core
Realm Object Store API
Zero copy
public class Pojo {



private String foo;

private int bar;



public Pojo() {

}



public String getFoo() {

return foo;

}



public void setFoo(String foo) {

this.foo = foo;

}



public int getBar() {

return bar;

}



public void setBar(int bar) {

this.bar = bar;

}

}

Annotation processor


public class Pojo extends RealmObject {



private String foo;

private int bar;



public Pojo(String foo, int bar) {

this.foo = foo;

this.bar = bar;

}



public String getFoo() {

return foo;

}



public void setFoo(String foo) {

this.foo = foo;

}



public int getBar() {

return bar;

}



public void setBar(int bar) {

this.bar = bar;

}

}

@RealmClass

public abstract class RealmObject {



protected Row row;

protected Realm realm;



// ...

}
+ =
Proxy classes
public class PojoRealmProxy extends Pojo

implements RealmObjectProxy {



private static long INDEX_FOO;

private static long INDEX_BAR;



@Override

public String getFoo() {

realm.checkIfValid();

return (java.lang.String) row.getString(INDEX_FOO);

}



@Override

public void setFoo(String value) {

realm.checkIfValid();

row.setString(INDEX_FOO, (String) value);

}



@Override

public int getBar() {

realm.checkIfValid();

return (int) row.getLong(INDEX_BAR);

}



@Override

public void setBar(int value) {

realm.checkIfValid();

row.setLong(INDEX_BAR, (long) value);

}



@Override

public String toString() {

// .. 

}



@Override

public int hashCode() {

// ...

}



@Override

public boolean equals(Object o) {

// ...

}
// Static helper methods ... 

}

public class NormalObject extends RealmObject {



public String foo;

public int bar;



@Override

public String toString() {

return "[" + foo + ";" + bar + "]";

}

}



NormalObject obj = new NormalObject();

obj.foo = "DroidCon";
Standard Java objects
Byte code manipulation
• Custom Gradle plugin
• Morpheus
• JavaAssist
Compile *.java
Create proxy classes
Bytecode: Replace field
access with accessors
Succes!
Dex
public class Pojo extends RealmObject {



public String foo;

public int bar;



@Override

public String toString() {

return "[" + foo + ";" + bar + "]";

}



public String realm$$getFoo() {

return foo;

}



public void realm$$setFoo(String s) {

foo = s;

}



public int realm$$getBar() {

return bar;

}



public int realm$$setBar(int i) {

return bar = i;

}

}
Byte code manipulation
public class Pojo extends RealmObject {



public String foo;

public int bar;



@Override

public String toString() {

return "[" + realm$$getFoo() + ";" + realm$$getBar() + "]";

}



public String realm$$getFoo() {

return foo;

}



public void realm$$setFoo(String s) {

foo = s;

}



public int realm$$getBar() {

return bar;

}



public int realm$$setBar(int i) {

return bar = i;

}

}
Byte code manipulation
Pojo pojo = new Pojo();

pojo.realm$$setFoo(“DroidCon”);
Join points
Method count
• Realm: ~1750
• Model class: +2x no. of fields
• Proxy class: + 2x no. of fields + 11
• Total method count: “it depends” (~2000)
Picasso: ~600
GSON: ~950
OrmLite: ~2400
RxJava: ~3500
Support library: ~12300
What does consistency
mean?
• Database/ACID: The consistency property
ensures that any transaction will bring the
database from one valid state to another
• UI consistency: Visible data should represent one
valid state.
UI Consistency
Fragment 1
Fragment 2
Fragment 1
Fragment 2
☺ ☹
Consistency today
Fragment 1
Fragment 2
• Loader
• Content URI
• ContentObserver
• ContentProvider
Consistency today
Fragment 1
Fragment 2
ContentProvider
1
2
2
3
• Multiversion concurrency control
• Multiple read transactions
• Data is versioned
• One write transaction
R
A B
C D E
MVCC
R
A B
X D E
v1
v2
Consistency in Realm
Background threadUI thread
queue.next();

queue.next();

thread.start();

Consistency in Realm
Background threadUI thread
queue.next();

queue.next();

thread.start();

Realm realm = Realm.getDefaultInstance();
Realm realm = Realm.getDefaultInstance();
Consistency in Realm
Background threadUI thread
queue.next();

queue.next();

thread.start();

realm.close();
realm.close();
realm.executeTransaction(new Realm.Transaction() {

@Override

public void execute(Realm realm) {

//...

}

});

Consistency in Realm
Background threadUI thread
queue.next();

queue.next();

thread.start();

Consistency in Realm
Background threadUI thread
queue.next();

queue.next();

thread.start();

@OnClick

public void buttonClicked() {

Person p = realm.where(Person.class).findFirst();

int ager = p.getAge();

String name = p.getName();

}

☹
Consistency in Realm
Background threadUI thread
queue.next();
 thread.start();

new RealmChangeListener() {

@Override

public void onChange() {

//...

}

}

handler.sendEmptyMessage(REALM_CHANGED);

Consistency with Realm
Fragment 1
Fragment 2
Fragment 1
Fragment 2
new RealmChangeListener() {

@Override

public void onChange() {

invalidateViews();

}

}

Current status
• Moving towards 1.0
• Used in well more than 500M installations.
• Still need to solve hard problems: Interprocess
cursors, move objects across threads, Parcelable.
Realm today
Questions?
@chrmelchior
cm@realm.io
We are hiring
https://realm.io/jobs/

More Related Content

What's hot

Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Grails: a quick tutorial (1)
Grails: a quick tutorial (1)Grails: a quick tutorial (1)
Grails: a quick tutorial (1)Davide Rossi
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Groupkchodorow
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
Hd insight programming
Hd insight programmingHd insight programming
Hd insight programmingCasear Chu
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Rebecca Grenier
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know Norberto Leite
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement SauvageCocoaHeads France
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015StampedeCon
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryWilliam Candillon
 

What's hot (20)

Latinoware
LatinowareLatinoware
Latinoware
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
greenDAO
greenDAOgreenDAO
greenDAO
 
GORM
GORMGORM
GORM
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Grails: a quick tutorial (1)
Grails: a quick tutorial (1)Grails: a quick tutorial (1)
Grails: a quick tutorial (1)
 
Green dao
Green daoGreen dao
Green dao
 
XQuery in the Cloud
XQuery in the CloudXQuery in the Cloud
XQuery in the Cloud
 
San Francisco Java User Group
San Francisco Java User GroupSan Francisco Java User Group
San Francisco Java User Group
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
Green dao
Green daoGreen dao
Green dao
 
Cassandra 2.2 & 3.0
Cassandra 2.2 & 3.0Cassandra 2.2 & 3.0
Cassandra 2.2 & 3.0
 
Hd insight programming
Hd insight programmingHd insight programming
Hd insight programming
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
XQuery Rocks
XQuery RocksXQuery Rocks
XQuery Rocks
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQuery
 

Similar to Realm: Building a mobile database

Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 
Corinna-2023.pptx
Corinna-2023.pptxCorinna-2023.pptx
Corinna-2023.pptxCurtis Poe
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Javascript development done right
Javascript development done rightJavascript development done right
Javascript development done rightPawel Szulc
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidJordi Gerona
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Best of build 2021 - C# 10 & .NET 6
Best of build 2021 -  C# 10 & .NET 6Best of build 2021 -  C# 10 & .NET 6
Best of build 2021 - C# 10 & .NET 6Moaid Hathot
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Heiko Behrens
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitZachary Klein
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationJoni
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607Kevin Hazzard
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationIvan Dolgushin
 
Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesSimon Willison
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages VictorSzoltysek
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival GuideGiordano Scalzo
 

Similar to Realm: Building a mobile database (20)

Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Corinna-2023.pptx
Corinna-2023.pptxCorinna-2023.pptx
Corinna-2023.pptx
 
Having Fun Programming!
Having Fun Programming!Having Fun Programming!
Having Fun Programming!
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Javascript development done right
Javascript development done rightJavascript development done right
Javascript development done right
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Best of build 2021 - C# 10 & .NET 6
Best of build 2021 -  C# 10 & .NET 6Best of build 2021 -  C# 10 & .NET 6
Best of build 2021 - C# 10 & .NET 6
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to Orbit
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The Libraries
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
 

Recently uploaded

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringWSO2
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governanceWSO2
 

Recently uploaded (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 

Realm: Building a mobile database

  • 1. Realm Building a mobile database Christian Melchior @chrmelchior
  • 2. Why a new database?
  • 3. Once upon a time
  • 4. Once upon a time
  • 6. Once upon a time
  • 8. Once upon a time
  • 9. SELECT owner.name, dog.name, city.name 
 FROM owner
 INNER JOIN dog ON owner.dog_id = dog.id
 INNER JOIN city ON owner.city_id = city.id
 WHERE owner.name = 'Frank' Once upon a time
  • 10. String query = "SELECT " + Owner.NAME + ", " + Dog.NAME + ", " + City.NAME 
 + " FROM " + Owner.TABLE_NAME
 + " INNER JOIN " + Dog.TABLE_NAME + " ON " + Owner.DOG_ID + " = " + Dog.ID
 + " INNER JOIN " + City.TABLE_NAME + " ON " + Owner.CITY_ID + " = " + City.ID
 + " WHERE " + Owner.NAME = "'" + escape(queryName) + "'";
 Once upon a time
  • 11.
  • 12. “Lets use an ORM” Abstract the problem away
  • 13. –Joel Spolsky “All non-trivial abstractions, to some degree, are leaky.”
  • 14. Why a new database? • ActiveRecord • Androrm • Blurb • Cupboard • DBFlow • DBQuery • DBTools • EasyliteOrm • GreenDAO • Ollie • Orman • OrmLite • Persistence • RushORM • Shillelagh • Sprinkles • SquiDB • SugarORM
  • 16. Zero-copy object store Designed for mobile devices
  • 18. A B C D E F G Realm.getA().getC().getF() Object Store references
  • 19. x z y x y z SELECT table1.x, table2.y, table3.z
 FROM table1
 INNER JOIN table2 ON table1.table2_id = table1.id
 INNER JOIN table3 ON table1.table3_id = table3.id
 References in SQL
  • 20. What is zero-copy? • CursorAdapter • FlatBuffers public class MyCursorAdapter extends CursorAdapter {
 
 // ...
 
 @Override
 public void bindView(View view, Context context, Cursor cursor) {
 ViewHolder holder = (ViewHolder) view.getTag();
 String foo = cursor.getString(cursor.getColumnIndexOrThrow("foo"));
 int bar = cursor.getInt(cursor.getColumnIndexOrThrow("bar"));
 holder.fooView.setText(foo);
 holder.barView.setText(Integer.toString(bar));
 }
 }
  • 21. What is zero-copy? • CursorAdapter • FlatBuffers public long id() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
 public String name() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } 
 ByteBuffer bb = ByteBuffer.wrap(bytes);
 MyObject obj = MyObject.getRootAsMyObject(bb);
 long id = obj.id();
 String name = obj.name();

  • 22. Zero-copy in Realm  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    }  PersonProxy  {   • name   • age   • dog      }  PersonProxy  {   • name   • age   • dog      }  Person  {   • name  =  Tommy   • age  =  8   • dog  =  {   • name  =  Lassie          }    } Realm ORM Realm SQLite
  • 23. Zero-copy in Realm // Objects
 Person javaPerson = new Person(); // Standard Java POJO 
 Person proxyPerson = realm.copyToRealm(javaPerson); // Convert POJO to Proxy
 Person proxyPerson = realm.createObject(Person.class); // Proxy
 
 // Query results are lazy
 RealmResults<Person> queryResults = realm.allObjects(Person.class);
 queryResults.get(0) != queryResults.get(0); // Different Java objects
 queryResults.get(0).equals(queryResults.get(0)); // Same data

  • 24. Designed for mobile • Memory-mapped files • C++ core • B+ trees • Column-oriented • Bit-packing • Minimize I/O overhead • Cross-platform • Faster reads and writes • Queries > writes • Smaller file size
  • 25. Benchmarks http://static.realm.io/downloads/java/android-benchmark.zip 1.09% 2.26% 3.79% 4.55% 22.85% 13.37% 1% 1% 1% 1% 1% 1% 0% 5% 10% 15% 20% 25% BatchWrite% SimpleWrite% SimpleQuery% FullScan% Sum% Count% Speedup&vs.&SQLite& Tests&/&1000&objects& Realm% SQLite%
  • 27. Architecture JNI Realm Internal API Realm Core Realm Object Store API
  • 28. Zero copy public class Pojo {
 
 private String foo;
 private int bar;
 
 public Pojo() {
 }
 
 public String getFoo() {
 return foo;
 }
 
 public void setFoo(String foo) {
 this.foo = foo;
 }
 
 public int getBar() {
 return bar;
 }
 
 public void setBar(int bar) {
 this.bar = bar;
 }
 }

  • 29. Annotation processor 
 public class Pojo extends RealmObject {
 
 private String foo;
 private int bar;
 
 public Pojo(String foo, int bar) {
 this.foo = foo;
 this.bar = bar;
 }
 
 public String getFoo() {
 return foo;
 }
 
 public void setFoo(String foo) {
 this.foo = foo;
 }
 
 public int getBar() {
 return bar;
 }
 
 public void setBar(int bar) {
 this.bar = bar;
 }
 }
 @RealmClass
 public abstract class RealmObject {
 
 protected Row row;
 protected Realm realm;
 
 // ...
 } + =
  • 30. Proxy classes public class PojoRealmProxy extends Pojo
 implements RealmObjectProxy {
 
 private static long INDEX_FOO;
 private static long INDEX_BAR;
 
 @Override
 public String getFoo() {
 realm.checkIfValid();
 return (java.lang.String) row.getString(INDEX_FOO);
 }
 
 @Override
 public void setFoo(String value) {
 realm.checkIfValid();
 row.setString(INDEX_FOO, (String) value);
 }
 
 @Override
 public int getBar() {
 realm.checkIfValid();
 return (int) row.getLong(INDEX_BAR);
 }
 
 @Override
 public void setBar(int value) {
 realm.checkIfValid();
 row.setLong(INDEX_BAR, (long) value);
 }
 
 @Override
 public String toString() {
 // .. 
 }
 
 @Override
 public int hashCode() {
 // ...
 }
 
 @Override
 public boolean equals(Object o) {
 // ...
 } // Static helper methods ... 
 }

  • 31. public class NormalObject extends RealmObject {
 
 public String foo;
 public int bar;
 
 @Override
 public String toString() {
 return "[" + foo + ";" + bar + "]";
 }
 }
 
 NormalObject obj = new NormalObject();
 obj.foo = "DroidCon"; Standard Java objects
  • 32. Byte code manipulation • Custom Gradle plugin • Morpheus • JavaAssist Compile *.java Create proxy classes Bytecode: Replace field access with accessors Succes! Dex
  • 33. public class Pojo extends RealmObject {
 
 public String foo;
 public int bar;
 
 @Override
 public String toString() {
 return "[" + foo + ";" + bar + "]";
 }
 
 public String realm$$getFoo() {
 return foo;
 }
 
 public void realm$$setFoo(String s) {
 foo = s;
 }
 
 public int realm$$getBar() {
 return bar;
 }
 
 public int realm$$setBar(int i) {
 return bar = i;
 }
 } Byte code manipulation
  • 34. public class Pojo extends RealmObject {
 
 public String foo;
 public int bar;
 
 @Override
 public String toString() {
 return "[" + realm$$getFoo() + ";" + realm$$getBar() + "]";
 }
 
 public String realm$$getFoo() {
 return foo;
 }
 
 public void realm$$setFoo(String s) {
 foo = s;
 }
 
 public int realm$$getBar() {
 return bar;
 }
 
 public int realm$$setBar(int i) {
 return bar = i;
 }
 } Byte code manipulation Pojo pojo = new Pojo();
 pojo.realm$$setFoo(“DroidCon”); Join points
  • 35. Method count • Realm: ~1750 • Model class: +2x no. of fields • Proxy class: + 2x no. of fields + 11 • Total method count: “it depends” (~2000) Picasso: ~600 GSON: ~950 OrmLite: ~2400 RxJava: ~3500 Support library: ~12300
  • 36. What does consistency mean? • Database/ACID: The consistency property ensures that any transaction will bring the database from one valid state to another • UI consistency: Visible data should represent one valid state.
  • 37. UI Consistency Fragment 1 Fragment 2 Fragment 1 Fragment 2 ☺ ☹
  • 38. Consistency today Fragment 1 Fragment 2 • Loader • Content URI • ContentObserver • ContentProvider
  • 39. Consistency today Fragment 1 Fragment 2 ContentProvider 1 2 2 3
  • 40.
  • 41. • Multiversion concurrency control • Multiple read transactions • Data is versioned • One write transaction R A B C D E MVCC R A B X D E v1 v2
  • 42. Consistency in Realm Background threadUI thread queue.next();
 queue.next();
 thread.start();

  • 43. Consistency in Realm Background threadUI thread queue.next();
 queue.next();
 thread.start();
 Realm realm = Realm.getDefaultInstance(); Realm realm = Realm.getDefaultInstance();
  • 44. Consistency in Realm Background threadUI thread queue.next();
 queue.next();
 thread.start();
 realm.close(); realm.close();
  • 45. realm.executeTransaction(new Realm.Transaction() {
 @Override
 public void execute(Realm realm) {
 //...
 }
 });
 Consistency in Realm Background threadUI thread queue.next();
 queue.next();
 thread.start();

  • 46. Consistency in Realm Background threadUI thread queue.next();
 queue.next();
 thread.start();
 @OnClick
 public void buttonClicked() {
 Person p = realm.where(Person.class).findFirst();
 int ager = p.getAge();
 String name = p.getName();
 }
 ☹
  • 47. Consistency in Realm Background threadUI thread queue.next();
 thread.start();
 new RealmChangeListener() {
 @Override
 public void onChange() {
 //...
 }
 }
 handler.sendEmptyMessage(REALM_CHANGED);

  • 48. Consistency with Realm Fragment 1 Fragment 2 Fragment 1 Fragment 2 new RealmChangeListener() {
 @Override
 public void onChange() {
 invalidateViews();
 }
 }

  • 50. • Moving towards 1.0 • Used in well more than 500M installations. • Still need to solve hard problems: Interprocess cursors, move objects across threads, Parcelable. Realm today