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

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
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
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 

Recently uploaded (20)

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
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
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

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