Repository: servo/servo
File: components/net/http_cache.rs (Rust)

Code before:
            }
            let to_send = if cached_resource.aborted.load(Ordering::Acquire) {
                // In the case of an aborted fetch,
                // wake-up all awaiting consumers.
                // Each will then start a new network request.
                // TODO: Wake-up only one consumer, and make it the producer on which others wait.
                Data::Cancelled
            } else {
                match *cached_resource.body.lock() {
                    ResponseBody::Done(_) | ResponseBody::Empty => Data::Done,
                    ResponseBody::Receiving(_) => {
                        continue;
                    },
                }
            };
            for done_sender in awaiting_consumers.drain(..) {
                let _ = done_sender.send(to_send.clone());
            }
        }
    }

    /// Returns a list of origins for which this HTTP cache currently
    /// contains entries.
    pub fn origin_descriptors(&self) -> Vec<OriginDescriptor> {
        let mut set: HashSet<String> = HashSet::new();

        for (key, _) in self.entries.iter() {
            set.insert(key.url.origin().ascii_serialization());
        }

        set.into_iter().map(OriginDescriptor::new).collect()
    }

    /// Clear the contents of this cache.
    pub fn clear(&self) {
        self.entries.clear();
    }

    /// Insert a response for `request` into the cache (used by tests that need direct access).
    pub async fn store(&self, request: &Request, response: &Response) {
        let guard = self.get_or_guard(CacheKey::new(request)).await;
        guard.insert(request, response).await;
    }

    /// Try to construct a cached response for `request`.
    pub async fn construct_response(
        &self,
        request: &Request,
        done_chan: &mut DoneChannel,
    ) -> Option<Response> {
        let entry = self.entries.get(&CacheKey::new(request))?;

Review comment (suggestion):
I suspect you can do something like this:


```suggestion
        HashSet::from(self.entries.iter().map(|entry| url.origin().ascii_serialization()).into()
    }
```

Code after:
                // In the case of an aborted fetch,
                // wake-up all awaiting consumers.
                // Each will then start a new network request.
                // TODO: Wake-up only one consumer, and make it the producer on which others wait.
                Data::Cancelled
            } else {
                match *cached_resource.body.lock() {
                    ResponseBody::Done(_) | ResponseBody::Empty => Data::Done,
                    ResponseBody::Receiving(_) => {
                        continue;
                    },
                }
            };
            for done_sender in awaiting_consumers.drain(..) {
                let _ = done_sender.send(to_send.clone());
            }
        }
    }

    /// Returns descriptors for cache entries currently stored in this cache.
    pub fn cache_entry_descriptors(&self) -> Vec<CacheEntryDescriptor> {
        self.entries
            .iter()
            .map(|(key, _)| CacheEntryDescriptor::new(key.url.to_string()))
            .collect()
    }

    /// Clear the contents of this cache.
    pub fn clear(&self) {
        self.entries.clear();
    }

    /// Insert a response for `request` into the cache (used by tests that need direct access).
    pub async fn store(&self, request: &Request, response: &Response) {
        let guard = self.get_or_guard(CacheKey::new(request)).await;
        guard.insert(request, response).await;
    }

    /// Try to construct a cached response for `request`.
    pub async fn construct_response(
        &self,
        request: &Request,
        done_chan: &mut DoneChannel,
    ) -> Option<Response> {
        let entry = self.entries.get(&CacheKey::new(request))?;
        let cached_resources = entry.read().await;
        construct_response(request, done_chan, cached_resources.as_slice())
            .map(|cached| cached.response)
    }

    /// Invalidate cache entries referenced by Location/Content-Location headers.