Redis源码分析(二十八)---object创建和释放redisObject对象
今天的学习效率比较高,把Rio分析完了,又顺便学习了其中的RedisObject的文件,只要讲的就是RedisObject的一些转换和创建。里面的大多数方法都是非常类似的。列出里面长长的API列表: /* ------------ API --------------------- */robj *createObject(int ty
今天的学习效率比较高,把Rio分析完了,又顺便学习了其中的RedisObject的文件,只要讲的就是RedisObject的一些转换和创建。里面的大多数方法都是非常类似的。列出里面长长的API列表:
/* ------------ API --------------------- */ robj *createObject(int type, void *ptr) /* 最初的创建robj对象方法,后面的创建方法与此类似 */ robj *createStringObject(char *ptr, size_t len) robj *createStringObjectFromLongLong(long long value) robj *createStringObjectFromLongDouble(long double value) robj *dupStringObject(robj *o) robj *createListObject(void) robj *createZiplistObject(void) robj *createSetObject(void) robj *createIntsetObject(void) robj *createHashObject(void) robj *createZsetObject(void) robj *createZsetZiplistObject(void) void freeStringObject(robj *o) /* free Obj中的特定对象,这里free的是r->ptr */ void freeListObject(robj *o) void freeSetObject(robj *o) void freeZsetObject(robj *o) void freeHashObject(robj *o) /* 释放hashObject有2种形式,1个是o-ptr的字典对象,还有1个回事压缩表o->ptr */ void incrRefCount(robj *o) /* robj对象增减引用计数,递增robj中的refcount的值 */ void decrRefCount(robj *o) /* 递减robj中的引用计数,引用到0后,释放对象 */ void decrRefCountVoid(void *o) robj *resetRefCount(robj *obj) int checkType(redisClient *c, robj *o, int type) /* 检查robj的类型是否为给定的Type类型 */ int isObjectRepresentableAsLongLong(robj *o, long long *llval) robj *tryObjectEncoding(robj *o) /* 编码一个robj中的额字符对象,主要是为了省空间 */ robj *getDecodedObject(robj *o) /* 获取解码后的robj */ int compareStringObjectsWithFlags(robj *a, robj *b, int flags) int compareStringObjects(robj *a, robj *b) int collateStringObjects(robj *a, robj *b) int equalStringObjects(robj *a, robj *b) size_t stringObjectLen(robj *o) int getDoubleFromObject(robj *o, double *target) /* 从robj中获取double数值 */ int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const char *msg) int getLongDoubleFromObject(robj *o, long double *target) int getLongDoubleFromObjectOrReply(redisClient *c, robj *o, long double *target, const char *msg) int getLongLongFromObject(robj *o, long long *target) int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, const char *msg) int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *msg) char *strEncoding(int encoding) unsigned long estimateObjectIdleTime(robj *o) robj *objectCommandLookup(redisClient *c, robj *key) /* obj的查找命令, */ robj *objectCommandLookupOrReply(redisClient *c, robj *key, robj *reply) void objectCommand(redisClient *c)
/* 最初的创建robj对象方法 */ robj *createObject(int type, void *ptr) { robj *o = zmalloc(sizeof(*o)); o->type = type; o->encoding = REDIS_ENCODING_RAW; o->ptr = ptr; o->refcount = 1; /* Set the LRU to the current lruclock (minutes resolution). */ o->lru = server.lruclock; return o; }
/* free Obj中的特定对象 */ void freeStringObject(robj *o) { if (o->encoding == REDIS_ENCODING_RAW) { sdsfree(o->ptr); } }
switch(o->type) { case REDIS_STRING: freeStringObject(o); break; case REDIS_LIST: freeListObject(o); break; case REDIS_SET: freeSetObject(o); break; case REDIS_ZSET: freeZsetObject(o); break; case REDIS_HASH: freeHashObject(o); break; default: redisPanic("Unknown object type"); break; }
/* robj对象增减引用计数,递增robj中的refcount的值 */ void incrRefCount(robj *o) { //递增robj中的refcount的值 o->refcount++; }
/* 递减robj中的引用计数,引用到0后,释放对象 */ void decrRefCount(robj *o) { //如果之前的引用计数已经<=0了,说明出现异常情况了 if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0"); if (o->refcount == 1) { //如果之前的引用计数为1,再递减一次,恰好内有被任何对象引用了,所以就可以释放对象了 switch(o->type) { case REDIS_STRING: freeStringObject(o); break; case REDIS_LIST: freeListObject(o); break; case REDIS_SET: freeSetObject(o); break; case REDIS_ZSET: freeZsetObject(o); break; case REDIS_HASH: freeHashObject(o); break; default: redisPanic("Unknown object type"); break; } zfree(o); } else { //其他对于>1的引用计数的情况,只需要按常规的递减引用计数即可 o->refcount--; } }
/* Try to encode a string object in order to save space */ /* 编码一个robj中的额字符对象,主要是为了省空间 */ robj *tryObjectEncoding(robj *o) { long value; sds s = o->ptr; size_t len; if (o->encoding != REDIS_ENCODING_RAW) //如果robj已经被编码了,则直接返回 return o; /* Already encoded */ /* It's not safe to encode shared objects: shared objects can be shared * everywhere in the "object space" of Redis. Encoded objects can only * appear as "values" (and not, for instance, as keys) */ /* 如果robj的引用计数超过1个人引用的时候,是不安全的去编码obj,因为对象是共享的 */ if (o->refcount > 1) return o; /* Currently we try to encode only strings */ redisAssertWithInfo(NULL,o,o->type == REDIS_STRING); /* Check if we can represent this string as a long integer */ len = sdslen(s); if (len > 21 || !string2l(s,len,&value)) { /* We can't encode the object... * * Do the last try, and at least optimize the SDS string inside * the string object to require little space, in case there * is more than 10% of free space at the end of the SDS string. * * We do that for larger strings, using the arbitrary value * of 32 bytes. This code was backported from the unstable branch * where this is performed when the object is too large to be * encoded as EMBSTR. */ if (len > 32 && o->encoding == REDIS_ENCODING_RAW && sdsavail(s) > len/10) { //调用sdsRemoveFreeSpace把0->ptr中的字符串中的空格给移除掉 o->ptr = sdsRemoveFreeSpace(o->ptr); } /* Return the original object. */ return o; } .....
/* Get a decoded version of an encoded object (returned as a new object). * If the object is already raw-encoded just increment the ref count. */ /* 获取解码后的robj */ robj *getDecodedObject(robj *o) { robj *dec; if (o->encoding == REDIS_ENCODING_RAW) { //如果没有编码方式,则直接增加引用计数,并返回 incrRefCount(o); return o; } if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) { char buf[32]; //如果是string,Type而且是encoding_int方式的,先做一步转换 ll2string(buf,32,(long)o->ptr); dec = createStringObject(buf,strlen(buf)); return dec; } else { redisPanic("Unknown encoding type"); } }

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











1. [スタート]メニューを起動し、[cmd]と入力し、[コマンドプロンプト]を右クリックし、[管理者として実行]を選択します。 2. 次のコマンドを順番に入力します (注意してコピーして貼り付けてください): SCconfigwuauservstart=auto、Enter キーを押す SCconfigbitsstart=auto、Enter キーを押す SCconfigcryptsvcstart=auto、Enter キーを押す SCconfigtrustedinstallerstart=auto、Enter キーを押す SCconfigwuauservtype=share、Enter キーを押す netstopwuauserv 、enter netstopcryptS を押す

GolangAPI のキャッシュ戦略により、パフォーマンスが向上し、サーバーの負荷が軽減されます。一般的に使用される戦略は、LRU、LFU、FIFO、TTL です。最適化手法には、適切なキャッシュ ストレージの選択、階層型キャッシュ、無効化管理、監視とチューニングが含まれます。実際には、データベースからユーザー情報を取得する API を最適化するために LRU キャッシュが使用されます。それ以外の場合は、データベースからデータを取得した後にキャッシュを更新できます。

PHP 開発では、キャッシュ メカニズムにより、頻繁にアクセスされるデータがメモリまたはディスクに一時的に保存され、データベース アクセスの数が削減され、パフォーマンスが向上します。キャッシュの種類には主にメモリ、ファイル、データベース キャッシュが含まれます。キャッシュは、組み込み関数またはサードパーティのライブラリ (cache_get() や Memcache など) を使用して PHP に実装できます。一般的な実用的なアプリケーションには、データベース クエリ結果をキャッシュしてクエリ パフォーマンスを最適化したり、ページ出力をキャッシュしてレンダリングを高速化したりすることが含まれます。キャッシュ メカニズムにより、Web サイトの応答速度が効果的に向上し、ユーザー エクスペリエンスが向上し、サーバーの負荷が軽減されます。

Redis キャッシュを使用すると、PHP 配列ページングのパフォーマンスを大幅に最適化できます。これは、次の手順で実現できます。 Redis クライアントをインストールします。 Redisサーバーに接続します。キャッシュ データを作成し、データの各ページをキー「page:{page_number}」を持つ Redis ハッシュに保存します。キャッシュからデータを取得し、大規模な配列での高コストの操作を回避します。

まず、システム言語を簡体字中国語表示に設定して再起動する必要があります。もちろん、以前に表示言語を簡体字中国語に変更したことがある場合は、この手順をスキップできます。次に、レジストリ regedit.exe の操作を開始し、左側のナビゲーション バーまたは上部のアドレス バーで HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage に直接移動し、InstallLanguage キーの値と Default キーの値を 0804 に変更します (英語に変更する場合)。まずシステムの表示言語を en-us に設定し、システムを再起動してから、すべてを 0409 に変更します) この時点でシステムを再起動する必要があります。

Golang フレームワークのソース コードを理解することで、開発者は言語の本質を習得し、フレームワークの機能を拡張できます。まず、ソース コードを入手して、そのディレクトリ構造を理解します。次に、コードを読み、実行フローをトレースし、依存関係を理解します。実際の例では、この知識を適用する方法、つまりカスタム ミドルウェアの作成とルーティング システムの拡張方法を示します。ベスト プラクティスには、段階的に学習すること、無意識のコピー&ペーストを避けること、ツールを利用すること、オンライン リソースを参照することが含まれます。

1. まず、デスクトップ上の[このPC]アイコンをダブルクリックして開きます。 2. 次に、マウスの左ボタンをダブルクリックして [C ドライブ] に入ります。システム ファイルは通常、自動的に C ドライブに保存されます。 3. 次に、C ドライブで [windows] フォルダーを見つけ、ダブルクリックしてに入ります。 4. [windows]フォルダーに入ったら、[SoftwareDistribution]フォルダーを見つけます。 5. 入力後、win11 のダウンロード ファイルとアップデート ファイルがすべて含まれている [ダウンロード] フォルダーを見つけます。 6. これらのファイルを削除したい場合は、このフォルダー内で直接削除してください。

Redis は、高性能のキー/値キャッシュです。 PHPRedis 拡張機能は、Redis サーバーと対話するための API を提供します。 Redis に接続し、データを保存および取得するには、次の手順を使用します。 接続: Redis クラスを使用してサーバーに接続します。ストレージ: set メソッドを使用してキーと値のペアを設定します。取得: get メソッドを使用してキーの値を取得します。
