Design and implement an in-memory rate limiter for an API gateway that enforces per-client request limits using either a sliding-window log or a token-bucket algorithm. The system receives configuration from an external service that specifies the algorithm and its parameters for each endpoint. For example, an endpoint may be configured to use a sliding-window log that allows at most 100 requests per minute per client, or a token-bucket with capacity 1000 tokens refilling at 10 tokens per second. When a request arrives you must decide, solely from in-memory state, whether to admit or reject it. If admitted, the request consumes one token or is appended to the log; if rejected, return HTTP 429 with headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After. You must efficiently evict stale data (timestamps outside the current window or expired tokens) on every check. The implementation must be thread-safe and support high concurrency.