1. 程式人生 > 程式設計 >C++實現迷宮生成與解決

C++實現迷宮生成與解決

Redis 是一個鍵值對(key-value pair)資料庫伺服器, 伺服器中的每個資料庫都由一個 redis.h/redisDb 結構表示, 其中, redisDb 結構的dict 字典儲存了資料庫中的所有鍵值對, 我們將這個字典稱為鍵空間(key space):  

typedef struct redisDb {

    // ...

    // 資料庫鍵空間,儲存著資料庫中的所有鍵值對
    dict *dict;

    // ...

} redisDb;

鍵空間和使用者所見的資料庫是直接對應的:

  • 鍵空間的鍵也就是資料庫的鍵, 每個鍵都是一個字串物件。
  • 鍵空間的值也就是資料庫的值, 每個值可以是字串物件、列表物件、雜湊表物件、集合物件和有序集合物件在內的任意一種 Redis 物件。

舉個例子, 如果我們在空白的資料庫中執行以下命令:

redis> SET message "hello world"
OK

redis> RPUSH alphabet "a" "b" "c"
(integer) 3

redis> HSET book name "Redis in Action"
(integer) 1

redis> HSET book author "Josiah L. Carlson"
(integer) 1

redis> HSET book publisher "Manning"
(integer) 1

那麼在這些命令執行之後, 資料庫的鍵空間將會是圖 IMAGE_DB_EXAMPLE 所展示的樣子:

  • alphabet 是一個列表鍵, 鍵的名字是一個包含字串 "alphabet" 的字串物件, 鍵的值則是一個包含三個元素的列表物件。
  • book 是一個雜湊表鍵, 鍵的名字是一個包含字串 "book" 的字串物件, 鍵的值則是一個包含三個鍵值對的雜湊表物件。
  • message 是一個字串鍵, 鍵的名字是一個包含字串 "message" 的字串物件, 鍵的值則是一個包含字串 "hello world" 的字串物件。

 

因為資料庫的鍵空間是一個字典, 所以所有針對資料庫的操作 —— 比如新增一個鍵值對到資料庫, 或者從資料庫中刪除一個鍵值對, 又或者在資料庫中獲取某個鍵值對, 等等, 實際上都是通過對鍵空間字典進行操作來實現的, 以下幾個小節將分別介紹資料庫的新增、刪除、更新、取值等操作的實現原理。

新增新鍵

新增一個新鍵值對到資料庫, 實際上就是將一個新鍵值對新增到鍵空間字典裡面, 其中鍵為字串物件, 而值則為任意一種型別的 Redis 物件。

舉個例子, 如果鍵空間當前的狀態如圖 IMAGE_DB_EXAMPLE 所示, 那麼在執行以下命令之後:

redis> SET date "2013.12.1"
OK

鍵空間將新增一個新的鍵值對, 這個新鍵值對的鍵是一個包含字串 "date" 的字串物件, 而鍵值對的值則是一個包含字串 "2013.12.1"的字串物件, 如圖 IMAGE_DB_AFTER_ADD_NEW_KEY 所示。

 

再舉個例子, 如果我們繼續執行以下命令:

redis> HSET book page 320
(integer) 1

那麼鍵空間中 book 鍵的值物件(一個雜湊物件)將被更新, 新的鍵值對 page 和 320 會被新增到值物件裡面, 如圖 IMAGE_UPDATE_BY_HSET 所示。

因為資料庫的鍵空間是一個字典, 所以所有針對資料庫的操作 —— 比如新增一個鍵值對到資料庫, 或者從資料庫中刪除一個鍵值對, 又或者在資料庫中獲取某個鍵值對, 等等, 實際上都是通過對鍵空間字典進行操作來實現的, 以下幾個小節將分別介紹資料庫的新增、刪除、更新、取值等操作的實現原理。

新增新鍵

新增一個新鍵值對到資料庫, 實際上就是將一個新鍵值對新增到鍵空間字典裡面, 其中鍵為字串物件, 而值則為任意一種型別的 Redis 物件。

舉個例子, 如果鍵空間當前的狀態如圖 IMAGE_DB_EXAMPLE 所示, 那麼在執行以下命令之後:

redis> SET date "2013.12.1"
OK

鍵空間將新增一個新的鍵值對, 這個新鍵值對的鍵是一個包含字串 "date" 的字串物件, 而鍵值對的值則是一個包含字串 "2013.12.1"的字串物件, 如圖 IMAGE_DB_AFTER_ADD_NEW_KEY 所示。

刪除鍵

刪除資料庫中的一個鍵, 實際上就是在鍵空間裡面刪除鍵所對應的鍵值對物件。

舉個例子, 如果鍵空間當前的狀態如圖 IMAGE_DB_EXAMPLE 所示, 那麼在執行以下命令之後:

redis> DEL book
(integer) 1

鍵 book 以及它的值將從鍵空間中被刪除, 如圖 IMAGE_DB_AFTER_DEL 所示。

更新鍵

對一個數據庫鍵進行更新, 實際上就是對鍵空間裡面鍵所對應的值物件進行更新, 根據值物件的型別不同, 更新的具體方法也會有所不同。

舉個例子, 如果鍵空間當前的狀態如圖 IMAGE_DB_EXAMPLE 所示, 那麼在執行以下命令之後:

redis> SET message "blah blah"
OK

鍵 message 的值物件將從之前包含 "hello world" 字串更新為包含 "blah blah" 字串, 如圖 IMAGE_DB_UPDATE_CAUSE_SET 所示。

 

 再舉個例子, 如果我們繼續執行以下命令:

redis> HSET book page 320
(integer) 1

那麼鍵空間中 book 鍵的值物件(一個雜湊物件)將被更新, 新的鍵值對 page 和 320 會被新增到值物件裡面, 如圖 IMAGE_UPDATE_BY_HSET 所示。

對鍵取值

對一個數據庫鍵進行取值, 實際上就是在鍵空間中取出鍵所對應的值物件, 根據值物件的型別不同, 具體的取值方法也會有所不同。

舉個例子, 如果鍵空間當前的狀態如圖 IMAGE_DB_EXAMPLE 所示, 那麼當執行以下命令時:

redis> GET message
"hello world"

GET 命令將首先在鍵空間中查詢鍵 message , 找到鍵之後接著取得該鍵所對應的字串物件值, 之後再返回值物件所包含的字串 "helloworld" , 取值過程如圖 IMAGE_FETCH_VALUE_VIA_GET 所示。

 

 再舉一個例子, 當執行以下命令時:

redis> LRANGE alphabet 0 -1
1) "a"
2) "b"
3) "c"

LRANGE 命令將首先在鍵空間中查詢鍵 alphabet , 找到鍵之後接著取得該鍵所對應的列表物件值, 之後再返回列表物件中包含的三個字串物件的值, 取值過程如圖 IMAGE_FETCH_VALUE_VIA_LRANGE 所示。