Should we consider thread safety?


  • 0
    T

    It seems that leetcode compiler does not support std::mutex. Compile error: error: 'mutex' in namespace 'std' does not name a type.

    But the following code should be a thread-safe version:

    class Solution {
    public:
        // Encodes a URL to a shortened URL.
        string encode(string const& longUrl) const {
            auto iter = urlToId_->find(longUrl);
            int64_t id = 0;
            if (iter == urlToId_->end()) {
                id = idToUrl_->size();
                {
                    unique_lock<mutex> lock(mutex_);
                    idToUrl_->emplace_back(longUrl);
                    urlToId_->emplace(longUrl, id);
                }
            } else {
                id = iter->second;
            }
            return idToShortUrl(id);
        }
    
        // Decodes a shortened URL to its original URL.
        string decode(string const& shortUrl) const {
            int64_t id = 0;
            {
                unique_lock<mutex> lock(mutex_); // should use shared_lock<mutex> lock(mutex) in C++14/17
                id = shortUrlToId(shortUrl);
            }
            return (*idToUrl_)[id];
        }
        
    private:
        using UrlIdMap = unordered_map<string, int64_t>;
        mutable mutex mutex_;
        unique_ptr<UrlIdMap> urlToId_ = unique_ptr<UrlIdMap>(new UrlIdMap()); // can use make_unique in C++14/17
        unique_ptr<vector<string>> idToUrl_ = unique_ptr<vector<string>>(new vector<string>());
        const string charMap_ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        const int64_t base_ = charMap_.size();
    
        string idToShortUrl(int64_t id) const {
            string shortUrl{};
            while (id) {
                shortUrl.push_back(charMap_[id % base_]);
                id /= base_;
            }
            return shortUrl;
        }
        
        int64_t shortUrlToId(string const& shortUrl) const {
            int64_t id = 0;
            for (auto iter = shortUrl.rbegin(); iter != shortUrl.rend(); ++iter) {
                const auto ch = *iter;
                if ('a' <= ch && ch <= 'z') {
                    id = id * base_ + ch - 'a';
                } else if ('A' <= ch && ch <= 'Z') {
                    id = id * base_ + ch - 'A' + 26;
                } else if ('0' <= ch && ch <= '9') {
                    id = id * base_ + ch - '0' + 52;
                }
            }
            return id;
        }
    };
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.