0
OhmObject hash map   Christopher Spring
A littlebackgroundinfo first...
Ohm runs on redis
Ohm runs on redisRemote dictionary server
Ohm runs on redisRemote dictionary serverStore multiple data-structure types
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, Hashes
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, HashesIn ...
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, HashesIn ...
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, HashesIn ...
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, HashesIn ...
Ohm runs on redisRemote dictionary serverStore multiple data-structure types  Lists, Sets, Sorted Sets, Strings, HashesIn ...
What is Ohm?
Ancient syllable
Ancient syllableAaa-ooo-mmm
Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universe
Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universeBrahma, Vishnu & Shiva
or...
symbol = {  :name => Ohm,  :description =>   Ancient syllable,  :phonemes => [    {      :sound   =>   aaa,      :meaning ...
Let’s store that inredis...
require redisdb = Redis.new
# make a bunch of phonemes# HMSET key field value [field value ...]phos = %w(pho1 pho2 pho3)db.hmset phos[1], sound, aaa, ...
# ... and create the symboldb.hmset symbol,         name, Ohm         description, Ancient syllable,         phonemes, pho...
require redisdb = Redis.newphos = %w(pho1 pho2 pho3)db.hmset phos[1], sound, aaa, meaning, beginning,god, Brahmadb.hmset p...
Awesome?
I want lot’s of Symbols
I want lot’s of Symbols      db.hmset symbol,        name, Ohm        description, Ancient syllable,        alternatives, ...
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_symbo...
Ok, but...
I wanna find symbols byname!
I wanna find symbols byname!Requires an extra index
I wanna find symbols byname!Requires an extra indexStore index in a hash or a set
I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy
I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy...
SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol...
SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol...
SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol...
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/implement...
Let’s build our own objectmapping on top of redis!
or...
Ohm: Object hash map
symbol = {  :name => Ohm,  :description =>   Ancient syllable,  :phonemes => [    {      :sound   =>   aaa,      :meaning ...
require rubygemsrequire ohmclass AncientSymbol < Ohm::Model  attribute :name  attribute :description  index :name  collect...
class Phoneme < Ohm::Model  attribute :sound  attribute :meaning  attribute :god  index :sound  index :god  reference :anc...
Ohm.connectsymbol = AncientSymbol.createp symbol.valid? # falsep symbol.errors # [[:name, :not_present]]
error_messages = symbol.errors.present do |e|  e.on [:name, :not_present] do    "Symbols must have a name."  endend
symbol = AncientSymbol.new :name => Ohmif symbol.save  symbol.phonemes << Phoneme.create(      :sound   => aaa,      :mean...
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 :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :so...
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 )# [<Ph...
symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]symbol.phonemes.sort_by( :sound, :order => ALPHA DESC )# [<Ph...
What else can we do?
Attribute types attribute set list counter reference collection
Available validation assert_present assert_format assert_numeric assert_unique
ohm-contribBoundariesCallbacksTimestampingToHashWebValidationsNumberValidationsExtraValidationsTypecastLocking
Awesome?
Questions?
Linkswww.christopherspring.comhttp://ohm.keyvalue.org/http://www.redis.io/
Ohm
Ohm
Ohm
Upcoming SlideShare
Loading in...5
×

Ohm

3,085

Published on

Interacting directly with a datastore can have many pitfalls. The presentation goes through an example which exposes some of the pitfalls, then shows how Ohm helps to solve them or make them a non issue. Some basic features of Ohm also covered.

Published in: Technology, Spiritual
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,085
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
29
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 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
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Get reference to database\n
  • \n
  • \n
  • Awesome - we&amp;#x2019;re storing our information in redis!\nSo what&amp;#x2019;s wrong with this approach?\n
  • \n
  • The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  • The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Using a set because each element will be unique\nOrder isn&amp;#x2019;t important\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • index: creates an index for an attribute you want to be able to search\ncollection: similar to has_many\n
  • \n
  • Validation behaves similarly to what we see in AR\nErrors are returned as an array of attributes and the associated failure\n
  • Error messages are not defined within the model, but with a presenter\n\nerror_messages is just an array of errors\n
  • Notice that the phoneme is added to the symbols phonemes\nAND a phoneme gets a reference to ancient_symbol\n
  • \n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • All sets are created on the fly\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • attribute-&gt;string set-&gt;unordered array list-&gt;array (great for queue) reference-&gt;foreign key collection-&gt;has_many\n
  • \n
  • Ohm contrib is a collection of drop-in modules\n
  • \n
  • \n
  • \n
  • Transcript of "Ohm"

    1. 1. OhmObject hash map Christopher Spring
    2. 2. A littlebackgroundinfo first...
    3. 3. Ohm runs on redis
    4. 4. Ohm runs on redisRemote dictionary server
    5. 5. Ohm runs on redisRemote dictionary serverStore multiple data-structure types
    6. 6. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes
    7. 7. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategies
    8. 8. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scale
    9. 9. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactions
    10. 10. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactionsKey expiry
    11. 11. Ohm runs on redisRemote dictionary serverStore multiple data-structure types Lists, Sets, Sorted Sets, Strings, HashesIn memory datastore with persistence strategiesSuper fast & easy to scaleAtomic operations & transactionsKey expiryredis-rb
    12. 12. What is Ohm?
    13. 13. Ancient syllable
    14. 14. Ancient syllableAaa-ooo-mmm
    15. 15. Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universe
    16. 16. Ancient syllableAaa-ooo-mmmThe beginning, duration anddissolution of the universeBrahma, Vishnu & Shiva
    17. 17. or...
    18. 18. 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 } ]}
    19. 19. Let’s store that inredis...
    20. 20. require redisdb = Redis.new
    21. 21. # 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, Brahmadb.hmset phos[2], sound, ooo, meaning, duration, god, Vishnudb.hmset phos[3], sound, mmm, meaning, dissolution, god, Shiva
    22. 22. # ... and create the symboldb.hmset symbol, name, Ohm description, Ancient syllable, phonemes, phos.to_json
    23. 23. require redisdb = Redis.newphos = %w(pho1 pho2 pho3)db.hmset phos[1], sound, aaa, meaning, beginning,god, Brahmadb.hmset phos[2], sound, ooo, meaning, duration,god, Vishnudb.hmset phos[3], sound, mmm, meaning, dissolution,god, Shivadb.hmset symbol, name, Ohm description, Ancient syllable, alternatives, alternatives, phenomes, phos.to_json
    24. 24. Awesome?
    25. 25. I want lot’s of Symbols
    26. 26. I want lot’s of Symbols db.hmset symbol, name, Ohm description, Ancient syllable, alternatives, alternatives, phenomes, phos.to_json
    27. 27. I want lot’s of Symbols
    28. 28. I want lot’s of Symbols
    29. 29. I want lot’s of Symbols Require a key strategy
    30. 30. I want lot’s of Symbols Require a key strategy Store the key in redis
    31. 31. I want lot’s of Symbols Require a key strategy Store the key in redis Auto-increment
    32. 32. # "symbol:1", "symbol:2" ... "symbol:n"def get_symbol_pk pk = db.incr symbol:pk "symbol:#{pk}"end# ...db.hmset get_symbol_pk, ...
    33. 33. Ok, but...
    34. 34. I wanna find symbols byname!
    35. 35. I wanna find symbols byname!Requires an extra index
    36. 36. I wanna find symbols byname!Requires an extra indexStore index in a hash or a set
    37. 37. I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy
    38. 38. I wanna find symbols byname!Requires an extra indexStore index in a hash or a setWe need an index key strategy...
    39. 39. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef 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_nameend
    40. 40. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef 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_nameend
    41. 41. SYMBOL_NAME_INDEX = symbol:index:namedef store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_keyenddef 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_nameend
    42. 42. Fine, but now i want...
    43. 43. Fine, but now i want... Validation
    44. 44. Fine, but now i want... Validation To use this in project X
    45. 45. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme
    46. 46. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme ... shoot me?
    47. 47. This sucks!! Not OO at all Validation? Referencing containing object What other pitfalls have we missed? Project/implementation specific ...
    48. 48. Let’s build our own objectmapping on top of redis!
    49. 49. or...
    50. 50. Ohm: Object hash map
    51. 51. 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 } ]}
    52. 52. require rubygemsrequire ohmclass AncientSymbol < Ohm::Model attribute :name attribute :description index :name collection :phonemes, Phoneme def validate assert_present :name endend
    53. 53. class Phoneme < Ohm::Model attribute :sound attribute :meaning attribute :god index :sound index :god reference :ancient_symbol, AncientSymbol def validate assert_present :sound endend
    54. 54. Ohm.connectsymbol = AncientSymbol.createp symbol.valid? # falsep symbol.errors # [[:name, :not_present]]
    55. 55. error_messages = symbol.errors.present do |e| e.on [:name, :not_present] do "Symbols must have a name." endend
    56. 56. symbol = AncientSymbol.new :name => Ohmif symbol.save symbol.phonemes << Phoneme.create( :sound => aaa, :meaning => beginnging of universe, :god => Brahma, :ancient_symbol => symbol ) # ...end
    57. 57. Cool, so how do find stuff?
    58. 58. Phoneme.all
    59. 59. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>
    60. 60. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo
    61. 61. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>
    62. 62. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa
    63. 63. Phoneme.all# <Set (Phoneme): ["3", "1", "2"]>Phoneme.all.except :sound => ooo# <Set (Phoneme): ["3", "1"]>Phoneme.find :sound => aaa# <Set (Phoneme): ["1"]>
    64. 64. 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]
    65. 65. 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"
    66. 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]# <Phoneme:1 ancient_symbol_id="1" sound="aaa"meaning="beginnging of universe" god="Brahma">
    67. 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"meaning="beginnging of universe" god="Brahma">pho.ancient_symbol
    68. 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">pho.ancient_symbol# <AncientSymbol:1 name="Ohm" description=nil>
    69. 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# <AncientSymbol:1 name="Ohm" description=nil>symbol.phonemes
    70. 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>symbol.phonemes# <Set (Phoneme): ["3", "1", "2"]>
    71. 71. We also get sorting...
    72. 72. symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]
    73. 73. symbol.phonemes.sort# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]symbol.phonemes.sort_by( :sound, :order => ALPHA DESC )# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
    74. 74. 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"]
    75. 75. What else can we do?
    76. 76. Attribute types attribute set list counter reference collection
    77. 77. Available validation assert_present assert_format assert_numeric assert_unique
    78. 78. ohm-contribBoundariesCallbacksTimestampingToHashWebValidationsNumberValidationsExtraValidationsTypecastLocking
    79. 79. Awesome?
    80. 80. Questions?
    81. 81. Linkswww.christopherspring.comhttp://ohm.keyvalue.org/http://www.redis.io/
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×