<commit_before>package gokvstores

import (
	"net"
	"time"

	conv "github.com/cstockton/go-conv"
	redis "gopkg.in/redis.v5"
)

// ----------------------------------------------------------------------------
// Client
// ----------------------------------------------------------------------------

// RedisClient is an interface thats allows to use Redis cluster or a redis single client seamlessly.
type RedisClient interface {
	Ping() *redis.StatusCmd
	Exists(key string) *redis.BoolCmd
	Del(keys ...string) *redis.IntCmd
	FlushDb() *redis.StatusCmd
	Close() error
	Process(cmd redis.Cmder) error
	Get(key string) *redis.StringCmd
	Set(key string, value interface{}, expiration time.Duration) *redis.StatusCmd
	MGet(keys ...string) *redis.SliceCmd
	HDel(key string, fields ...string) *redis.IntCmd
	HGetAll(key string) *redis.StringStringMapCmd
	HMSet(key string, fields map[string]string) *redis.StatusCmd
	SMembers(key string) *redis.StringSliceCmd
	SAdd(key string, members ...interface{}) *redis.IntCmd
	Keys(pattern string) *redis.StringSliceCmd
	Pipeline() *redis.Pipeline
}

// RedisPipeline is a struct which contains an opend redis pipeline transaction
type RedisPipeline struct {
	pipeline *redis.Pipeline
}

// RedisClientOptions are Redis client options.
type RedisClientOptions struct {
	Network            string
	Addr               string
	Dialer             func() (net.Conn, error)
	Password           string
	DB                 int
	MaxRetries         int
	DialTimeout        time.Duration
	ReadTimeout        time.Duration
	WriteTimeout       time.Duration
	PoolSize           int
	PoolTimeout        time.Duration
	IdleTimeout        time.Duration
	IdleCheckFrequency time.Duration
	ReadOnly           bool
}

// RedisClusterOptions are Redis cluster options.
type RedisClusterOptions struct {
	Addrs              []string
	MaxRedirects       int
	ReadOnly           bool
	RouteByLatency     bool
	Password           string
	DialTimeout        time.Duration
	ReadTimeout        time.Duration
	WriteTimeout       time.Duration
	PoolSize           int
	PoolTimeout        time.Duration
	IdleTimeout        time.Duration
	IdleCheckFrequency time.Duration
}

// ----------------------------------------------------------------------------
// Store
// ----------------------------------------------------------------------------

// RedisStore is the Redis implementation of KVStore.
type RedisStore struct {
	client     RedisClient
	expiration time.Duration
}

// Get returns value for the given key.
func (r *RedisStore) Get(key string) (interface{}, error) {
	cmd := redis.NewCmd("get", key)

	if err := r.client.Process(cmd); err != nil {
		return nil, err
	}

	return cmd.Val(), cmd.Err()
}

// MGet returns map of key, value for a list of keys.
func (r *RedisStore) MGet(keys []string) (map[string]interface{}, error) {
	values, err := r.client.MGet(keys...).Result()

	newValues := make(map[string]interface{}, len(keys))

	for k, v := range keys {
		value := values[k]
		if err != nil {
			return nil, err
		}

		newValues[v] = value
	}
	return newValues, nil
}<commit_msg>fix: handle redis.Nil case for RedisStore.Get<commit_after>package gokvstores

import (
	"net"
	"time"

	conv "github.com/cstockton/go-conv"
	redis "gopkg.in/redis.v5"
)

// ----------------------------------------------------------------------------
// Client
// ----------------------------------------------------------------------------

// RedisClient is an interface thats allows to use Redis cluster or a redis single client seamlessly.
type RedisClient interface {
	Ping() *redis.StatusCmd
	Exists(key string) *redis.BoolCmd
	Del(keys ...string) *redis.IntCmd
	FlushDb() *redis.StatusCmd
	Close() error
	Process(cmd redis.Cmder) error
	Get(key string) *redis.StringCmd
	Set(key string, value interface{}, expiration time.Duration) *redis.StatusCmd
	MGet(keys ...string) *redis.SliceCmd
	HDel(key string, fields ...string) *redis.IntCmd
	HGetAll(key string) *redis.StringStringMapCmd
	HMSet(key string, fields map[string]string) *redis.StatusCmd
	SMembers(key string) *redis.StringSliceCmd
	SAdd(key string, members ...interface{}) *redis.IntCmd
	Keys(pattern string) *redis.StringSliceCmd
	Pipeline() *redis.Pipeline
}

// RedisPipeline is a struct which contains an opend redis pipeline transaction
type RedisPipeline struct {
	pipeline *redis.Pipeline
}

// RedisClientOptions are Redis client options.
type RedisClientOptions struct {
	Network            string
	Addr               string
	Dialer             func() (net.Conn, error)
	Password           string
	DB                 int
	MaxRetries         int
	DialTimeout        time.Duration
	ReadTimeout        time.Duration
	WriteTimeout       time.Duration
	PoolSize           int
	PoolTimeout        time.Duration
	IdleTimeout        time.Duration
	IdleCheckFrequency time.Duration
	ReadOnly           bool
}

// RedisClusterOptions are Redis cluster options.
type RedisClusterOptions struct {
	Addrs              []string
	MaxRedirects       int
	ReadOnly           bool
	RouteByLatency     bool
	Password           string
	DialTimeout        time.Duration
	ReadTimeout        time.Duration
	WriteTimeout       time.Duration
	PoolSize           int
	PoolTimeout        time.Duration
	IdleTimeout        time.Duration
	IdleCheckFrequency time.Duration
}

// ----------------------------------------------------------------------------
// Store
// ----------------------------------------------------------------------------

// RedisStore is the Redis implementation of KVStore.
type RedisStore struct {
	client     RedisClient
	expiration time.Duration
}

// Get returns value for the given key.
func (r *RedisStore) Get(key string) (interface{}, error) {
	cmd := redis.NewCmd("get", key)

	if err := r.client.Process(cmd); err != nil {
		if err == redis.Nil {
			return nil, nil
		}

		return nil, err
	}

	return cmd.Val(), cmd.Err()
}

// MGet returns map of key, value for a list of keys.
func (r *RedisStore) MGet(keys []string) (map[string]interface{}, error) {
	values, err := r.client.MGet(keys...).Result()

	newValues := make(map[string]interface{}, len(keys))

	for k, v := range keys {
		value := values[k]
		if err != nil {
			return nil, err
		}

		newValues[v] = value
	}
	return newValues, nil
}
{'fraction_non_alphanumeric': 0.1837157425111536, 'fraction_numerical': 0.00031867431485022306, 'mean_word_length': 2.0951676528599608, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '544138', 'n_tokens_mistral': 1824, 'n_tokens_neox': 1793, 'n_words': 519}