SlideShare a Scribd company logo
1 of 84
Ohm
Object hash map   Christopher Spring
A little
background
info first...
Ohm runs on redis
Ohm runs on redis
Remote dictionary server
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Key expiry
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Key expiry
redis-rb
What is Ohm?
Ancient syllable
Ancient syllable
Aaa-ooo-mmm
Ancient syllable
Aaa-ooo-mmm
The beginning, duration and
dissolution of the universe
Ancient syllable
Aaa-ooo-mmm
The beginning, duration and
dissolution of the universe
Brahma, Vishnu & Shiva
or...
symbol = {
  :name => 'Ohm',
  :description =>   'Ancient syllable',
  :phonemes => [
    {
      :sound   =>   'aaa',
      :meaning =>   'beginning of the universe',
      :god     =>   'Brahma'
    }, {
      :sound   =>   'ooo',
      :meaning =>   'duration of the universe',
      :god     =>   'Vishnu'
    }, {
      :sound   =>   'mmm',
      :meaning =>   'dissolution of the universe',
      :god     =>   'Shiva'
    }
  ]
}
Let’s store that in
redis...
require 'redis'

db = Redis.new
# make a bunch of phonemes
# HMSET key field value [field value ...]

phos = %w(pho1 pho2 pho3)

db.hmset phos[1], 'sound', 'aaa',
                  'meaning', 'beginning',
                  'god', 'Brahma'

db.hmset phos[2], 'sound', 'ooo',
                  'meaning', 'duration',
                  'god', 'Vishnu'

db.hmset phos[3], 'sound', 'mmm',
                  'meaning', 'dissolution',
                  'god', 'Shiva'
# ... and create the symbol

db.hmset 'symbol',
         'name', 'Ohm'
         'description', 'Ancient syllable',
         'phonemes', phos.to_json
require 'redis'

db = Redis.new

phos = %w(pho1 pho2 pho3)
db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning',
'god', 'Brahma'

db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration',
'god', 'Vishnu'

db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution',
'god', 'Shiva'

db.hmset 'symbol',
  'name', 'Ohm'
  'description', 'Ancient syllable',
  'alternatives', 'alternatives',
  'phenomes', phos.to_json
Awesome?
I want lot’s of Symbols
I want lot’s of Symbols

      db.hmset 'symbol',
        'name', 'Ohm'
        'description', 'Ancient syllable',
        'alternatives', 'alternatives',
        'phenomes', phos.to_json
I want lot’s of Symbols
I want lot’s of Symbols
I want lot’s of Symbols

 Require a key strategy
I want lot’s of Symbols

 Require a key strategy
 Store the key in redis
I want lot’s of Symbols

 Require a key strategy
 Store the key in redis
 Auto-increment
# "symbol:1", "symbol:2" ... "symbol:n"
def get_symbol_pk
  pk = db.incr 'symbol:pk'
  "symbol:#{pk}"
end

# ...

db.hmset get_symbol_pk, ...
Ok, but...
I wanna find symbols by
name!
I wanna find symbols by
name!
Requires an extra index
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
We need an index key strategy
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
We need an index key strategy
...
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
Fine, but now i want...
Fine, but now i want...

 Validation
Fine, but now i want...

 Validation
 To use this in project X
Fine, but now i want...

 Validation
 To use this in project X
 To be able to find the symbol of a phoneme
Fine, but now i want...

 Validation
 To use this in project X
 To be able to find the symbol of a phoneme
 ... shoot me?
This sucks!!
 Not OO at all
 Validation?
 Referencing containing object
 What other pitfalls have we missed?
 Project/implementation specific
 ...
Let’s build our own object
mapping on top of redis!
or...
Ohm: Object hash map
symbol = {
  :name => 'Ohm',
  :description =>   'Ancient syllable',
  :phonemes => [
    {
      :sound   =>   'aaa',
      :meaning =>   'beginning of the universe',
      :god     =>   'Brahma'
    }, {
      :sound   =>   'ooo',
      :meaning =>   'duration of the universe',
      :god     =>   'Vishnu'
    }, {
      :sound   =>   'mmm',
      :meaning =>   'dissolution of the universe',
      :god     =>   'Shiva'
    }
  ]
}
require 'rubygems'
require 'ohm'

class AncientSymbol < Ohm::Model

  attribute :name
  attribute :description

  index :name

  collection :phonemes, Phoneme

  def validate
    assert_present :name
  end

end
class Phoneme < Ohm::Model

  attribute :sound
  attribute :meaning
  attribute :god

  index :sound
  index :god

  reference :ancient_symbol, AncientSymbol

  def validate
    assert_present :sound
  end

end
Ohm.connect

symbol = AncientSymbol.create

p symbol.valid? # false

p symbol.errors # [[:name, :not_present]]
error_messages = symbol.errors.present do |e|
  e.on [:name, :not_present] do
    "Symbols must have a name."
  end
end
symbol = AncientSymbol.new :name => 'Ohm'

if symbol.save
  symbol.phonemes << Phoneme.create(
      :sound   => 'aaa',
      :meaning => 'beginnging of universe',
      :god     => 'Brahma',
      :ancient_symbol => symbol )

  # ...

end
Cool, so how do find stuff?
Phoneme.all
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>


symbol.phonemes
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>


symbol.phonemes
# <Set (Phoneme): ["3", "1", "2"]>
We also get sorting...
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]




symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' )
# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]




symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' )
# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]




symbol.phonemes.sort_by( :sound, :get => :god )
# ["Shiva", "Brahma", "Vishnu"]
What else can we do?
Attribute types

 attribute
 set
 list
 counter
 reference
 collection
Available validation

 assert_present
 assert_format
 assert_numeric
 assert_unique
ohm-contrib
Boundaries

Callbacks

Timestamping

ToHash

WebValidations

NumberValidations

ExtraValidations

Typecast

Locking
Awesome?
Questions?
Links


www.christopherspring.com
http://ohm.keyvalue.org/
http://www.redis.io/

More Related Content

What's hot

Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)garux
 
F# delight
F# delightF# delight
F# delightpriort
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOPAndrzej Krzywda
 
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...David Koelle
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma IntroduçãoÍgor Bonadio
 
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]David Koelle
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...takeoutweight
 
Python basic
Python basic Python basic
Python basic sewoo lee
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 WorldDaniel Blyth
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorialkizzx2
 
CouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conferenceCouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conferenceleinweber
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on PythonDaker Fernandes
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to GroovyAnton Arhipov
 

What's hot (20)

Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)
 
F# delight
F# delightF# delight
F# delight
 
Good Code
Good CodeGood Code
Good Code
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOP
 
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
 
Clojure入門
Clojure入門Clojure入門
Clojure入門
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
 
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
 
Python basic
Python basic Python basic
Python basic
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
FPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixirFPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixir
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorial
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
 
CouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conferenceCouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conference
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on Python
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 

Similar to Ohm

Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Pamela Fox
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 
第二讲 Python基礎
第二讲 Python基礎第二讲 Python基礎
第二讲 Python基礎juzihua1102
 
第二讲 预备-Python基礎
第二讲 预备-Python基礎第二讲 预备-Python基礎
第二讲 预备-Python基礎anzhong70
 
Python tutorial
Python tutorialPython tutorial
Python tutorialRajiv Risi
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangSean Cribbs
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then Howsfarmer10
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new thingsDavid Black
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionariesMarc Gouw
 
Python tutorial
Python tutorialPython tutorial
Python tutorialnazzf
 
Python tutorial
Python tutorialPython tutorial
Python tutorialShani729
 

Similar to Ohm (20)

Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
第二讲 Python基礎
第二讲 Python基礎第二讲 Python基礎
第二讲 Python基礎
 
第二讲 预备-Python基礎
第二讲 预备-Python基礎第二讲 预备-Python基礎
第二讲 预备-Python基礎
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
 
Poetic APIs
Poetic APIsPoetic APIs
Poetic APIs
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then How
 
1 the ruby way
1   the ruby way1   the ruby way
1 the ruby way
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Strings and Symbols
Strings and SymbolsStrings and Symbols
Strings and Symbols
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionaries
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 

More from Christopher Spring

More from Christopher Spring (7)

Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
 
jRuby and TorqueBox
jRuby and TorqueBoxjRuby and TorqueBox
jRuby and TorqueBox
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
 
Ruby Concurrency and EventMachine
Ruby Concurrency and EventMachineRuby Concurrency and EventMachine
Ruby Concurrency and EventMachine
 
Redis overview for Software Architecture Forum
Redis overview for Software Architecture ForumRedis overview for Software Architecture Forum
Redis overview for Software Architecture Forum
 
Redis, Resque & Friends
Redis, Resque & FriendsRedis, Resque & Friends
Redis, Resque & Friends
 

Recently uploaded

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 

Recently uploaded (20)

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 

Ohm

  • 1. Ohm Object hash map Christopher Spring
  • 3. Ohm runs on redis
  • 4. Ohm runs on redis Remote dictionary server
  • 5. Ohm runs on redis Remote dictionary server Store multiple data-structure types
  • 6. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes
  • 7. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies
  • 8. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale
  • 9. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions
  • 10. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions Key expiry
  • 11. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions Key expiry redis-rb
  • 13.
  • 16. Ancient syllable Aaa-ooo-mmm The beginning, duration and dissolution of the universe
  • 17. Ancient syllable Aaa-ooo-mmm The beginning, duration and dissolution of the universe Brahma, Vishnu & Shiva
  • 18. or...
  • 19. symbol = { :name => 'Ohm', :description => 'Ancient syllable', :phonemes => [ { :sound => 'aaa', :meaning => 'beginning of the universe', :god => 'Brahma' }, { :sound => 'ooo', :meaning => 'duration of the universe', :god => 'Vishnu' }, { :sound => 'mmm', :meaning => 'dissolution of the universe', :god => 'Shiva' } ] }
  • 20. Let’s store that in redis...
  • 21. require 'redis' db = Redis.new
  • 22. # make a bunch of phonemes # HMSET key field value [field value ...] phos = %w(pho1 pho2 pho3) db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning', 'god', 'Brahma' db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration', 'god', 'Vishnu' db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution', 'god', 'Shiva'
  • 23. # ... and create the symbol db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'phonemes', phos.to_json
  • 24. require 'redis' db = Redis.new phos = %w(pho1 pho2 pho3) db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning', 'god', 'Brahma' db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration', 'god', 'Vishnu' db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution', 'god', 'Shiva' db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'alternatives', 'alternatives', 'phenomes', phos.to_json
  • 26. I want lot’s of Symbols
  • 27. I want lot’s of Symbols db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'alternatives', 'alternatives', 'phenomes', phos.to_json
  • 28. I want lot’s of Symbols
  • 29. I want lot’s of Symbols
  • 30. I want lot’s of Symbols Require a key strategy
  • 31. I want lot’s of Symbols Require a key strategy Store the key in redis
  • 32. I want lot’s of Symbols Require a key strategy Store the key in redis Auto-increment
  • 33. # "symbol:1", "symbol:2" ... "symbol:n" def get_symbol_pk pk = db.incr 'symbol:pk' "symbol:#{pk}" end # ... db.hmset get_symbol_pk, ...
  • 35. I wanna find symbols by name!
  • 36. I wanna find symbols by name! Requires an extra index
  • 37. I wanna find symbols by name! Requires an extra index Store index in a hash or a set
  • 38. I wanna find symbols by name! Requires an extra index Store index in a hash or a set We need an index key strategy
  • 39. I wanna find symbols by name! Requires an extra index Store index in a hash or a set We need an index key strategy ...
  • 40. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 41. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 42. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 43. Fine, but now i want...
  • 44. Fine, but now i want... Validation
  • 45. Fine, but now i want... Validation To use this in project X
  • 46. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme
  • 47. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme ... shoot me?
  • 48. This sucks!! Not OO at all Validation? Referencing containing object What other pitfalls have we missed? Project/implementation specific ...
  • 49. Let’s build our own object mapping on top of redis!
  • 50. or...
  • 52. symbol = { :name => 'Ohm', :description => 'Ancient syllable', :phonemes => [ { :sound => 'aaa', :meaning => 'beginning of the universe', :god => 'Brahma' }, { :sound => 'ooo', :meaning => 'duration of the universe', :god => 'Vishnu' }, { :sound => 'mmm', :meaning => 'dissolution of the universe', :god => 'Shiva' } ] }
  • 53. require 'rubygems' require 'ohm' class AncientSymbol < Ohm::Model attribute :name attribute :description index :name collection :phonemes, Phoneme def validate assert_present :name end end
  • 54. class Phoneme < Ohm::Model attribute :sound attribute :meaning attribute :god index :sound index :god reference :ancient_symbol, AncientSymbol def validate assert_present :sound end end
  • 55. Ohm.connect symbol = AncientSymbol.create p symbol.valid? # false p symbol.errors # [[:name, :not_present]]
  • 56. error_messages = symbol.errors.present do |e| e.on [:name, :not_present] do "Symbols must have a name." end end
  • 57. symbol = AncientSymbol.new :name => 'Ohm' if symbol.save symbol.phonemes << Phoneme.create( :sound => 'aaa', :meaning => 'beginnging of universe', :god => 'Brahma', :ancient_symbol => symbol ) # ... end
  • 58. Cool, so how do find stuff?
  • 59.
  • 61. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]>
  • 62. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo'
  • 63. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]>
  • 64. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa'
  • 65. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]>
  • 66. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1]
  • 67. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa"
  • 68. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma">
  • 69. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol
  • 70. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil>
  • 71. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil> symbol.phonemes
  • 72. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil> symbol.phonemes # <Set (Phoneme): ["3", "1", "2"]>
  • 73. We also get sorting...
  • 74.
  • 76. symbol.phonemes.sort # [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>] symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' ) # [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
  • 77. symbol.phonemes.sort # [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>] symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' ) # [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>] symbol.phonemes.sort_by( :sound, :get => :god ) # ["Shiva", "Brahma", "Vishnu"]
  • 78. What else can we do?
  • 79. Attribute types attribute set list counter reference collection
  • 80. Available validation assert_present assert_format assert_numeric assert_unique

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. We&amp;#x2019;re going to build up to why we need Ohm with an example of the pitfalls of trying to roll your own solution to interact with redis as a datastore.\n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. Get reference to database\n
  20. \n
  21. \n
  22. Awesome - we&amp;#x2019;re storing our information in redis!\nSo what&amp;#x2019;s wrong with this approach?\n
  23. \n
  24. The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  25. The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. Using a set because each element will be unique\nOrder isn&amp;#x2019;t important\n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. index: creates an index for an attribute you want to be able to search\ncollection: similar to has_many\n
  48. \n
  49. Validation behaves similarly to what we see in AR\nErrors are returned as an array of attributes and the associated failure\n
  50. Error messages are not defined within the model, but with a presenter\n\nerror_messages is just an array of errors\n
  51. Notice that the phoneme is added to the symbols phonemes\nAND a phoneme gets a reference to ancient_symbol\n
  52. \n
  53. All sets are created on the fly\n
  54. All sets are created on the fly\n
  55. All sets are created on the fly\n
  56. All sets are created on the fly\n
  57. All sets are created on the fly\n
  58. All sets are created on the fly\n
  59. All sets are created on the fly\n
  60. All sets are created on the fly\n
  61. All sets are created on the fly\n
  62. All sets are created on the fly\n
  63. All sets are created on the fly\n
  64. All sets are created on the fly\n
  65. All sets are created on the fly\n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. attribute-&gt;string set-&gt;unordered array list-&gt;array (great for queue) reference-&gt;foreign key collection-&gt;has_many\n
  72. \n
  73. Ohm contrib is a collection of drop-in modules\n
  74. \n
  75. \n
  76. \n