2013년 2월 6일 수요일

Redis command - 1

* GET key
Time complexity: O(1)
key의 값(value) 얻어오기. key가 없으면 nil을 리턴
GET은 string만을 다루기 때문에 key의 값이 string이 아니면 에러가 리턴됨

- getCommand in t_string.c
a. db로부터 key를 찾는다.
b. key가 있으면 access time을 업데이트
c. key가 없으면 "$-1\r\n"을 client에 보낸다.
d. 찾은 key의 type이 string이 아니면 "-ERR Operation against a key holding the wrong kind of value\r\n"을 client에 보낸다.
e. 리턴할 value의 크기를 prefix로 해주고(예: "$2344\r\n") 뒤에 value를 붙인 후 client에게 보낸다.(예: value가 Hello인 경우 - "$5\r\nHello\r\n")

- value의 크기가 32보다 작은 경우는 자주 사용되므로 미리 shared.bulkhdr[]에 보낼 값을 만들어 놓고 사용함
shared.bulkhdr[j] = createObject(REDIS_STRING, sdscatprintf(sdsempty(), "$%d\r\n", j));

* SET key value
Time complexity: O(1)
string인 value를 key로 하여 저장. key가 이미 있으면 그 값의 타입이 무었인지에 상관없이 덮어쓴다.

- setCommand in t_string.c
a. 공간 절약을 위해 string이 숫자이면 숫자로 변환한다.
b. db에 key/value를 무조건 설정한다.(없으면 add, 있으면 overwrite)
c. expire가 설정되어 있으면 delete
d. 이 key를 watch하고 있는 client가 있으면 이 client의 flags값에 REDIS_DIRTY_CAS를 더함으로서 그 client에서의 exec가 실패하도록 해준다.
e. 항상 "+OK\r\n"을 client에게 보낸다.(set은 실패하지 않음)

* SETNX key value
Time complexity: O(1)
key가 없을 경우만 key/value를 저장한다.

- setnxCommand in t_string.c
a. key가 없을 경우는 SET과 같다.
b. key가 있을 경우 ":0\\r\n"을 key가 없을 경우는 ":1\r\n"을 client에게 보낸다.

* SETEX key seconds value
Time complexity: O(1)
주어진 시간에 timeout하는 key/value 저장
아래의 두 명령을 MULTI/EXEC block 안에서 실행하는 것과 같은 명령
    SET key value
    EXPIRE key seconds

- setexCommand in t_string.c
위의 SET 명령어에 더하여 expire에 관련된 부분만 추가해줌
a. seconds를 milliseconds로 바꾼다.
b. db의 expires로부터 key를 찾는다.(없으면 추가)
c. key의 value를 milliseconds로 바꾸어준다.

* PSETEX key milliseconds value 
Time complexity: O(1)
expire time을 millisecond로 설정한다는 것만 제외하고는 setex와 같은 명령어

* APPEND key value
Time complexity: O(1)
key가 이미 있고 string이라면 string의 끝에 value를 더한다. 없으면 key를 만들어서 value를 넣는다.

- appendCommand in t_string.c
a. key를 찾는다.
b. 없으면 key를 만들어 value를 저장한다.
c. key가 있으면 type을 확인하여 type이 string이 아니면 "-ERR Operation against a key holding the wrong kind of value\r\n"을 client에게 보낸다.
d. append할 경우 string의 size가 512MB를 넘으면 "string exceeds maximum allowed size (512MB)"를 client에게 보낸다.
e. object가 shared이거나 encoded이면 value를 copy한 후 key의 value에 덮어쓴다.
f. key의 value가 바뀌었으므로 watch하고 있는 client에 signal을 날린다.

* STRLEN key
Time complexity: O(1)
key에 저장된 value의 size를 리턴한다. key가 string이 아니면 에러를 리턴한다.

- strlenCommand in t_string.c
a. key가 없으면 ":0\r\n"을 client에게 보낸다.
b. key가 string이 아니면  "-ERR Operation against a key holding the wrong kind of value\r\n"을 client에게 보낸다.
c. value의 크기를 client에게 보낸다.

* DEL key [key ...]
Time complexity: O(1)
지정한 키를 지운다. key가 없으면 무시한다.

- delCommand in db.c
a. argument로 지정한 key들을 지운다.
b. 지정한 key를 watch하고 있는 client에게 알린다.
c. 지운 key의 수를 client에게 보낸다.

* EXISTS key
Time complexity: O(1)
key가 존재하는지 확인한다.

- existsCommand in db.c
a. key가 존재하는지 확인한다.
b. 있으면 ":1\r\n"을 client에게 보낸다.
c. 없으면 ":0\r\n"을 client에게 보낸다.

* SETBIT key offset value
Time complexity: O(1)
key에 저장된 value의 offset위치의 bit를 set(1) 또는 clear(0)한다.

- setbitCommand in bitops.c
a. offset의 값을 가져온다. 512MB이하여야 한다. 아닐경우 "-ERR bit offset is not an integer or out of range\r\n"를 리턴한다.
b. value의 값을 가져온다. LONG_MIN과 LONG_MAX사이여야 한다. 아닐 경우 "-ERR bit is not an integer or out of range\r\n"를 client에게 보낸다.
c. offset이 0이나 1이 아니면 "-ERR bit is not an integer or out of range\r\n"를 client에게 보낸다.
d. key를 찾는다.
e. key가 없으면 empty string을 새로 만든다.
f. key가 있으면 type이 string인지 확인한다. 그리고 나서 key가 shared 또는 encoded이면 copy를 하여 기존의 다른 값이 변하지 않도록 한다.
g. string의 크기가 offset만큼 크지 않으면 offset 설정이 가능하도록 string의 크기를 증가시킨다. 이때 추가되는 부분의 bit값은 0으로 한다.
h. offset 부분의 값을 value로 바꾼다.(key의 값이 바뀌므로 watch중인 client에 signal을 보낸다.)
i. 값을 바꾼 bit의 원래 값을 client에게 보낸다.

* GETBIT key offset
Time complexity: O(1)
key에 저장된 value의 offset 위치의 값을 리턴한다.

- getbitCommand in bitops.c
a. offset 값이 정상적인지 확인한다.
b. key가 없으면 ":0\r\n"을 client에게 보낸다. type이 string이 아니면 에러를 리턴한다.
c. key가 있으면 offset 위치의 값을 client에게 보낸다.(":1\\r\n" or ":0\r\n")
d. offset의 위치가 key의 string 크기를 벗어나면 0으로 가정하고 값을 리턴한다.

* SETRANGE key offset value
Time complexity: O(1)
string의 부분을 변경한다.

- setrangeCommand in t_string.c
a. offset값을 가져온다. 값이 0보다 작으면 "-ERR offset is out of range\r\n"을 client에게 보낸다.
b. key를 찾는다.
c. key가 없는 경우 다음의 순서로 진행한다.
    c-1. value의 크기가 0이면 ":0\r\n"을 client에게 보낸다.
    c-2. offset + value의 크기가 최대 크기를 넘으면 에러를 리턴한다.
    c-3. key에 빈 스트링을 넣는다.
d. key가 있는 경우
    d-1. key의 타입이 string인지 확인한다.
    d-2. value의 크기가 0이면 저장되어 있는 key의 value의 크기를 리턴한다.
    d-3. offset + value의 크기가 최대 크기를 넘으면 에러를 리턴한다.
    d-4. object가 shared이거나 encoded이면 object를 복사한다.
e. value의 크기가 0보다 크면 key의 value의 offset위치의 값을 변경한다. 이때 offset위치가 저장되어 있는 value의 크기보다 크면 0(zero byte)을 붙여서 값 변경이 가능하도록 해준다.
f. 변경된 value의 크기를 리턴한다.

* GETRANGE key start end
Time complexity: O(N)
string의 지정한 부분의 값을 가져온다. 음수의 start와 end는 뒤에서 부터를 의미한다. 이전 버전에서는 SUBSTR이었다.(코드에 남아있으므로 사용은 가능하다.)

- getrangeCommand in t_string.c
a. key가 없으면 "$0\r\n\r\n"를 리턴한다.
b. start가 음수인 경우 뒤에서 부터 value에서의 실제 위치를 계산했을 때 value의 0 index보다 더 작게 가면 0으로 설정한다.
c. end가 음수인 경우 뒤에서 부터 value에서의 실제 위치를 계산했을 때 value의 0 index보다 작으면 0으로 설정한다.
d. end가 value의 크기보다 크면 값을 value의 크기로 조정한다.
c. end보다 start가 더 크면 "$0\r\n\r\n"를 리턴한다.

댓글 없음:

댓글 쓰기

Building asynchronous views in SwiftUI 정리

Handling loading states within SwiftUI views self loading views View model 사용하기 Combine을 사용한 AnyPublisher Making SwiftUI views refreshable r...