blog

認可されたビット・リモート・ストレージの範囲分析

コンポーネント市場のベースモジュールであるbitのリモートメタデータ情報は透過性がないので、メタデータ情報を理解しておくとbitを理解しやすくなります。 objects すべてのハッシュファイルはこの...

Jun 3, 2020 · 5 min. read
シェア

原文:Wen Xin, Crypto商業化フロントエンド

コンポーネント市場のベースモジュールとして、ビットのリモートメタデータ情報は透明ではなく、メタデータ情報を理解することはビットをより便利に理解するのに役立ちます。

bitのリモートスコープディレクトリの構造を少し見てみると

  • オブジェクト すべてのハッシュファイルはこのディレクトリに保存されます。
  • コンポーネント このファイルは現在空です。
  • scope.jsonに現在のスコープ情報を記述します。
  • index.jsonを使用して、現在のスコープにあるすべてのコンポーネントを保存します。

index.jsonはデータソースでもあるので。内容はだいたい以下のような感じです。

 [{
 "id": {
 "scope": "ad-fe",
 "name": "ad-banner"
 },
 "isSymlink": false,
 "hash": "b08db6ab7ed1206fd04fc5d49c8cd10"
 },]

ハッシュ部分の最初の2桁がオブジェクトのフォルダ名、それ以降が対応するファイルです。

ハッシュファイル名の保存

zlibで圧縮し、ハッシュファイル名で保存する方法。

利点は...

  • データを保存する容量は小さくなります。
  • ハッシュ分散されたデータファイルは、ファイルシステムによるファイル操作に適しています。

ハッシュ生成方法

 const crypto = require('crypto');
 function sha1(data, encoding = 'hex') {
 return crypto
 .createHash('sha1')
 .update(data)
 .digest(encoding);
}

data 異なるモデルの実装に対応するオブジェクトの id メソッド。

モデルのコードは src/scope/models にあります。

例えば

//src/scope/models/model-component.ts
 id(): string {
 return this.scope ? [this.scope, this.name].join('/') : this.name;
 }

解析メソッドの抽出

ビットソースを見るsrc/scope/objects/object.ts

const zlib = require('zlib');
const fs = require('fs');
const NULL_BYTE = '\u0000';
function parse(buffer, types) {
 const firstNullByteLocation = buffer.indexOf(NULL_BYTE);
 const headers = buffer.slice(0, firstNullByteLocation).toString();
 const contents = buffer.slice(firstNullByteLocation + 1, buffer.length);
 const [header] = headers.split(" ");
 try{
 console.log(header,JSON.stringify(JSON.parse(contents.toString()),null,2))
 }catch(e){
 console.log(header,contents.toString())
 }
 
 }
 
 // ローカル解析
 let file = 'fcdecd0482caf91d19';
 let dir = "./ad-fe/objects/"+ file.substr(0,2);
 let f = file.substr(2);
 
 fs.readFile(path.resolve(dir,f), (err, data) => {
 if (err) throw err;
 zlib.inflate(data, (err, data) => {
 parse(data)
 });
 // console.log(output);
 });

ストレージ階層

graph LR
Component-->Version
Version-->Source

Component

データ構造の最初のレベルに到達

ソースコードオブジェクトsrc/scope/models/model-component.ts

Component {
 "name": "ad-banner",
 "scope": "ad-fe",
 "versions": {
 "0.0.1": "e37217ddb4cfbc691",
 "0.0.2": "2b18288ecca2aa5c6d0cea19679eb1fd4",
 "0.0.3": "713cb2a80153cecc9f6a7b476",
 "0.0.4": "d41fa1bd32d83adb031ceb1b",
 "0.0.5": "a6a413e78ef7c8b7f5cd1544c",
 "0.0.6": "c51dbeba93598ecc",
 "0.0.7": "03fcefb8afd707cac",
 "0.0.8": "1ac4072ddffdc7d467ecae92",
 "0.0.9": "0e9731bae3755db235ae93423bae15",
 "0.0.10": "fcdecd0482caf91d19"
 },
 "lang": "javascript",
 "deprecated": false,
 "bindingPrefix": "@bit",
 "remotes": [
 {
 "url": "ssh://bit@bit.xxxx.com:/data/bit/ad-fe",
 "name": "ad-fe",
 "date": "220"
 }
 ]
}

これらのデータ構造はまだ比較的明確です。

Version

第2層のメタデータのさらなる取得

ソースコードオブジェクトsrc/scope/models/version.ts

Version {
 "files": [
 {
 "file": "ea3a806c29ff79c45dfdad4ecea8e3d80",
 "relativePath": "src/components/ad-banner/index.vue",
 "name": "index.vue",
 "test": false
 }
 ],
 "mainFile": "src/components/ad-banner/index.vue",
 "bindingPrefix": "@bit",
 "log": {
 "message": "",
 "date": "777",
 "username": "xuhongzhi",
 "email": "xuhongzhi@kuaishou.com"
 },
 "ci": {},
 "docs": [],
 "dependencies": [
 {
 "id": {
 "scope": "ad-fe",
 "name": "logger",
 "version": "0.0.1"
 },
 "relativePaths": [
 {
 "sourceRelativePath": "src/logger/index.ts",
 "destinationRelativePath": "src/logger/index.ts",
 "importSpecifiers": [
 {
 "mainFile": {
 "isDefault": false,
 "name": "pageShowLog"
 }
 },
 {
 "mainFile": {
 "isDefault": false,
 "name": "showLog"
 }
 },
 {
 "mainFile": {
 "isDefault": false,
 "name": "clickLog"
 }
 }
 ],
 "isCustomResolveUsed": true,
 "importSource": "@/logger"
 }
 ]
 }
 ],
 "devDependencies": [],
 "compilerDependencies": [],
 "testerDependencies": [],
 "flattenedDependencies": [
 {
 "scope": "ad-fe",
 "name": "logger",
 "version": "0.0.1"
 }
 ],
 "flattenedDevDependencies": [],
 "flattenedCompilerDependencies": [],
 "flattenedTesterDependencies": [],
 "packageDependencies": {
 "@ks/ks-bridge": "2.0.0-alpha.5",
 "vue-property-decorator": "^8.0.0"
 },
 "devPackageDependencies": {},
 "peerPackageDependencies": {},
 "compilerPackageDependencies": {},
 "testerPackageDependencies": {},
 "customResolvedPaths": [],
 "overrides": {},
 "packageJsonChangedProps": {},
 "extensions": []
}

Source

ソースファイルのデータは、file で指定されたハッシュで取得できます。

ソース・ファイルとは、ソース・コード・ファイルだけでなく、例えば静的ファイルも含みます。

Source <template>
 <view :class="['ad-banner', 'needsclick', { isTeam }]">
 <swiper
 :class="['ad-banner-swiper', 'needsclick', { isTeam }]"
 :indicator-dots="true"
 indicator-color="rgba(,)"
 indicator-active-color="#ff5000"
 :autoplay="true"
 :circular="true"
 :interval="3000"
 :duration="500"
 @change="changeCurrentMonitor"
 >
 <swiper-item v-for="(i, index) in config" :key="index" @click="onClickBanner(i)" class="needsclick">
 
 <!--...more -->
 }
 border-radius: 16rpx;
 overflow: hidden;
}
</style>

まとめ

このメタ情報によって、ビットのデータフォーマットやデータ取得のプロセスをより深く理解することができます。ビットのストレージには魔法はなく、解析は比較的簡単です。

ハッシュ化されたファイルを保存する理由については、あまり情報が見つかりませんでした。」だけが見つかりました。

大雑把に言えば、より多くの貯蓄ができるということです。

最後に、このセリフは急いで書いたものなので、間違いがあれば遠慮なく訂正してください。

Read next

InnoDBを理解する -- トランザクション

Unrepeatable reads:トランザクションAが同じデータを複数回読み取り、その間にトランザクションBがデータを更新してコミットするため、トランザクションAが同じデータを複数回読み取ると結果に矛盾が生じます。 ファントムリード: トランザクション A が同じクエリを複数回読み取り、その間にトランザクション B が条件を満たすデータを削除または挿入します。 | READ| トランザクションが別の...

Jun 3, 2020 · 11 min read