// Delete a key func (client *Client) Delete(key string) error { client.lock() defer client.unlock() rawKey := client.addPrefix(key) cKey := C.CString(rawKey) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(rawKey)) cNoreply := C.bool(client.noreply) var rst **C.message_result_t var n C.size_t errCode := C.client_delete( client._imp, &cKey, &cKeyLen, cNoreply, 1, &rst, &n, ) defer C.client_destroy_message_result(client._imp) if errCode == 0 { if client.noreply { return nil } else if int(n) == 1 { if (*rst).type_ == C.MSG_DELETED { return nil } else if (*rst).type_ == C.MSG_NOT_FOUND { return ErrCacheMiss } } } else if errCode == C.RET_INVALID_KEY_ERR { return ErrMalformedKey } return networkError(errorMessage[errCode]) }
// Touch command func (client *Client) Touch(key string, expiration int64) error { client.lock() defer client.unlock() rawKey := client.addPrefix(key) cKey := C.CString(rawKey) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(rawKey)) cExptime := C.exptime_t(expiration) cNoreply := C.bool(client.noreply) var rst **C.message_result_t var n C.size_t errCode := C.client_touch( client._imp, &cKey, &cKeyLen, cExptime, cNoreply, 1, &rst, &n, ) defer C.client_destroy_message_result(client._imp) if errCode == 0 { if client.noreply { return nil } else if int(n) == 1 && (*rst).type_ == C.MSG_TOUCHED { return nil } } return errors.New(errorMessage[errCode]) }
// Delete a key func (client *Client) Delete(key string) error { client.lock() defer client.unlock() rawKey := client.addPrefix(key) cKey := C.CString(rawKey) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(rawKey)) cNoreply := C.bool(client.noreply) var rst **C.message_result_t var n C.size_t errCode := C.client_delete( client._imp, &cKey, &cKeyLen, cNoreply, 1, &rst, &n, ) defer C.client_destroy_message_result(client._imp) if errCode == 0 { if client.noreply { return nil } else if int(n) == 1 && ((*rst).type_ == C.MSG_DELETED || (*rst).type_ == C.MSG_NOT_FOUND) { return nil } } return errors.New(errorMessage[errCode]) }
// Touch command func (client *Client) Touch(key string, expiration int64) error { client.lock() defer client.unlock() rawKey := client.addPrefix(key) cKey := C.CString(rawKey) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(rawKey)) cExptime := C.exptime_t(expiration) cNoreply := C.bool(client.noreply) var rst **C.message_result_t var n C.size_t errCode := C.client_touch( client._imp, &cKey, &cKeyLen, cExptime, cNoreply, 1, &rst, &n, ) defer C.client_destroy_message_result(client._imp) switch errCode { case 0: if client.noreply { return nil } else if int(n) == 1 { if (*rst).type_ == C.MSG_TOUCHED { return nil } else if (*rst).type_ == C.MSG_NOT_FOUND { return ErrCacheMiss } } case C.RET_INVALID_KEY_ERR: return ErrMalformedKey } return networkError(errorMessage[errCode]) }
// DeleteMulti will delete multi keys at once func (client *Client) DeleteMulti(keys []string) (failedKeys []string, err error) { client.lock() defer client.unlock() var rawKeys []string if len(client.prefix) == 0 { rawKeys = keys } else { rawKeys = make([]string, len(keys)) for i, key := range keys { rawKeys[i] = key } } nKeys := len(rawKeys) cNKeys := C.size_t(nKeys) cKeys := make([]*C.char, nKeys) cKeyLens := make([]C.size_t, nKeys) cNoreply := C.bool(client.noreply) var results **C.message_result_t var n C.size_t for i, key := range rawKeys { cKey := C.CString(key) defer C.free(unsafe.Pointer(cKey)) cKeys[i] = cKey cKeyLen := C.size_t(len(key)) cKeyLens[i] = cKeyLen } errCode := C.client_delete( client._imp, (**C.char)(&cKeys[0]), (*C.size_t)(&cKeyLens[0]), cNoreply, cNKeys, &results, &n, ) defer C.client_destroy_message_result(client._imp) switch errCode { case 0: err = nil return case C.RET_INVALID_KEY_ERR: err = ErrMalformedKey default: err = networkError(errorMessage[errCode]) } if client.noreply { failedKeys = keys return } deletedKeySet := make(map[string]struct{}) sr := unsafe.Sizeof(*results) for i := 0; i <= int(n); i++ { if (*results).type_ == C.MSG_DELETED { deletedKey := C.GoStringN((*results).key, C.int((*results).key_len)) deletedKeySet[deletedKey] = struct{}{} } results = (**C.message_result_t)( unsafe.Pointer(uintptr(unsafe.Pointer(results)) + sr), ) } err = networkError(errorMessage[errCode]) failedKeys = make([]string, len(rawKeys)-len(deletedKeySet)) i := 0 for _, key := range rawKeys { if _, contains := deletedKeySet[key]; contains { continue } failedKeys[i] = client.removePrefix(key) i++ } return }
// SetMulti will set multi values at once func (client *Client) SetMulti(items []*Item) (failedKeys []string, err error) { client.lock() defer client.unlock() nItems := len(items) cKeys := make([]*C.char, nItems) cKeyLens := make([]C.size_t, nItems) cValues := make([]*C.char, nItems) cValueSizes := make([]C.size_t, nItems) cFlagsList := make([]C.flags_t, nItems) for i, item := range items { rawKey := client.addPrefix(item.Key) cKey := C.CString(rawKey) defer C.free(unsafe.Pointer(cKey)) cKeys[i] = cKey cKeyLen := C.size_t(len(rawKey)) cKeyLens[i] = cKeyLen cVal := C.CString(string(item.Value)) defer C.free(unsafe.Pointer(cVal)) cValues[i] = cVal cValueSize := C.size_t(len(item.Value)) cValueSizes[i] = cValueSize cFlags := C.flags_t(item.Flags) cFlagsList[i] = cFlags } cExptime := C.exptime_t(items[0].Expiration) cNoreply := C.bool(client.noreply) cNItems := C.size_t(nItems) var results **C.message_result_t var n C.size_t errCode := C.client_set( client._imp, (**C.char)(&cKeys[0]), (*C.size_t)(&cKeyLens[0]), (*C.flags_t)(&cFlagsList[0]), cExptime, nil, cNoreply, (**C.char)(&cValues[0]), (*C.size_t)(&cValueSizes[0]), cNItems, &results, &n, ) defer C.client_destroy_message_result(client._imp) if errCode == 0 { return []string{}, nil } if errCode == C.RET_INVALID_KEY_ERR { err = ErrMalformedKey } else { err = networkError(errorMessage[errCode]) } sr := unsafe.Sizeof(*results) storedKeySet := make(map[string]struct{}) for i := 0; i <= int(n); i++ { if (*results).type_ == C.MSG_STORED { storedKey := C.GoStringN((*results).key, C.int((*results).key_len)) storedKeySet[storedKey] = struct{}{} } results = (**C.message_result_t)( unsafe.Pointer(uintptr(unsafe.Pointer(results)) + sr), ) } failedKeys = make([]string, len(items)-len(storedKeySet)) i := 0 for _, item := range items { if _, contains := storedKeySet[item.Key]; contains { continue } failedKeys[i] = client.removePrefix(item.Key) i++ } return failedKeys, err }
func (client *Client) store(cmd string, item *Item) error { client.lock() defer client.unlock() key := client.addPrefix(item.Key) cKey := C.CString(key) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(key)) cFlags := C.flags_t(item.Flags) cExptime := C.exptime_t(item.Expiration) cNoreply := C.bool(client.noreply) cValue := C.CString(string(item.Value)) defer C.free(unsafe.Pointer(cValue)) cValueSize := C.size_t(len(item.Value)) var rst **C.message_result_t var n C.size_t var errCode C.int switch cmd { case "set": errCode = C.client_set( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "add": errCode = C.client_add( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "replace": errCode = C.client_replace( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "prepend": errCode = C.client_prepend( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "append": errCode = C.client_append( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "cas": cCasUnique := C.cas_unique_t(item.casid) errCode = C.client_cas( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, &cCasUnique, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) } defer C.client_destroy_message_result(client._imp) if errCode == 0 { if client.noreply { return nil } else if int(n) == 1 { switch (*rst).type_ { case C.MSG_STORED: return nil case C.MSG_NOT_STORED: return ErrNotStored case C.MSG_EXISTS: return ErrCASConflict case C.MSG_NOT_FOUND: return ErrCacheMiss } } } else if errCode == C.RET_INVALID_KEY_ERR { return ErrMalformedKey } return networkError(errorMessage[errCode]) }
func (client *Client) store(cmd string, item *Item) error { client.lock() defer client.unlock() key := client.addPrefix(item.Key) cKey := C.CString(key) defer C.free(unsafe.Pointer(cKey)) cKeyLen := C.size_t(len(key)) cFlags := C.flags_t(item.Flags) cExptime := C.exptime_t(item.Expiration) cNoreply := C.bool(client.noreply) cValue := C.CString(string(item.Value)) defer C.free(unsafe.Pointer(cValue)) cValueSize := C.size_t(len(item.Value)) var rst **C.message_result_t var n C.size_t var errCode C.int switch cmd { case "set": errCode = C.client_set( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "add": errCode = C.client_add( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "replace": errCode = C.client_replace( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "prepend": errCode = C.client_prepend( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "append": errCode = C.client_append( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, nil, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) case "cas": cCasUnique := C.cas_unique_t(item.casid) errCode = C.client_cas( client._imp, &cKey, &cKeyLen, &cFlags, cExptime, &cCasUnique, cNoreply, &cValue, &cValueSize, 1, &rst, &n, ) } defer C.client_destroy_message_result(client._imp) if errCode == 0 { if client.noreply { return nil } else if int(n) == 1 && (*rst).type_ == C.MSG_STORED { return nil } } return errors.New(errorMessage[errCode]) }