Object-Oriented Abstraction of Redis Sorted Set

6115584ec4554ed71f17effd3e0b6988?s=47 Altech
May 12, 2018

Object-Oriented Abstraction of Redis Sorted Set

6115584ec4554ed71f17effd3e0b6988?s=128

Altech

May 12, 2018
Tweet

Transcript

  1. 0CKFDU0SJFOUFE"CTUSBDUJPO PG3FEJT4PSUFE4FU 4PIFJ5BLFOP!3FKFDU,BJHJ

  2. "CPVUNF  !"MUFDI@  8BOUFEMZ *OD  "QQMJDBUJPO&OHJOFFS  1SPpMF%BUB4USBUFHZ(SPVQ

    4PIFJ5BLFOP
  3. ໨࣍  3FEJTʹ͍ͭͯ4PSUFE4FUͷ༻ྫ  Α͋͘Δ3FEJTͷݺͼํ3FEJTΫϥΠΞϯτΛ࢖͏  3FE#MPDLTͷ঺հΫϥεʹந৅Խ͢Δ  ·ͱΊ

  4. 3FEJTʹ͍ͭͯ 4PSUFE4FUͷ༻ྫ

  5. 3FEJTʹ͍ͭͯ  4FU )BTI౳ׂͱߴڃͳσʔλܕΛඋ͑ͨΠϯϝϞϦ,74  8FCαʔϏεͷߴ଎Խͱ͔ͰΑ͘࢖ΘΕΔ  4PSUFE4FU  3FEJT͕ఏڙ͢ΔσʔλܕͷҰͭ

     είΞ෇͖ͷཁૉͷू߹ʢείΞͰιʔτ͞Ε͍ͯΔʣ  ϥϯΩϯάʹ࢖͑Δ  ू߹ʹରͯ͠࿨ू߹΍ੵू߹ͱݴͬͨԋࢉ΋༻ҙ͞Ε͍ͯΔ  είΞ͸σϑΥϧτͰ଍͠߹Θ͞ΕΔ  ਪનɾݕࡧͳͲԿ͔Λ୳͢Ұཡը໘ͷ࣮૷ʹ΋࢖͑Δ
  6. 4PSUFE4FUͷ༻ྫ   4UBS਺Ͱιʔτ͞ΕͨϦϙδτϦ  ݴޠ͕3VCZ·ͨ͸1ZUIPOͰॻ͔ΕͨϦϙδτϦ  ࠓिͷτϨϯυʹࡌ͍ͬͯΔϦϙδτϦ  ࠓिͷτϨϯυʹࡌ͍ͬͯͯɺ͔ͭݴޠ͕3VCZ·ͨ͸1ZUIPOͰॻ͔ΕͨϦϙδτϦ

    
  ݴޠ͕3VCZͰॻ͔Ε͍ͯͯɺ͔ͭYNMΛΩʔϫʔυͱؚͯ͠ΉϦϙδτϦ [શͯͷϦϙδτϦ(Star ਺ΛείΞʹ࣋ͭ)] [ݴޠ͕ Ruby ͷϦϙδτϦ] ∪ [ݴޠ͕ Python ͷϦϙδτϦ] [ࠓिͷτϨϯυʹؚ·ΕΔϦϙδτϦ] [ࠓिͷτϨϯυʹؚ·ΕΔϦϙδτϦ] ∩ 
 ([ݴޠ͕ Ruby ͷϦϙδτϦ] ∪ [ݴޠ͕ Python ͷϦϙδτϦ]) [ݴޠ͕ Ruby ͷϦϙδτϦ] ∪ [จষதʹ “xml” ΛؚΉϦϙδτϦ(ݕࡧΤϯδϯͷධՁ஋ΛείΞʹ࣋ͭ)]
  7. ͱ͜ΖͰɿͲͷٕज़ʹدͤΔ͔໰୊  Ϛελʔσʔλతͳ΋ͷ͸%#ʹೖΕΒΕ͍ͯΔ͜ͱ͕ଟ͍
 㲈"DUJWF3FDPSE͍ͬͯ͏࠷ߴͷ03.BQQFS͕͋Δ3VCZΛ࢖͍͍ͨʁ  FHϦϙδτϦͷ࡞੒೔࣌ɺ4UBS਺  શจݕࡧΛ͍ͨ͠ͷͰݕࡧΤϯδϯ͕࢖͍͍ͨ  FHYNMΛΩʔϫʔυͱؚͯ͠Ή

     ػցֶशΛऔΓೖΕ͍ͨͷͰ1ZUIPOͰαʔόʔॻ͖͍ͨ  FHਪનΛ͍ͨ͠ͷͰॱҐ෇͚͸౎౓ܭࢉ͍ͨ͠
  8. ҰͭͷղܾҊɿ3FEJTͰ౷߹͢Δ  ߴ଎ͳ3FEJT্ͰܭࢉͰ͖Δ  Ωϟογϡػೳ΋෇ՃͰ͖Δ  DGҰཡը໘͸଎౓͕ٻΊΒΕ͕ͪ

  9. Α͋͘Δ3FEJTͷݺͼํ 3FEJTΫϥΠΞϯτΛ࢖͏

  10. ೋͭͷू߹ͷੵΛऔͬͯ݅औಘ͢Δ  3FEJTΫϥΠΞϯτΛ࢖͏ͱͻͨ͢Βखଓ͖తʹͳΔ  ؔ਺ʹ·ͱΊΔ͜ͱ͸Ͱ͖Δ͕ɺେ͖͘վળ͠ͳ͍ c = Redis.new if c.ttl(“src1”)

    < 0 c.zadd("src1", [[32.0, "a"], [64.0, “b”]]) c.expire("src1", 60) end if c.ttl(“src2”) < 0 c.zadd("src2", [[44.0, "a"], [21.0, "c"]]) c.expire("src2", 60) end c.zinterstore("dest", ["src1", "src2"]) c.expire("dest", 10) c.zrevrange("dest", 0, 5) #=> [“a"] dest = src1 ∩ src2
  11. ࢖͍·ΘͤΔΑ͏ʹΩʔΛఆٛ͢Δ  ͜͏͍͏Ωʔੜ੒ΛΑ͘΍Δʢ͏͔ͬΓΩʔ͕িಥͨ͠Γ͠ͳ͍ʁʣ  lࠓिͷτϨϯυʹࡌ͍ͬͯͯɺ͔ͭݴޠ͕3VCZ·ͨ͸1ZUIPO Ͱॻ͔ΕͨϦϙδτϦz
 <ࠓिͷτϨϯυ>㱯 <ݴޠ͕3VCZ>㱮<ݴޠ͕1ZUIPO> 
 ɾɾɾΈ͍ͨͳෳࡶͳू߹ͷΩʔ͸Ͳ͏΍ܾͬͯΊΑ͏ʁ

    def user_repository_key(user_id) "user_repositories:#{user_id}" end c.zadd( user_repository_key(user_id), get_user_repositories(user_id) )
  12. ଞʹ΋࣮ࡍʹӡ༻͢Δ্Ͱ͸৭ʑ͋Δ  ۭͷέʔε  ԋࢉதʹσʔλ͕ඈΜͩΒͲ͏͢Δʁ  ɾɾɾ

  13. ͜ΕΛ࡞Δ্ͰϑΥʔΧε͍ͨ͜͠ͱ  ֤αϒγεςϜͷग़ྗΛͲ͏૊Έ߹ΘͤΔ͔
 ʜ"/%ͳͷ͔03ͳͷ͔ɺείΞΛͲ͏૊Έ߹ΘͤΔ͔  ͦΕͧΕͷܭࢉஈ֊ʹ͓͚ΔσʔλΛͲͷఔ౓Ωϟογϡ͢Δ͔ ந৅ԽͰղܾ

  14. 3FE#MPDLTͷ঺հ Ϋϥεʹந৅Խ͢Δ

  15. HFN3FE#MPDLT  3FEJTͷ4PSUFE4FUʹؔ͢Δந৅ԽΛఏڙ  ࣮ࡍͷαʔϏεͰ࢖ΘΕ͍ͯΔ΋ͷΛ੾Γग़ͨ͠ͷͰɺ৭ʑࡉ ͔͍ศརΫϥε΋ؚ·ΕΔ  IUUQTHJUIVCDPN"MUFDISFE@CMPDLT

  16. جఈΫϥεɿ3FE#MPDLT4FU  SFRVJSFEkey_suffix, get  PQUJPOBMcache_time class RepositorySearchService::LanguageSet < RedBlocks::Set

    def initialize(language) raise ArgumentError unless Repository::LANGS.include?(language) @language = language end def key_suffix @language.to_s end def get Repository.where(language: @language).pluck(:id) end def cache_time 60.minutes end end
  17. جຊతͳ࢖͍ํ set = RepositorySearchService::LanduageSet.new(:Ruby) # ઌ಄5݅Λऔಘ set.ids #=> [341, 325,

    932, 421, 523] # 10ϖʔδ໨Λऔಘ set.ids(paginator: RedBlocks::Paginator.new(per: 10, page: 10)) # શମͷ݅਺Λऔಘ set.size #=> 2314 # Redis ͷΩʔΛ֬ೝ set.key #=> “RB:RepositorySearchService::LanguageSet:Ruby” # ໌ࣔతʹ Redis ্ͷσʔλΛ࠷৽ʹ͢Δ set.update!
  18. ΑΓৄ͘͠ʜ 3FE#MPDLT4FUHFU 3FE#MPDLT4FUJET 3FE#MPDLT4FULFZ@TV⒏Y 3FE#MPDLT4FUVQEBUF

  19. 3FE#MPDLT4FUHFUείΞͳ͠ͱείΞ͋Γ  ཁૉʢJEʣͷϦετɺ·ͨ͸ཁૉͱείΞͷϖΞͷϦετΛฦͤΔ  ཁૉͷϦετΛฦͨ͠৔߹ɺείΞ͸શͯʹͳΔ  ू߹ಉ࢜ͷԋࢉͷࡍɺείΞ͸σϑΥϧτͰ଍͞ΕΔͷͰɺͦ͸શମͷείΞʢॱংʣʹӨڹΛ༩͑ͳ͍  ॱংʹڵຯ͕ͳ͘ɺ͍ΘΏΔ਺ֶతͳҙຯͰͷू߹Λఆ͍ٛͨ͠৔߹ɺγϯϓϧʹཁૉ͚ͩΛฦͤ͹ྑ͍ def

    get Repository.where(language: @language).pluck(:id) end def get Repository.all.pluck(:id, :star_count) end ಛఆͷݴޠͷϦϙδτϦͷू߹ɿ શͯͷϦϙδτϦͷू߹ʢελʔ਺ΛείΞʹ࣋ͭʣɿ
  20. 3FE#MPDLT4FUJETۭू߹ͷදݱ  3FEJTͷ4PSUFE4FUͷ࢓༷Ͱ͸ɺ಺แ͢Δཁૉ͕݅Ͱ͋Δͱ͍͏ঢ়ଶͱɺ 4PSUFE4FUࣗମ͕ଘࡏ͠ͳ͍ͱ͍͏ঢ়ଶΛ۠ผͰ͖ͳ͍  ͔͠͠ɺʮۭͷू߹Ͱ͋Δʯͱ͍͏ঢ়ଶ΋Ωϟογϡ͍ͨ͠ʢྫ͑͹ɺಛఆͷΩʔ ϫʔυʹΑΔશจݕࡧͷ݁Ռ͕݅Ͱ͋Δͱ͍͏͜ͱࣗମΛΩϟογϡ͍ͨ͠ʣ  ࣮ࡏ͢Δཁૉ͕஋ͱͯ͠औΓಘͳ͍΋ͷʢA3FE#MPDLTDPOpHCMBOL@JEAʣΛɺ શͯͷ4PSUFE4FUʹඞؚͣΊΔΑ͏ʹ͍ͯ͠Δ

    def ids(paginator: Paginator.new) update! if disabled? RedBlocks.client.zrevrange(key, paginator.head, paginator.tail ).reject { |id| id == RedBlocks.config.blank_id } end
  21. 3FE#MPDLT4FULFZ@TV⒏YΩʔͷମܥԽ  શମͷ໊લۭؒ3FE#MPDLT͕ར༻͢ΔϕʔεͱͳΔ໊લۭؒ  ΫϥεϨϕϧͷࣝผࢠLFZ@QSFpYΫϥε໊Λࣗಈతʹ࠾༻  ΠϯελϯεϨϕϧͷࣝผࢠLFZ@TV⒏YϢʔβʔ͕ఆٛ͢Δ  ௨ৗɺΦϒδΣΫτͷଐੑΛҰҙͳจࣈྻදݱʹ͢Ε͹ྑ͍ <શମͷ໊લۭؒ>:<ΫϥεϨϕϧͷࣝผࢠ>:<ΠϯελϯεϨϕϧͷࣝผࢠ>

    set = RepositorySearchService::LanguageSet.new(:Ruby) set.key #=> “RB:RepositorySearchService::LanguageSet:Ruby”
  22. 3FE#MPDLT4FUVQEBUFσʔλͷࠩ෼ߋ৽  Ұ౓શͯΛ࡟আ͔ͯ͠Β৽͘͠σʔλΛೖΕΔͱ͍͏ํ๏ͩͱɺ σʔλ͕ͳ͘ͳͬͯ͠·͏ॠ͕ؒ͋Δ  ΞοϓσʔτલͱޙͰൺֱ͠ɺফ͑ͨཁૉͷΈΛ࡟আ͢Δ  είΞ͸શͯߋ৽͢Δ def update!

    entries = normalize_entries(validate_entries!(self.get)) removed_ids = self.ids(paginator: Paginator.all, update_if_disabled: false) - entries.map(&:last) RedBlocks.client.pipelined do RedBlocks.client.zrem(key, removed_ids) if removed_ids.size > 0 RedBlocks.client.zadd(key, all_entries) RedBlocks.client.expire(key, expiration_time) end end
  23. ू߹ԋࢉΛѻ͏ɿ 3FE#MPDLT6OJPO4FU 3FE#MPDLT*OUFSTFDUJPO4FU

  24. 3FE#MPDLT6OJPO4FU3FE#MPDLT*OUFSTFDUJPO4FU  HFU3FEJTʹ৐ͬͯͳ͍શͯͷ಺แ͢Δू߹ʹରͯ͠AVQEBUFAΛൃߦͨ͠ ޙɺA[VOJPOTUPSF EFTU TSD TSD  AͰԋࢉ݁ՌΛ֨ೲ 

    LFZ@TV⒏YΠϯελϯεϨϕϧͷࣝผࢠʹશͯͷ಺แ͢Δू߹ͷΩʔͷλϓϧ  ”[#{ruby_set.key}|#{python_set.key}]"Έ͍ͨͳΠϝʔδ set1 = RedBlocks::UnionSet.new([ruby_set, python_set]) # ܭࢉ݁ՌΛΩϟογϡ͢Δ͜ͱ΋Մೳ set1 = RedBlocks::UnionSet.new([ruby_set, python_set], cache_time: 3.minutes ) # ෳࡶͳωετ΋΋ͪΖΜՄೳ set2 = RedBlocks::IntersectionSet.new(starred_count_set, set1) ˞HFU LFZ@TV⒏Y͸ϥΠϒϥϦଆͰ࣮૷͍ͯ͠ΔͷͰɺΫϥεఆٛͳ͠Ͱར༻Մೳ
  25. 3FEJT্ͷσʔλͷੜଘظؒ

  26. 3FEJT্ͷσʔλͷੜଘظؒ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET

  27. 3FEJT্ͷσʔλͷੜଘظؒ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ " U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET

  28. 3FEJT্ͷσʔλͷੜଘظؒ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ " 1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU>

    JET
  29. 3FEJT্ͷσʔλͷੜଘظؒ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ " 1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX

    <SVCZ@TFU QZUIPO@TFU> JET
  30. 3FEJT্ͷσʔλͷੜଘظؒ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ " 1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ $͔ΒσʔλΛҾ͘ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ

    3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET
  31. 3FEJT্ͷσʔλͷੜଘظؒ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ " 1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ ྫ͑͹ɺ͜͜ʹདྷΔ·Ͱʹ"͕FYQJSF ͪ͠ΌͬͨΒɾɾɾ $͔ΒσʔλΛҾ͘

    U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET
  32. 3FEJT্ͷσʔλͷੜଘظؒ  શͯͷू߹ͷϛχϚϜ ͷੜଘظؒΛΩϟογϡ ظؒͱ͸ผʹઃఆ͢Δ  ͦͷؒʹશͯͷॲཧ ͕ऴΘΔඞཁ͕͋Δ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ "

    1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ ྫ͑͹ɺ͜͜ʹདྷΔ·Ͱʹ"͕FYQJSF ͪ͠ΌͬͨΒɾɾɾ $͔ΒσʔλΛҾ͘ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET
  33. 3FEJT্ͷσʔλͷੜଘظؒ  શͯͷू߹ͷϛχϚϜ ͷੜଘظؒΛΩϟογϡ ظؒͱ͸ผʹઃఆ͢Δ  ͦͷؒʹશͯͷॲཧ ͕ऴΘΔඞཁ͕͋Δ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ "

    1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ ྫ͑͹ɺ͜͜ʹདྷΔ·Ͱʹ"͕FYQJSF ͪ͠ΌͬͨΒɾɾɾ $͔ΒσʔλΛҾ͘ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET def expiration_time RedBlocks.config.min_ttl + self.cache_time end
  34. 3FEJT্ͷσʔλͷੜଘظؒ  શͯͷू߹ͷϛχϚϜ ͷੜଘظؒΛΩϟογϡ ظؒͱ͸ผʹઃఆ͢Δ  ͦͷؒʹશͯͷॲཧ ͕ऴΘΔඞཁ͕͋Δ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ "

    1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ ྫ͑͹ɺ͜͜ʹདྷΔ·Ͱʹ"͕FYQJSF ͪ͠ΌͬͨΒɾɾɾ $͔ΒσʔλΛҾ͘ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET def expiration_time RedBlocks.config.min_ttl + self.cache_time end
  35. 3FEJT্ͷσʔλͷੜଘظؒ  શͯͷू߹ͷϛχϚϜ ͷੜଘظؒΛΩϟογϡ ظؒͱ͸ผʹઃఆ͢Δ  ͦͷؒʹશͯͷॲཧ ͕ऴΘΔඞཁ͕͋Δ 3VCZͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ "

    1ZUIPOͷू߹Λ%#͔ΒҾ͍ͯ3FEJTʹอଘ # 3FEJT্Ͱ"ͱ#ͷ࿨ू߹Λܭࢉ͠อଘ $ ྫ͑͹ɺ͜͜ʹདྷΔ·Ͱʹ"͕FYQJSF ͪ͠ΌͬͨΒɾɾɾ $͔ΒσʔλΛҾ͘ U ಺෦ͰߦΘΕΔॲཧͷྲྀΕ 3FE#MPDLT6OJPO4FUOFX <SVCZ@TFU QZUIPO@TFU> JET def expiration_time RedBlocks.config.min_ttl + self.cache_time end RedBlocks.config.min_tll ʼ
  36. ྫɿϦϙδτϦΛݕࡧ͢ΔαʔϏεΫϥε

  37. 3FE#MPDLT6OJPO4FU3FE#MPDLT*OUFSTFDUJPO4FU class RepositorySearchService def initialize(params); @params = params end def

    fetch(per: nil, page: nil) case format when :ids set.ids(paginator: RedBlocks::Paginator.new(per || 10, page || 1)) when :count set.size end end def set @set ||= build_set(@params) end def build_set(params) sets = [PublicSet.new] sets += params.map { |key, value| case key.to_sym when :languages RedBlocks::UnionSet.new(value.map { |v| LanguageSet.new(v) }) when :tags RedBlocks::UnionSet.new(value.map { |v| TagSet.new(v) }) when :keywords RedBlocks::UnionSet.new(value.map { |v| KeywordSet.new(v) }) when :order case value.to_sym when :starred StarredSet.new when :recent RecentSet.new end end }.compact RedBlocks::IntersectionSet.new(sets, cache_time: 5.minutes).unset end end
  38. ݕ౼ɿ3FE#MPDLTͰͲ͏มΘ͔ͬͨ  ಉ༷ͷϩδοΫΛ࣋ͭू߹ΛΫϥε୯ҐͰ·ͱΊΒΕΔ  ྫɿݴޠʢʹ֘౰͢ΔϦϙδτϦͷू߹ʣΫϥε3VCZʢʹ֘౰͢ΔϦϙδτ Ϧͷू߹ʣΠϯελϯε  ݸผͷσʔλΛҾ͘෦෼Λ4FUΫϥεɺ౷߹Λ4FSWJDFͰߦ ͏ͱ͍͏෼཭͕Ͱ͖Δ 

    ྫɿ֤αϒγεςϜ΁ͷΞΫηε͸4FUΫϥεͷHFUϝιουʹہॴԽ͞ΕΔ  3FEJTʹؔ͢Δ༷ʑͳৄࡉ࣮૷Λ౎౓ߟྀ͢Δඞཁ͕ͳ͍  ྫɿ࿨ू߹ͷΩʔΛߟ͑Δඞཁ͕ͳ͍
  39. ݕ౼ɿ3FE#MPDLTͰͲ͏มΘ͔ͬͨ  ಉ༷ͷϩδοΫΛ࣋ͭू߹ΛΫϥε୯ҐͰ·ͱΊΒΕΔ  ྫɿݴޠʢʹ֘౰͢ΔϦϙδτϦͷू߹ʣΫϥε3VCZʢʹ֘౰͢ΔϦϙδτ Ϧͷू߹ʣΠϯελϯε  ݸผͷσʔλΛҾ͘෦෼Λ4FUΫϥεɺ౷߹Λ4FSWJDFͰߦ ͏ͱ͍͏෼཭͕Ͱ͖Δ 

    ྫɿ֤αϒγεςϜ΁ͷΞΫηε͸4FUΫϥεͷHFUϝιουʹہॴԽ͞ΕΔ  3FEJTʹؔ͢Δ༷ʑͳৄࡉ࣮૷Λ౎౓ߟྀ͢Δඞཁ͕ͳ͍  ྫɿ࿨ू߹ͷΩʔΛߟ͑Δඞཁ͕ͳ͍ ͷΑ͏ͳ΋ͷ΋؆୯ʹͭ͘ΕΔ
  40. ·ͱΊ

  41. ·ͱΊ  3FEJTͷ4PSUFE4FUΛ3VCZͰ4FUΫϥεͱͯ͠ఏڙ  3FEJTʹରͯ͠ద੾ͳந৅ԽΛߦ͏͜ͱͰɺෳࡶͳॲཧ͕ 3VCZͰهड़Մೳʹͳͬͨ  ͦΕʹΑΓɺ3VCZͰ΋ਪનγεςϜͷ౷߹ॲཧͷΑ͏ͳ΋ͷ Λ࡞Δ͜ͱ͕Ͱ͖Δ 

    ϝΠϯͷॲཧ͸$Ͱॻ͔Εͨ3FEJTͰߦ͏͜ͱͰɺ
 3VCZͱ͍͏ݴޠͷԸܙʢߴੜ࢈ੑɾΤίγεςϜ౳ʣΛ
 ੑೳͱཱ྆͠ͳ͕ΒڗडͰ͖Δ  ࠓޙɿ4PSUFE4FUҎ֎ͷσʔλܕʹ͍ͭͯͷݕ౼ɺ౳