★初期回答
※ 誤っている点もありますが、記録として残しておきます。後ろに追加した追加検証もご覧ください。(誤っている箇所は取り消し線を入れました)
完全に私の主観ですが、こういう事ではないでしょうか。
- ① UUIDにより辞書型のキーが重複しない様にし
- ② ハッシュ化により、データ同士の比較を容易にしている
UUIDについて
_id = uuid.uuid4()
について
UUID4は乱数ベースなのでデバイスの違いなどによる偏りが出ないと予測します。
UUIDを使う意図としては重複しない事ですね。辞書型のキーとして使うならここは重要と思います。
データの中身は一緒でもキーが異なるので、同じデータをいくつも持てる事にもなります。
※このプロダクトだとキーは2種類。同一データでもユニークに扱うためのキーと、KV型データの中のキーに相当するものがあります。以降、ユニークキー、データキーと使い分けます。
ハッシュ化について
hash(tuple(data))
について
データをハッシュ化する事で、一定の型(組込hash()なので整数)になります。
格納するデータの型はオブジェクトも含んでまちまちだと思いますが、一緒かどうかという判定はラクに出来ると思います。
キーが違っていても同じデータというのはあるので、それらが一緒かどうかというのもハッシュを見るだけでOKという事になります。
※正しくは、データキーの重複に容易に気づける事でしょう
ただ、これは要件次第ではデメリットにもなると思っていまして
データとしてオブジェクトを格納する場合、一律でhash(tuple(data))
としているのでオブジェクトの中の特定の値を見たいといった場合には、正しく比較が出来ない可能性もあります。
(例えばdata.hoge
の値だけで同値かを判定する)
単に、is演算子的な比較をしたいのかどうかというのもありますね。
どちらにせよ、この辺は作りたいものに合わせて修正する必要があるかもしれません。
※botterの性質を考えると、デメリットは特に思いつきません
蛇足
Java
の話になりますが、全てのObjectにはEquals(obj)という関数があります。
これはObject自身のhash値を計算して、引数のobj
と同値かどうかで判定しています。
質問に掲載したコードの意図はこれと似たようなものではないのかと思いました。
※機能の性質としてはあっているが、意図とは異なるでしょうね…orz
参考
Python 標準ライブラリ » 組み込み関数
https://docs.python.org/ja/3/library/functions.html#hash
Python インターネットプロトコルとサポート » uuid --- RFC 4122 に基づくUUID オブジェクト
https://docs.python.org/ja/3/library/uuid.html
モジュール java.base > パッケージ java.lang > クラスObject > java.lang.Object
https://docs.oracle.com/javase/jp/15/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)
★追加検証分
追記分です。
今回掲載したコードで目的を考えるなら、下記の性質から単サーバ複クライアントでも最新データに気づく為の仕掛けと考えると腑に落ちました。
- ①
DataBase._index
にはキーの数だけ要素が増える事
- ②
DataBase._data
の各要素に対するindexは、最新のidを指している事
- ③ GitHubのプロダクトが仮想通貨用のbotterである事(時間とタイミングの勝負でしょうし)
検証コード
python3
1from typing import Dict
2import uuid
3
4class DataBase:
5
6 def __init__(self) -> None:
7 """
8 初期化
9 """
10 self._data: Dict[uuid.UUID, Dict] = {}
11 self._index: Dict[int, uuid.UUID] = {}
12
13
14 def insert(self, data: Dict[str, int]) -> None:
15 """
16 KV型データを追加する
17 """
18 _id = uuid.uuid4()
19 self._data[_id] = data
20
21 keyhash = hash(tuple(data))
22 self._index[keyhash] = _id
23
24 def print_all_datas(self):
25 """
26 データリストを出力する
27 """
28 for i, _id in enumerate(self._data):
29 _data = self._data[_id]
30 _seed = tuple(_data)
31 _keyhash = hash(_seed)
32 _index = self._index[_keyhash]
33 print(f'{i} => id: {_id}, index: {_index}, hash: {_keyhash: >20}, seed: {_seed}, data: {_data}')
34
35 def print_all_indexes(self):
36 """
37 ハッシュリストを出力する
38 """
39 for i, _keyhash in enumerate(self._index):
40 _id = self._index[_keyhash]
41 print(f'{i} => hash: {_keyhash: >20}, latest_id: {_id}')
42
43db = DataBase()
44db.insert({'priceA': 5000})
45db.insert({'priceB': 4000})
46db.insert({'priceA': 3000})
47db.insert({'priceA': 5000})
48db.insert({'priceA': 7000})
49
50print('### print_all_datas ###')
51db.print_all_datas()
52
53print('### print_all_indexes ###')
54db.print_all_indexes()
実行結果
log
1### print_all_datas ###
20 => id: 498a2423-8f65-42ac-90f7-d2e321f8b1ec, index: 689e09cb-dadd-4cb7-ad69-a6377c4a362f, hash: -261320819014024164, seed: ('priceA',), data: {'priceA': 5000}
31 => id: daaa98fb-cba8-4dbd-9299-172754780f01, index: daaa98fb-cba8-4dbd-9299-172754780f01, hash: 4814718565598271203, seed: ('priceB',), data: {'priceB': 4000}
42 => id: c0422535-cdae-4b92-a22a-09cf98dd928f, index: 689e09cb-dadd-4cb7-ad69-a6377c4a362f, hash: -261320819014024164, seed: ('priceA',), data: {'priceA': 3000}
53 => id: cf0d74f1-752f-43a6-898c-292c276d9bb3, index: 689e09cb-dadd-4cb7-ad69-a6377c4a362f, hash: -261320819014024164, seed: ('priceA',), data: {'priceA': 5000}
64 => id: 689e09cb-dadd-4cb7-ad69-a6377c4a362f, index: 689e09cb-dadd-4cb7-ad69-a6377c4a362f, hash: -261320819014024164, seed: ('priceA',), data: {'priceA': 7000}
7### print_all_indexes ###
80 => hash: -261320819014024164, latest_id: 689e09cb-dadd-4cb7-ad69-a6377c4a362f
91 => hash: 4814718565598271203, latest_id: daaa98fb-cba8-4dbd-9299-172754780f01
検証結果から分かる事
- 登録したデータは重複キーも含めて全てユニークに持っている(UUIDをユニークキーとしている)
- indexには、最新データを持つユニークキーの一覧が入っている
- 各登録データは、hashを使ったデータキーによるアクセスをする事で、indexに入っている最新のユニークキーが事に気づける。クライアントとしては自分のユニークキーとは違うと気づける
- 今回の掲載コードにはありませんが、hashが一致しなければ更新させないといった楽観的ロックの仕掛けと見る事も出来そうですね
以上です。長文失礼しました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/26 02:06 編集
2021/06/26 03:02
2021/06/26 11:10
2021/06/27 01:31