SlideShare une entreprise Scribd logo
1  sur  51
Télécharger pour lire hors ligne
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/

Contenu connexe

Tendances

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
 

Tendances (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
 

Similaire à 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
 

Similaire à 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
 

Dernier

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
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
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
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
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
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
 
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
 

Dernier (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
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
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
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
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
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
 
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...
 

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