text:
"""
4. Many-to-one relationships

To define a many-to-one relationship, use ``ForeignKey()``.
"""

from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()

    def __unicode__(self):
        return u"%s %s" % (self.first_name, self.last_name)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter)

    def __unicode__(self):
        return self.headline

    class Meta:
        ordering = ('headline',)

__test__ = {'API_TESTS':"""
# Create a few Reporters.
>>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> r.save()

>>> r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')
>>> r2.save()

# Create an Article.
>>> from datetime import datetime
>>> a = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter=r)
>>> a.save()

>>> a.reporter.id
1

>>> a.reporter
<Reporter: John Smith>

# Article objects have access to their related Reporter objects.
>>> r = a.reporter

# These are strings instead of unicode strings because that's what was used in
# the creation of this reporter (and we haven't refreshed the data from the
# database, which always returns unicode strings).
>>> r.first_name, r.last_name
('John', 'Smith')

# Create an Article via the Reporter object.
>>> new_article = r.article_set.create(headline="John's second story", pub_date=datetime(2005, 7, 29))
>>> new_article
<Article: John's second story>
>>> new_article.reporter.id
1

# Create a new article, and add it to the article set.
>>> new_article2 = Article(headline="Paul's story", pub_date=datetime(2006, 1, 17))
>>> r.article_set.add(new_article2)
>>> new_article2.reporter.id
1
>>> r.article_set.all()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]

# Add the same article to a different article set - check that it moves.
>>> r2.article_set.add(new_article2)
>>> new_article2.reporter.id
2

# Adding an object of the wrong type raises TypeError
>>> r.article_set.add(r2)
Traceback (most recent call last):
...
TypeError: 'Article' instance expected

>>> r.article_set.all()
[<Article: John's second story>, <Article: This is a test>]
>>> r2.article_set.all()
[<Article: Paul's story>]

# Assign the article to the reporter directly using the descriptor
>>> new_article2.reporter = r
>>> new_article2.save()
>>> new_article2.reporter
<Reporter: John Smith>
>>> new_article2.reporter.id
1
>>> r.article_set.all()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]
>>> r2.article_set.all()
[]

# Set the article back again using set descriptor.
>>> r2.article_set = [new_article, new_article2]
>>> r.article_set.all()
[<Article: This is a test>]
>>> r2.article_set.all()
[<Article: John's second story>, <Article: Paul's story>]

# Funny case - assignment notation can only go so far; because the
# ForeignKey cannot be null, existing members of the set must remain
>>> r.article_set = [new_article]
>>> r.article_set.all()
[<Article: John's second story>, <Article: This is a test>]
>>> r2.article_set.all()
[<Article: Paul's story>]

# Reporter cannot be null - there should not be a clear or remove method
>>> hasattr(r2.article_set, 'remove')
False
>>> hasattr(r2.article_set, 'clear')
False

# Reporter objects have access to their related Article objects.
>>> r.article_set.all()
[<Article: John's second story>, <Article: This is a test>]

>>> r.article_set.filter(headline__startswith='This')
[<Article: This is a test>]

>>> r.article_set.count()
2

>>> r2.article_set.count()
1

# Get articles by id
>>> Article.objects.filter(id__exact=1)
[<Article: This is a test>]
>>> Article.objects.filter(pk=1)
[<Article: This is a test>]

# Query on an article property
>>> Article.objects.filter(headline__startswith='This')
[<Article: This is a test>]

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want. There's no limit.
# Find all Articles for any Reporter whose first name is "John".
>>> Article.objects.filter(reporter__first_name__exact='John')
[<Article: John's second story>, <Article: This is a test>]

# Check that implied __exact also works
>>> Article.objects.filter(reporter__first_name='John')
[<Article: John's second story>, <Article: This is a test>]

# Query twice over the related field.
>>> Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith')
[<Article: John's second story>, <Article: This is a test>]

# The underlying query only makes one join when a related table is referenced twice.
>>> queryset = Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith')
>>> sql = queryset.query.get_compiler(queryset.db).as_sql()[0]
>>> sql.count('INNER JOIN')
1

# The automatically joined table has a predictable name.
>>> Article.objects.filter(reporter__first_name__exact='John').extra(where=["many_to_one_reporter.last_name='Smith'"])
[<Article: John's second story>, <Article: This is a test>]

# And should work fine with the unicode that comes out of
# forms.Form.cleaned_data
>>> Article.objects.filter(reporter__first_name__exact='John').extra(where=["many_to_one_reporter.last_name='%s'" % u'Smith'])
[<Article: John's second story>, <Article: This is a test>]

# Find all Articles for the Reporter whose ID is 1.
# Use direct ID check, pk check, and object comparison
>>> Article.objects.filter(reporter__id__exact=1)
[<Article: John's second story>, <Article: This is a test>]
>>> Article.objects.filter(reporter__pk=1)
[<Article: John's second story>, <Article: This is a test>]
>>> Article.objects.filter(reporter=1)
[<Article: John's second story>, <Article: This is a test>]
>>> Article.objects.filter(reporter=r)
[<Article: John's second story>, <Article: This is a test>]

>>> Article.objects.filter(reporter__in=[1,2]).distinct()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]
>>> Article.objects.filter(reporter__in=[r,r2]).distinct()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]

# You can also use a queryset instead of a literal list of instances.
# The queryset must be reduced to a list of values using values(),
# then converted into a query
>>> Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John').values('pk').query).distinct()
[<Article: John's second story>, <Article: This is a test>]

# You need two underscores between "reporter" and "id" -- not one.
>>> Article.objects.filter(reporter_id__exact=1)
Traceback (most recent call last):
    ...
FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter

# You need to specify a comparison clause
>>> Article.objects.filter(reporter_id=1)
Traceback (most recent call last):
    ...
FieldError: Cannot resolve keyword 'reporter_id' into field. Choices are: headline, id, pub_date, reporter

# You can also instantiate an Article by passing
# the Reporter's ID instead of a Reporter object.
>>> a3 = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter_id=r.id)
>>> a3.save()
>>> a3.reporter.id
1
>>> a3.reporter
<Reporter: John Smith>

# Similarly, the reporter ID can be a string.
>>> a4 = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter_id="1")
>>> a4.save()
>>> a4.reporter
<Reporter: John Smith>

# Reporters can be queried
>>> Reporter.objects.filter(id__exact=1)
[<Reporter: John Smith>]
>>> Reporter.objects.filter(pk=1)
[<Reporter: John Smith>]
>>> Reporter.objects.filter(first_name__startswith='John')
[<Reporter: John Smith>]

# Reporters can query in opposite direction of ForeignKey definition
>>> Reporter.objects.filter(article__id__exact=1)
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article__pk=1)
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article=1)
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article=a)
[<Reporter: John Smith>]

>>> Reporter.objects.filter(article__in=[1,4]).distinct()
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article__in=[1,a3]).distinct()
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article__in=[a,a3]).distinct()
[<Reporter: John Smith>]

>>> Reporter.objects.filter(article__headline__startswith='This')
[<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]
>>> Reporter.objects.filter(article__headline__startswith='This').distinct()
[<Reporter: John Smith>]

# Counting in the opposite direction works in conjunction with distinct()
>>> Reporter.objects.filter(article__headline__startswith='This').count()
3
>>> Reporter.objects.filter(article__headline__startswith='This').distinct().count()
1

# Queries can go round in circles.
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John')
[<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct()
[<Reporter: John Smith>]
>>> Reporter.objects.filter(article__reporter__exact=r).distinct()
[<Reporter: John Smith>]

# Regression for #12876 -- Model methods that include queries that
# recursive don't cause recursion depth problems under deepcopy.
>>> r.cached_query = Article.objects.filter(reporter=r)
>>> from copy import deepcopy
>>> deepcopy(r)
<Reporter: John Smith>

# Check that implied __exact also works.
>>> Reporter.objects.filter(article__reporter=r).distinct()
[<Reporter: John Smith>]

# It's possible to use values() calls across many-to-one relations. (Note, too, that we clear the ordering here so as not to drag the 'headline' field into the columns being used to determine uniqueness.)
>>> d = {'reporter__first_name': u'John', 'reporter__last_name': u'Smith'}
>>> list(Article.objects.filter(reporter=r).distinct().order_by().values('reporter__first_name', 'reporter__last_name')) == [d]
True

# If you delete a reporter, his articles will be deleted.
>>> Article.objects.all()
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
>>> Reporter.objects.order_by('first_name')
[<Reporter: John Smith>, <Reporter: Paul Jones>]
>>> r2.delete()
>>> Article.objects.all()
[<Article: John's second story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
>>> Reporter.objects.order_by('first_name')
[<Reporter: John Smith>]

# You can delete using a JOIN in the query.
>>> Reporter.objects.filter(article__headline__startswith='This').delete()
>>> Reporter.objects.all()
[]
>>> Article.objects.all()
[]

# Check that Article.objects.select_related().dates() works properly when
# there are multiple Articles with the same date but different foreign-key
# objects (Reporters).
>>> r1 = Reporter.objects.create(first_name='Mike', last_name='Royko', email='royko@suntimes.com')
>>> r2 = Reporter.objects.create(first_name='John', last_name='Kass', email='jkass@tribune.com')
>>> a1 = Article.objects.create(headline='First', pub_date=datetime(1980, 4, 23), reporter=r1)
>>> a2 = Article.objects.create(headline='Second', pub_date=datetime(1980, 4, 23), reporter=r2)
>>> Article.objects.select_related().dates('pub_date', 'day')
[datetime.datetime(1980, 4, 23, 0, 0)]
>>> Article.objects.select_related().dates('pub_date', 'month')
[datetime.datetime(1980, 4, 1, 0, 0)]
>>> Article.objects.select_related().dates('pub_date', 'year')
[datetime.datetime(1980, 1, 1, 0, 0)]
"""}


text:
package com.amazonaws.services.elasticsearch.model;

import java.io.Serializable;

/**
 *

 * The current status of an Elasticsearch domain.
 *

 */
public class ElasticsearchDomainStatus implements Serializable, Cloneable {

    /**
     *

     * The unique identifier for the specified Elasticsearch domain.
     *

     */
    private String domainId;
    /**
     *

     * The name of an Elasticsearch domain. Domain names are unique across the
     * domains owned by an account within an AWS region. Domain names start with
     * a letter or number and can contain the following characters: a-z
     * (lowercase), 0-9, and - (hyphen).
     *

     */
    private String domainName;
    /**
     *

     * The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS Identity
     * and Access Management for more information.
     *

     */
    private String aRN;
    /**
     *

     * The domain creation status. True if the creation of an
     * Elasticsearch domain is complete. False if domain creation
     * is still in progress.
     *

     */
    private Boolean created;
    /**
     *

     * The domain deletion status. True if a delete request has
     * been received for the domain but resource cleanup is still in progress.
     * False if the domain has not been deleted. Once domain
     * deletion is complete, the status of the domain is no longer returned.
     *

     */
    private Boolean deleted;
    /**
     *

     * The Elasticsearch domain endpoint that you use to submit index and search
     * requests.
     *

     */
    private String endpoint;
    /**
     *

     * The status of the Elasticsearch domain configuration. True
     * if Amazon Elasticsearch Service is processing configuration changes.
     * False if the configuration is active.
     *

     */
    private Boolean processing;
    /**
     *

     * The type and number of instances in the domain cluster.
     *

     */
    private ElasticsearchClusterConfig elasticsearchClusterConfig;
    /**
     *

     * The EBSOptions for the specified domain. See Configuring EBS-based Storage for more information.
     *

     */
    private EBSOptions eBSOptions;
    /**
     *

     * IAM access policy as a JSON-formatted string.
     *

     */
    private String accessPolicies;
    /**
     *

     * Specifies the status of the SnapshotOptions
     *

     */
    private SnapshotOptions snapshotOptions;
    /**
     *

     * Specifies the status of the AdvancedOptions
     *

     */
    private java.util.Map<String, String> advancedOptions;

    /**
     *

     * The unique identifier for the specified Elasticsearch domain.
     *

     *
     * @param domainId
     *        The unique identifier for the specified Elasticsearch domain.
     */
    public void setDomainId(String domainId) {
        this.domainId = domainId;
    }

    /**
     *

     * The unique identifier for the specified Elasticsearch domain.
     *

     *
     * @return The unique identifier for the specified Elasticsearch domain.
     */
    public String getDomainId() {
        return this.domainId;
    }

    /**
     *

     * The unique identifier for the specified Elasticsearch domain.
     *

     *
     * @param domainId
     *        The unique identifier for the specified Elasticsearch domain.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withDomainId(String domainId) {
        setDomainId(domainId);
        return this;
    }

    /**
     *

     * The name of an Elasticsearch domain. Domain names are unique across the
     * domains owned by an account within an AWS region. Domain names start with
     * a letter or number and can contain the following characters: a-z
     * (lowercase), 0-9, and - (hyphen).
     *

     *
     * @param domainName
     *        The name of an Elasticsearch domain. Domain names are unique
     *        across the domains owned by an account within an AWS region.
     *        Domain names start with a letter or number and can contain the
     *        following characters: a-z (lowercase), 0-9, and - (hyphen).
     */
    public void setDomainName(String domainName) {
        this.domainName = domainName;
    }

    /**
     *

     * The name of an Elasticsearch domain. Domain names are unique across the
     * domains owned by an account within an AWS region. Domain names start with
     * a letter or number and can contain the following characters: a-z
     * (lowercase), 0-9, and - (hyphen).
     *

     *
     * @return The name of an Elasticsearch domain. Domain names are unique
     *         across the domains owned by an account within an AWS region.
     *         Domain names start with a letter or number and can contain the
     *         following characters: a-z (lowercase), 0-9, and - (hyphen).
     */
    public String getDomainName() {
        return this.domainName;
    }

    /**
     *

     * The name of an Elasticsearch domain. Domain names are unique across the
     * domains owned by an account within an AWS region. Domain names start with
     * a letter or number and can contain the following characters: a-z
     * (lowercase), 0-9, and - (hyphen).
     *

     *
     * @param domainName
     *        The name of an Elasticsearch domain. Domain names are unique
     *        across the domains owned by an account within an AWS region.
     *        Domain names start with a letter or number and can contain the
     *        following characters: a-z (lowercase), 0-9, and - (hyphen).
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withDomainName(String domainName) {
        setDomainName(domainName);
        return this;
    }

    /**
     *

     * The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS Identity
     * and Access Management for more information.
     *

     *
     * @param aRN
     *        The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS
     *        Identity and Access Management for more information.
     */
    public void setARN(String aRN) {
        this.aRN = aRN;
    }

    /**
     *

     * The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS Identity
     * and Access Management for more information.
     *

     *
     * @return The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS
     *         Identity and Access Management for more information.
     */
    public String getARN() {
        return this.aRN;
    }

    /**
     *

     * The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS Identity
     * and Access Management for more information.
     *

     *
     * @param aRN
     *        The Amazon resource name (ARN) of an Elasticsearch domain. See Identifiers for IAM Entities in Using AWS
     *        Identity and Access Management for more information.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withARN(String aRN) {
        setARN(aRN);
        return this;
    }

    /**
     *

     * The domain creation status. True if the creation of an
     * Elasticsearch domain is complete. False if domain creation
     * is still in progress.
     *

     *
     * @param created
     *        The domain creation status. True if the creation of
     *        an Elasticsearch domain is complete. False if domain
     *        creation is still in progress.
     */
    public void setCreated(Boolean created) {
        this.created = created;
    }

    /**
     *

     * The domain creation status. True if the creation of an
     * Elasticsearch domain is complete. False if domain creation
     * is still in progress.
     *

     *
     * @return The domain creation status. True if the creation of
     *         an Elasticsearch domain is complete. False if domain
     *         creation is still in progress.
     */
    public Boolean getCreated() {
        return this.created;
    }

    /**
     *

     * The domain creation status. True if the creation of an
     * Elasticsearch domain is complete. False if domain creation
     * is still in progress.
     *

     *
     * @param created
     *        The domain creation status. True if the creation of
     *        an Elasticsearch domain is complete. False if domain
     *        creation is still in progress.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withCreated(Boolean created) {
        setCreated(created);
        return this;
    }

    /**
     *

     * The domain creation status. True if the creation of an
     * Elasticsearch domain is complete. False if domain creation
     * is still in progress.
     *

     *
     * @return The domain creation status. True if the creation of
     *         an Elasticsearch domain is complete. False if domain
     *         creation is still in progress.
     */
    public Boolean isCreated() {
        return this.created;
    }

    /**
     *

     * The domain deletion status. True if a delete request has
     * been received for the domain but resource cleanup is still in progress.
     * False if the domain has not been deleted. Once domain
     * deletion is complete, the status of the domain is no longer returned.
     *

     *
     * @param deleted
     *        The domain deletion status. True if a delete request
     *        has been received for the domain but resource cleanup is still in
     *        progress. False if the domain has not been deleted.
     *        Once domain deletion is complete, the status of the domain is no
     *        longer returned.
     */
    public void setDeleted(Boolean deleted) {
        this.deleted = deleted;
    }

    /**
     *

     * The domain deletion status. True if a delete request has
     * been received for the domain but resource cleanup is still in progress.
     * False if the domain has not been deleted. Once domain
     * deletion is complete, the status of the domain is no longer returned.
     *

     *
     * @return The domain deletion status. True if a delete request
     *         has been received for the domain but resource cleanup is still in
     *         progress. False if the domain has not been deleted.
     *         Once domain deletion is complete, the status of the domain is no
     *         longer returned.
     */
    public Boolean getDeleted() {
        return this.deleted;
    }

    /**
     *

     * The domain deletion status. True if a delete request has
     * been received for the domain but resource cleanup is still in progress.
     * False if the domain has not been deleted. Once domain
     * deletion is complete, the status of the domain is no longer returned.
     *

     *
     * @param deleted
     *        The domain deletion status. True if a delete request
     *        has been received for the domain but resource cleanup is still in
     *        progress. False if the domain has not been deleted.
     *        Once domain deletion is complete, the status of the domain is no
     *        longer returned.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withDeleted(Boolean deleted) {
        setDeleted(deleted);
        return this;
    }

    /**
     *

     * The domain deletion status. True if a delete request has
     * been received for the domain but resource cleanup is still in progress.
     * False if the domain has not been deleted. Once domain
     * deletion is complete, the status of the domain is no longer returned.
     *

     *
     * @return The domain deletion status. True if a delete request
     *         has been received for the domain but resource cleanup is still in
     *         progress. False if the domain has not been deleted.
     *         Once domain deletion is complete, the status of the domain is no
     *         longer returned.
     */
    public Boolean isDeleted() {
        return this.deleted;
    }

    /**
     *

     * The Elasticsearch domain endpoint that you use to submit index and search
     * requests.
     *

     *
     * @param endpoint
     *        The Elasticsearch domain endpoint that you use to submit index and
     *        search requests.
     */
    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    /**
     *

     * The Elasticsearch domain endpoint that you use to submit index and search
     * requests.
     *

     *
     * @return The Elasticsearch domain endpoint that you use to submit index
     *         and search requests.
     */
    public String getEndpoint() {
        return this.endpoint;
    }

    /**
     *

     * The Elasticsearch domain endpoint that you use to submit index and search
     * requests.
     *

     *
     * @param endpoint
     *        The Elasticsearch domain endpoint that you use to submit index and
     *        search requests.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withEndpoint(String endpoint) {
        setEndpoint(endpoint);
        return this;
    }

    /**
     *

     * The status of the Elasticsearch domain configuration. True
     * if Amazon Elasticsearch Service is processing configuration changes.
     * False if the configuration is active.
     *

     *
     * @param processing
     *        The status of the Elasticsearch domain configuration.
     *        True if Amazon Elasticsearch Service is processing
     *        configuration changes. False if the configuration is
     *        active.
     */
    public void setProcessing(Boolean processing) {
        this.processing = processing;
    }

    /**
     *

     * The status of the Elasticsearch domain configuration. True
     * if Amazon Elasticsearch Service is processing configuration changes.
     * False if the configuration is active.
     *

     *
     * @return The status of the Elasticsearch domain configuration.
     *         True if Amazon Elasticsearch Service is processing
     *         configuration changes. False if the configuration is
     *         active.
     */
    public Boolean getProcessing() {
        return this.processing;
    }

    /**
     *

     * The status of the Elasticsearch domain configuration. True
     * if Amazon Elasticsearch Service is processing configuration changes.
     * False if the configuration is active.
     *

     *
     * @param processing
     *        The status of the Elasticsearch domain configuration.
     *        True if Amazon Elasticsearch Service is processing
     *        configuration changes. False if the configuration is
     *        active.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withProcessing(Boolean processing) {
        setProcessing(processing);
        return this;
    }

    /**
     *

     * The status of the Elasticsearch domain configuration. True
     * if Amazon Elasticsearch Service is processing configuration changes.
     * False if the configuration is active.
     *

     *
     * @return The status of the Elasticsearch domain configuration.
     *         True if Amazon Elasticsearch Service is processing
     *         configuration changes. False if the configuration is
     *         active.
     */
    public Boolean isProcessing() {
        return this.processing;
    }

    /**
     *

     * The type and number of instances in the domain cluster.
     *

     *
     * @param elasticsearchClusterConfig
     *        The type and number of instances in the domain cluster.
     */
    public void setElasticsearchClusterConfig(
            ElasticsearchClusterConfig elasticsearchClusterConfig) {
        this.elasticsearchClusterConfig = elasticsearchClusterConfig;
    }

    /**
     *

     * The type and number of instances in the domain cluster.
     *

     *
     * @return The type and number of instances in the domain cluster.
     */
    public ElasticsearchClusterConfig getElasticsearchClusterConfig() {
        return this.elasticsearchClusterConfig;
    }

    /**
     *

     * The type and number of instances in the domain cluster.
     *

     *
     * @param elasticsearchClusterConfig
     *        The type and number of instances in the domain cluster.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withElasticsearchClusterConfig(
            ElasticsearchClusterConfig elasticsearchClusterConfig) {
        setElasticsearchClusterConfig(elasticsearchClusterConfig);
        return this;
    }

    /**
     *

     * The EBSOptions for the specified domain. See Configuring EBS-based Storage for more information.
     *

     *
     * @param eBSOptions
     *        The EBSOptions for the specified domain. See Configuring EBS-based Storage for more
     *        information.
     */
    public void setEBSOptions(EBSOptions eBSOptions) {
        this.eBSOptions = eBSOptions;
    }

    /**
     *

     * The EBSOptions for the specified domain. See Configuring EBS-based Storage for more information.
     *

     *
     * @return The EBSOptions for the specified domain. See Configuring EBS-based Storage for more
     *         information.
     */
    public EBSOptions getEBSOptions() {
        return this.eBSOptions;
    }

    /**
     *

     * The EBSOptions for the specified domain. See Configuring EBS-based Storage for more information.
     *

     *
     * @param eBSOptions
     *        The EBSOptions for the specified domain. See Configuring EBS-based Storage for more
     *        information.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withEBSOptions(EBSOptions eBSOptions) {
        setEBSOptions(eBSOptions);
        return this;
    }

    /**
     *

     * IAM access policy as a JSON-formatted string.
     *

     *
     * @param accessPolicies
     *        IAM access policy as a JSON-formatted string.
     */
    public void setAccessPolicies(String accessPolicies) {
        this.accessPolicies = accessPolicies;
    }

    /**
     *

     * IAM access policy as a JSON-formatted string.
     *

     *
     * @return IAM access policy as a JSON-formatted string.
     */
    public String getAccessPolicies() {
        return this.accessPolicies;
    }

    /**
     *

     * IAM access policy as a JSON-formatted string.
     *

     *
     * @param accessPolicies
     *        IAM access policy as a JSON-formatted string.
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withAccessPolicies(String accessPolicies) {
        setAccessPolicies(accessPolicies);
        return this;
    }

    /**
     *

     * Specifies the status of the SnapshotOptions
     *

     *
     * @param snapshotOptions
     *        Specifies the status of the SnapshotOptions
     */
    public void setSnapshotOptions(SnapshotOptions snapshotOptions) {
        this.snapshotOptions = snapshotOptions;
    }

    /**
     *

     * Specifies the status of the SnapshotOptions
     *

     *
     * @return Specifies the status of the SnapshotOptions
     */
    public SnapshotOptions getSnapshotOptions() {
        return this.snapshotOptions;
    }

    /**
     *

     * Specifies the status of the SnapshotOptions
     *

     *
     * @param snapshotOptions
     *        Specifies the status of the SnapshotOptions
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withSnapshotOptions(
            SnapshotOptions snapshotOptions) {
        setSnapshotOptions(snapshotOptions);
        return this;
    }

    /**
     *

     * Specifies the status of the AdvancedOptions
     *

     *
     * @return Specifies the status of the AdvancedOptions
     */
    public java.util.Map<String, String> getAdvancedOptions() {
        return advancedOptions;
    }

    /**
     *

     * Specifies the status of the AdvancedOptions
     *

     *
     * @param advancedOptions
     *        Specifies the status of the AdvancedOptions
     */
    public void setAdvancedOptions(java.util.Map<String, String> advancedOptions) {
        this.advancedOptions = advancedOptions;
    }

    /**
     *

     * Specifies the status of the AdvancedOptions
     *

     *
     * @param advancedOptions
     *        Specifies the status of the AdvancedOptions
     * @return Returns a reference to this object so that method calls can be
     *         chained together.
     */
    public ElasticsearchDomainStatus withAdvancedOptions(
            java.util.Map<String, String> advancedOptions) {
        setAdvancedOptions(advancedOptions);
        return this;
    }

    public ElasticsearchDomainStatus addAdvancedOptionsEntry(String key,
            String value) {
        if (null == this.advancedOptions) {
            this.advancedOptions = new java.util.HashMap<String, String>();
        }
        if (this.advancedOptions.containsKey(key))
            throw new IllegalArgumentException("Duplicated keys ("
                    + key.toString() + ") are provided.");
        this.advancedOptions.put(key, value);
        return this;
    }

    /**
     * Removes all the entries added into AdvancedOptions. <p> Returns a
     * reference to this object so that method calls can be chained together.
     */
    public ElasticsearchDomainStatus clearAdvancedOptionsEntries() {
        this.advancedOptions = null;
        return this;
    }

    /**
     * Returns a string representation of this object; useful for testing and
     * debugging.
     *
     * @return A string representation of this object.
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        if (getDomainId() != null)
            sb.append("DomainId: " + getDomainId() + ",");
        if (getDomainName() != null)
            sb.append("DomainName: " + getDomainName() + ",");
        if (getARN() != null)
            sb.append("ARN: " + getARN() + ",");
        if (getCreated() != null)
            sb.append("Created: " + getCreated() + ",");
        if (getDeleted() != null)
            sb.append("Deleted: " + getDeleted() + ",");
        if (getEndpoint() != null)
            sb.append("Endpoint: " + getEndpoint() + ",");
        if (getProcessing() != null)
            sb.append("Processing: " + getProcessing() + ",");
        if (getElasticsearchClusterConfig() != null)
            sb.append("ElasticsearchClusterConfig: "
                    + getElasticsearchClusterConfig() + ",");
        if (getEBSOptions() != null)
            sb.append("EBSOptions: " + getEBSOptions() + ",");
        if (getAccessPolicies() != null)
            sb.append("AccessPolicies: " + getAccessPolicies() + ",");
        if (getSnapshotOptions() != null)
            sb.append("SnapshotOptions: " + getSnapshotOptions() + ",");
        if (getAdvancedOptions() != null)
            sb.append("AdvancedOptions: " + getAdvancedOptions());
        sb.append("}");
        return sb.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;

        if (obj instanceof ElasticsearchDomainStatus == false)
            return false;
        ElasticsearchDomainStatus other = (ElasticsearchDomainStatus) obj;
        if (other.getDomainId() == null ^ this.getDomainId() == null)
            return false;
        if (other.getDomainId() != null
                && other.getDomainId().equals(this.getDomainId()) == false)
            return false;
        if (other.getDomainName() == null ^ this.getDomainName() == null)
            return false;
        if (other.getDomainName() != null
                && other.getDomainName().equals(this.getDomainName()) == false)
            return false;
        if (other.getARN() == null ^ this.getARN() == null)
            return false;
        if (other.getARN() != null
                && other.getARN().equals(this.getARN()) == false)
            return false;
        if (other.getCreated() == null ^ this.getCreated() == null)
            return false;
        if (other.getCreated() != null
                && other.getCreated().equals(this.getCreated()) == false)
            return false;
        if (other.getDeleted() == null ^ this.getDeleted() == null)
            return false;
        if (other.getDeleted() != null
                && other.getDeleted().equals(this.getDeleted()) == false)
            return false;
        if (other.getEndpoint() == null ^ this.getEndpoint() == null)
            return false;
        if (other.getEndpoint() != null
                && other.getEndpoint().equals(this.getEndpoint()) == false)
            return false;
        if (other.getProcessing() == null ^ this.getProcessing() == null)
            return false;
        if (other.getProcessing() != null
                && other.getProcessing().equals(this.getProcessing()) == false)
            return false;
        if (other.getElasticsearchClusterConfig() == null
                ^ this.getElasticsearchClusterConfig() == null)
            return false;
        if (other.getElasticsearchClusterConfig() != null
                && other.getElasticsearchClusterConfig().equals(
                        this.getElasticsearchClusterConfig()) == false)
            return false;
        if (other.getEBSOptions() == null ^ this.getEBSOptions() == null)
            return false;
        if (other.getEBSOptions() != null
                && other.getEBSOptions().equals(this.getEBSOptions()) == false)
            return false;
        if (other.getAccessPolicies() == null
                ^ this.getAccessPolicies() == null)
            return false;
        if (other.getAccessPolicies() != null
                && other.getAccessPolicies().equals(this.getAccessPolicies()) == false)
            return false;
        if (other.getSnapshotOptions() == null
                ^ this.getSnapshotOptions() == null)
            return false;
        if (other.getSnapshotOptions() != null
                && other.getSnapshotOptions().equals(this.getSnapshotOptions()) == false)
            return false;
        if (other.getAdvancedOptions() == null
                ^ this.getAdvancedOptions() == null)
            return false;
        if (other.getAdvancedOptions() != null
                && other.getAdvancedOptions().equals(this.getAdvancedOptions()) == false)
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int hashCode = 1;

        hashCode = prime * hashCode
                + ((getDomainId() == null) ? 0 : getDomainId().hashCode());
        hashCode = prime * hashCode
                + ((getDomainName() == null) ? 0 : getDomainName().hashCode());
        hashCode = prime * hashCode
                + ((getARN() == null) ? 0 : getARN().hashCode());
        hashCode = prime * hashCode
                + ((getCreated() == null) ? 0 : getCreated().hashCode());
        hashCode = prime * hashCode
                + ((getDeleted() == null) ? 0 : getDeleted().hashCode());
        hashCode = prime * hashCode
                + ((getEndpoint() == null) ? 0 : getEndpoint().hashCode());
        hashCode = prime * hashCode
                + ((getProcessing() == null) ? 0 : getProcessing().hashCode());
        hashCode = prime
                * hashCode
                + ((getElasticsearchClusterConfig() == null) ? 0
                        : getElasticsearchClusterConfig().hashCode());
        hashCode = prime * hashCode
                + ((getEBSOptions() == null) ? 0 : getEBSOptions().hashCode());
        hashCode = prime
                * hashCode
                + ((getAccessPolicies() == null) ? 0 : getAccessPolicies()
                        .hashCode());
        hashCode = prime
                * hashCode
                + ((getSnapshotOptions() == null) ? 0 : getSnapshotOptions()
                        .hashCode());
        hashCode = prime
                * hashCode
                + ((getAdvancedOptions() == null) ? 0 : getAdvancedOptions()
                        .hashCode());
        return hashCode;
    }

    @Override
    public ElasticsearchDomainStatus clone() {
        try {
            return (ElasticsearchDomainStatus) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new IllegalStateException(
                    "Got a CloneNotSupportedException from Object.clone() "
                            + "even though we're Cloneable!", e);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
void f() throw(...) { }

namespace PR28080 {
struct S;           // expected-note {{forward declaration}}
#if __cplusplus >= 201703L
// expected-error@+3 {{ISO C++17 does not allow dynamic exception specifications}}
// expected-note@+2 {{use 'noexcept(false)' instead}}
#endif
void fn() throw(S); // expected-warning {{incomplete type}} expected-note{{previous declaration}}
void fn() throw();  // expected-warning {{does not match previous declaration}}
}

template <typename T> struct FooPtr {
  template <typename U> FooPtr(U *p) : m_pT(nullptr) {}

  template <>
      // FIXME: It would be better if this note pointed at the primary template
      // above.
      // expected-note@+1 {{previous declaration is here}}
  FooPtr(T *pInterface) throw() // expected-warning {{exception specification in declaration does not match previous declaration}}
      : m_pT(pInterface) {}

  T *m_pT;
};
struct Bar {};
template struct FooPtr<Bar>; // expected-note {{requested here}}


text:
// Copyright 2022 DeepMind Technologies Limited..
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "envlogger/backends/cc/riegeli_dataset_writer.h"

#include <algorithm>
#include <iterator>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "envlogger/backends/cc/episode_info.h"
#include "envlogger/backends/cc/riegeli_dataset_io_constants.h"
#include "envlogger/backends/cc/riegeli_shard_writer.h"
#include "envlogger/platform/filesystem.h"
#include "envlogger/platform/parse_text_proto.h"
#include "envlogger/platform/proto_testutil.h"
#include "envlogger/platform/riegeli_file_reader.h"
#include "envlogger/platform/test_macros.h"
#include "envlogger/proto/storage.pb.h"
#include "riegeli/records/record_reader.h"
#include "riegeli/records/record_writer.h"

namespace envlogger {
namespace {

using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::IsTrue;
using ::testing::Not;
using ::testing::SizeIs;
using ::testing::Value;

// A simple matcher to compare the output of RiegeliDatasetReader::Episode().
MATCHER_P2(EqualsEpisode, start_index, num_steps, "") {
  return Value(arg.start, start_index) && Value(arg.num_steps, num_steps);
}

// A specification for creating directories with some fictitious data.
struct TimestampDirSpec {
  struct StepSpec {
    // A step-specific payload.
    float payload;
    // Whether this step is the first step of a new episode.
    bool is_new_episode;
    // Episodic metadata.
    std::optional<Data> episode_metadata;
    // Whether to use a different payload type (other than Data).
    bool use_other_payload_type;
  };

  // The timestamp associated with this directory.
  // This influences the name of the directory.
  absl::Time timestamp;
  // List of steps to be inserted into this timestamp dir.
  std::vector<StepSpec> steps;
};

TEST(RiegeliDatasetWriterTest, EmptyTagDir) {
  const Data metadata;
  const int max_episodes_per_shard = 1000;
  RiegeliDatasetWriter writer;
  EXPECT_TRUE(absl::IsNotFound(
      writer.Init(/*data_dir=*/"", metadata, max_episodes_per_shard)));
}

TEST(RiegeliDatasetWriterTest, NonPositiveMaxEpisodesPerShard) {
  const std::string data_dir =
      file::JoinPath(getenv("TEST_TMPDIR"), "single_shard");
  const Data metadata;
  const int max_episodes_per_shard = -1;

  ENVLOGGER_EXPECT_OK(file::CreateDir(data_dir));
  {
    RiegeliDatasetWriter writer;
    ENVLOGGER_EXPECT_OK(
        writer.Init(data_dir, metadata, max_episodes_per_shard));
    // Write "lots" of episodes.
    for (int i = 0; i < 1000; ++i) {
      Data data;
      data.mutable_datum()->mutable_values()->add_float_values(i);
      writer.AddStep(data, /*is_new_episode=*/true);
    }
    writer.Flush();
  }

  // Check that there's only a single shard.
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto match_results,
                                 file::GetSubdirectories(data_dir));
  EXPECT_THAT(match_results, SizeIs(1));

  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(data_dir));
}

TEST(RiegeliDatasetWriterTest, PositiveMaxEpisodesPerShard) {
  const std::string data_dir =
      file::JoinPath(getenv("TEST_TMPDIR"), "multi_shard");
  const Data metadata;
  const int max_episodes_per_shard = 5;

  ENVLOGGER_EXPECT_OK(file::CreateDir(data_dir));
  {
    RiegeliDatasetWriter writer;
    ENVLOGGER_EXPECT_OK(
        writer.Init(data_dir, metadata, max_episodes_per_shard));
    // Write "lots" of episodes.
    for (int i = 0; i < 1000; ++i) {
      Data data;
      data.mutable_datum()->mutable_values()->add_float_values(i);
      writer.AddStep(data, /*is_new_episode=*/true);
    }
    writer.Flush();
  }

  // Check that there are many shards.
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto match_results,
                                 file::GetSubdirectories(data_dir));
  const int expected_num_shards = 1000 / max_episodes_per_shard;
  EXPECT_THAT(match_results, SizeIs(expected_num_shards))
      << "Expecting 1000/max_episodes_per_shard == 200 shards.";

  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(data_dir));
}

TEST(RiegeliDatasetWriterTest, EpisodeMetadata) {
  const std::string data_dir =
      file::JoinPath(getenv("TEST_TMPDIR"), "single_shard");
  const Data metadata;
  const int max_episodes_per_shard = -1;  // Single shard for entire trajectory.

  ENVLOGGER_EXPECT_OK(file::CreateDir(data_dir));
  const Data episode0_metadata =
      ParseTextProtoOrDie(R"pb(datum: { values: { int64_values: 7 } })pb");
  const Data episode2_metadata =
      ParseTextProtoOrDie(R"pb(datum: { values: { int64_values: 8 } })pb");
  {
    RiegeliDatasetWriter writer;
    ENVLOGGER_EXPECT_OK(
        writer.Init(data_dir, metadata, max_episodes_per_shard));
    // Write 30 identical steps and 3 episodes of 10 steps each.
    // The metadata we write is:
    // episode 0: int64(7)
    // episode 1: nothing (should be left at its default nullopt).
    // episode 2: int64(8).
    const Data step_data =
        ParseTextProtoOrDie(R"pb(datum: { values: { int64_values: 321 } })pb");
    // Setting episodic metadata before an episode is available should be
    // ignored.
    writer.SetEpisodeMetadata(ParseTextProtoOrDie(
        R"pb(datum: { values: { float_values: 3.14 } })pb"));
    for (int i = 0; i < 30; ++i) {
      if (i < 10) {  // Call during all steps of episode 0.
        writer.SetEpisodeMetadata(episode0_metadata);
      } else if (i > 20) {  // Set multiple times during episode 2.
        writer.SetEpisodeMetadata(episode2_metadata);
      }
      writer.AddStep(step_data, /*is_new_episode=*/i % 10 == 0);
    }
    writer.Flush();
  }

  // Get single shard.
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto match_results,
                                 file::GetSubdirectories(data_dir));
  EXPECT_THAT(match_results, SizeIs(1));
  const auto& shard_dir = match_results[0];

  // Open episode metadata file and read contents into vector.
  const std::string episode_metadata_riegeli_file =
      file::JoinPath(shard_dir, internal::kEpisodeMetadataFilename);
  riegeli::RecordReader episode_metadata_reader{
      RiegeliFileReader(episode_metadata_riegeli_file)};
  ENVLOGGER_EXPECT_OK(episode_metadata_reader.status());
  std::vector<Data> actual_episode_metadata;
  Data value;
  while (episode_metadata_reader.ReadRecord(value)) {
    actual_episode_metadata.push_back(value);
  }
  EXPECT_THAT(actual_episode_metadata,
              ElementsAre(EqualsProto(episode0_metadata),
                          // Second episode1 should have no metadata here.
                          EqualsProto(episode2_metadata)));

  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(data_dir));
}

// This test ensures that `writer_options` are not ignored and have an effect in
// the output (i.e. the file sizes of the output files are different).
TEST(RiegeliDatasetWriterTest, WriterOptionsAreForwarded) {
  // Write the same trajectory using two different writer options.
  auto write_trajectory = [](absl::string_view output_dir,
                             absl::string_view writer_options) {
    const Data metadata;
    const int max_episodes_per_shard = -1;

    ENVLOGGER_EXPECT_OK(file::CreateDir(output_dir));
    {
      RiegeliDatasetWriter writer;
      ENVLOGGER_EXPECT_OK(writer.Init(std::string(output_dir), metadata,
                                      max_episodes_per_shard,
                                      std::string(writer_options)));
      // Write some steps.
      for (int i = 0; i < 100; ++i) {
        Data data;
        data.mutable_datum()->mutable_values()->add_float_values(i);
        writer.AddStep(data, /*is_new_episode=*/true);
      }
      writer.Flush();
    }
  };
  const std::string writer_options1 =
      file::JoinPath(getenv("TEST_TMPDIR"), "writer_options1");
  const std::string writer_options2 =
      file::JoinPath(getenv("TEST_TMPDIR"), "writer_options2");
  write_trajectory(writer_options1, "brotli:9,chunk_size:10M");
  write_trajectory(writer_options2, "brotli:1,chunk_size:16K");

  // Read the sizes of kStepsFilename from both trajectories.
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto writer_options1_results,
                                 file::GetSubdirectories(writer_options1));
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto writer_options2_results,
                                 file::GetSubdirectories(writer_options2));
  EXPECT_THAT(writer_options1_results, SizeIs(1));  // Expecting a single shard.
  EXPECT_THAT(writer_options2_results, SizeIs(1));  // Expecting a single shard.
  const std::string writer_options1_fname =
      file::JoinPath(writer_options1_results[0], internal::kStepsFilename);
  const std::string writer_options2_fname =
      file::JoinPath(writer_options2_results[0], internal::kStepsFilename);
  const absl::StatusOr<int64_t> writer_options1_size =
      file::GetSize(writer_options1_fname);
  const absl::StatusOr<int64_t> writer_options2_size =
      file::GetSize(writer_options2_fname);

  // Verify that the sizes exist and that they're different.
  EXPECT_THAT(writer_options1_size.ok(), IsTrue());
  EXPECT_THAT(writer_options2_size.ok(), IsTrue());
  EXPECT_THAT(*writer_options1_size, Not(Eq(*writer_options2_size)));

  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(writer_options1));
  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(writer_options2));
}

TEST(RiegeliDatasetWriterTest, DataDirReuseShouldStillWork) {
  const std::string data_dir =
      file::JoinPath(getenv("TEST_TMPDIR"), "some_shard");
  const Data metadata;
  ENVLOGGER_EXPECT_OK(file::CreateDir(data_dir));

  // Write some episodes in `data_dir`.
  {
    RiegeliDatasetWriter writer;
    ENVLOGGER_EXPECT_OK(writer.Init(data_dir, metadata));
    for (int i = 0; i < 10; ++i) {
      Data data;
      data.mutable_datum()->mutable_values()->add_float_values(i);
      writer.AddStep(data, /*is_new_episode=*/true);
    }
    writer.Flush();
  }

  // Write more episodes in the same `data_dir`.
  {
    RiegeliDatasetWriter writer;
    ENVLOGGER_EXPECT_OK(writer.Init(data_dir, metadata));
    for (int i = 0; i < 10; ++i) {
      Data data;
      data.mutable_datum()->mutable_values()->add_float_values(i);
      writer.AddStep(data, /*is_new_episode=*/true);
    }
    writer.Flush();
  }

  // Check that there's a second shard.
  ENVLOGGER_ASSERT_OK_AND_ASSIGN(const auto match_results,
                                 file::GetSubdirectories(data_dir));
  EXPECT_THAT(match_results, SizeIs(2));

  ENVLOGGER_EXPECT_OK(file::RecursivelyDelete(data_dir));
}

}  // namespace
}  // namespace envlogger


text:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Patologia extends CI_Controller {

	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/login
	 *	- or -
	 * 		http://example.com/index.php/login/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 * @see https://codeigniter.com/user_guide/general/urls.html
	 */

	public function __construct()
    {
        parent::__construct();

        if (!$this->session->has_userdata('login') && ($this->uri->segment(1, 0) != '0' || $this->uri->segment(2, 0) != '0')) {
        	redirect(base_url());
        }
        /*
        if ($this->session->has_userdata('tipo_usuario') && $this->session->userdata('tipo_usuario') != "Administrador") {
        	redirect(base_url('Home'));
        }*/
    }

  	public function AgregarPatologia()
 	{
		$this->load->model('PatologiaModel');

 		$data = array("titulo" => "Agregar nueva patologia");

		//Si se envió una petición POST...
		if ($_SERVER["REQUEST_METHOD"] == "POST") {

            //Si los datos de registro son correctos...
			if ($this->ValidarPatologia($data, 0) === false) {
				//Si la patologia se agrega exitosamente a la base de datos...
	        	if ($this->PatologiaModel->AgregarPatologia()) {

    				set_cookie("message","La Patología '".$this->input->post('patologia')."' fue registrada exitosamente!...", time()+15);
					header("Location: ".base_url()."Patologia/ListarPatologias"); //controlador y metododo del controlador que carga la vista

				//Si hay error en la inserción
				}else{

					$data['mensaje'] = $this->db->error();
				}
			}

		}

		$this->CargarHeader();
        $this->load->view('patologias/FormularioRegistroPatologia', $data);
        $this->load->view('footer');
 	}

	public function ModificarPatologia($id_patologia = null)
	{
		$this->load->model('PatologiaModel');

		$data = array("titulo" => "Modificar datos de la Patologia");

		$cond = array(
				"where" => array(
					"MD5(concat('sismed',id))" => $id_patologia
					)
				);

		$result = $this->PatologiaModel->ExtraerPatologia($cond);
		//Si los registros encontrados son más de 0...
		if ($result->num_rows() > 0) {

			$data['patologia'] = $result->row_array(); // guarda lo que se trae de la bdd en la variable $data['patologia'] , como un arreglo asosiativo con el nombre de las columnas en la bdd
			//var_dump($data['patologia']);
			//Si se envía una petición POST...
			if ($_SERVER["REQUEST_METHOD"] == "POST") {

			  	if($this->ValidarPatologia($data, 1) === FALSE)
			  	{
				//var_dump($_POST);

					$condicion = array(
						"data" => array(
							"nombre" => $this->input->post('patologia'),
			     			"descripcion" => $this->input->post('descripcion')
							),
			            	"where" => array("MD5(concat('sismed',id))" => $id_patologia) // codifica y compara el campo id de la tabla patologia con el id que se envia desde el formulario
			            );
					//var_dump($condicion);
				//Si se realiza la modificación exitosamente...
					if ($this->PatologiaModel->ModificarPatologia($condicion)) {

						set_cookie("message","Datos de la patología '".$this->input->post('patologia')."' modificados exitosamente!...", time()+15);
						header("Location: ".base_url()."Patologia/ListarPatologias");

					//Si ocurre un error durante la modificación...
					}else{
						$data['mensaje'] = $this->db->error();
					}
				}

			}
		}

		$this->CargarHeader();
        $this->load->view('patologias/FormularioRegistroPatologia', $data);
        $this->load->view('footer');
	}

	public function EliminarPatologia()
	{
		$this->load->model('PatologiaModel');

		$id = $this->input->post('id');
		$action = $this->input->post('action');
		$condicion = array(
			'where' => array("MD5(concat('sismed',id))" => $id)
			);

		//Si la acción a realizar es 'habilitar'...
		if ($action == "habilitar") {
			$condicion['data'] = array('status' => true);

		//Si la acción a realizar es 'inhabilitar'...
		}else{
			$condicion['data'] = array('status' => false);
		}

		//Si la modificación se realiza con éxito...
		if ($this->PatologiaModel->ModificarPatologia($condicion)) {

			$data['result']  = true;
			$data['message'] = "Operación exitosa!... El listado se recargará en breve...";

		//Si ocurre un error durante la modificación...
		}else{
			$data['result']  = false;
			$data['message'] = "Error: Ha ocurrido un problema durante la eliminación.\n".$this->db->error();
		}

		echo json_encode($data);
	}

	public function ListarPatologias()
	{
		$this->load->model('PatologiaModel');

		$condicion = array(
			"order_by" => array("campo" => "id", "direccion" => "ASC")
			);

		$data = array();

		$result = $this->PatologiaModel->ExtraerPatologia($condicion);

		$data["patologias"] = $result;

		$this->CargarHeader();
        $this->load->view('patologias/ListarPatologias', $data);
        $this->load->view('footer');
	}

	/**
	* Verifica que los datos de la Patologia ingresados en el formulario de registro y modificación cumplan con las reglas de integridad
	*
	* @param mixed[] $data Arreglo con información que se enviará a la vista
	* @param integer $operación Valor numérico que identifica la acción que se realiza
	*		0 -> Registro de usuario
	*		1 -> Modificación de datos de usuario
	*
	* @return void|boolean
	*/
	public function ValidarPatologia($data, $operacion)
	{
		$validar_patologia = array('required','min_length[3]','max_length[50]','regex_match[/([0-9a-zA-ZáéíóúàèìòùÀÈÌÒÙÁÉÍÓÚñÑüÜ])+$/]');
		$mensaje_patologia = array(
	        	'min_length'    => 'La %s debe tener al menos 3 caracteres.',
	            'max_length'    => 'La %s debe tener máximo 50 caracteres.',
	            'regex_match'  	=> 'La %s no pueden contener caracteres especiales, sólo se permiten caracteres alfanumericos',
	            'required'   	=> 'Debe insertar un %s.'
	        );

		//Si la operación es un registro de patologia...
		if ($operacion == 0) {

			$validar_patologia[] = 'is_unique[patologia.nombre]';
			$mensaje_patologia['is_unique'] = 'La %s ya existe';

		}elseif ($operacion == 1 && isset($data['patologia']))  {

			//Si la patologia almacenada es diferente a la ingresada por formulario...
		 	if (strcmp($data['patologia']['nombre'], $_POST['patologia']) != 0) {

				$nombre_validacion[] = 'is_unique[patologia.nombre]';
				$nombre_respuestas['is_unique'] = 'La %s ya ha sido registrada anteriormente.';
			}
		}

		$this->form_validation->set_rules('patologia', 'Patología',$validar_patologia,$mensaje_patologia);

		$this->form_validation->set_rules(
		        'descripcion', 'Descripción', // el primero corresponde al nombre del campo del formulario y el segundo a el nombre que aparecera por pantalla en las validaciones
		        array('min_length[16]','max_length[255]'),
		        array(
		        	'min_length'    => 'La %s debe tener al menos 16 caracteres.',
		            'max_length'    => 'La %s debe tener máximo 255 caracteres.'

		        )
		);

		//Si algún dato es incorrecto...
		if ($this->form_validation->run() == FALSE) {

			$this->CargarHeader();
	        $this->load->view('patologias/FormularioRegistroPatologia', $data);
	        $this->load->view('footer');

		//Si los datos son correctos...
		}else{

			return false;
		}
	}

	/**
	 * Extrae de la base de datos las patologías registradas y las devuelve en un objeto JSON
	 *
	 * @return void
	 */
	public function ExtraerPatologia()
	{
		$this->load->model('PatologiaModel');

		/*
		if (isset($_POST["edit"]) && !empty($_POST["edit"])) {

			$condicion = array(
	            "where" => array("status" => TRUE),
	            "order_by" => array("campo" => "id", "direccion" => "ASC")
	            );

			$data = json_decode(stripslashes($_POST['edit']));

			foreach ($data->selected as $key => $patologia) {

				$condicion["wheres"][] = array("id !=" => $patologia->id);
			}
		}else*/
		if (isset($_POST["id_vacuna"]) && !empty($_POST["id_vacuna"])) {

			$condicion = array(
				"select" => "patologia.id",
	            "where" => array("patologia.status" => TRUE, "MD5(concat('sismed',vacuna_patologia.id_vacuna))" => $_POST["id_vacuna"]),
	            "order_by" => array("campo" => "patologia.id", "direccion" => "ASC")
	            );

			$condicion["join"] = array(
				"tabla" => "vacuna_patologia",
				"condicion" => "patologia.id = vacuna_patologia.id_patologia"
				);

			$result = $this->PatologiaModel->ExtraerPatologia($condicion);

			$condicion = array(
				"where" => array("status" => TRUE),
	            "order_by" => array("campo" => "id", "direccion" => "ASC")
	            );

			if ($result->num_rows() > 0) {

				foreach ($result->result_array() as $key => $row) {

					$where_not_in[] = $row["id"];
				}

				$condicion["where_not_in"] = array("campo" => "id", "data" => $where_not_in);
			}

		}else{

			$condicion = array(
	            "where" => array("status" => TRUE),
	            "order_by" => array("campo" => "id", "direccion" => "ASC")
	            );
		}

		$result = $this->PatologiaModel->ExtraerPatologia($condicion);

		echo json_encode($result->result());
		/*
		if (isset($_POST['id']) && !empty($_POST['id'])) {

			$condicion = array("where" => array('id !=' => $_POST['id']));

			$result = $this->PatologiaModel->ExtraerPatologia($condicion);
		}else{

			$result = $this->PatologiaModel->ExtraerPatologia(array());
		}*/

		//echo json_encode($result->result());
	}
}


text:
namespace print_dialog_cloud {

namespace {

// Limit is used only to allocate memory. Cloud has own small limit.
const int kMaxFileSize = 1024 * 1024 * 1024;

// Sets print data into Cloud Print widget.
class PrintDataSetter : public content::WebContentsObserver {
 public:
  PrintDataSetter(content::WebContents* web_contents,
                  scoped_refptr<base::RefCountedMemory> data,
                  const base::string16& print_job_title,
                  const base::string16& print_ticket,
                  const std::string& file_type)
      : WebContentsObserver(web_contents) {
    DCHECK_NE(data->size(), 0u);
    std::string base64_data;
    base::Base64Encode(base::StringPiece(data->front_as<char>(), data->size()),
                       &base64_data);
    std::string header("data:");
    header.append(file_type);
    header.append(";base64,");
    base64_data.insert(0, header);

    base::DictionaryValue message_data;
    message_data.SetString("type", "dataUrl");
    message_data.SetString("title", print_job_title);
    message_data.SetString("content", base64_data);
    std::string json_data;
    base::JSONWriter::Write(message_data, &json_data);
    message_data_ = L"cp-dialog-set-print-document::";
    message_data_.append(base::UTF8ToUTF16(json_data));
  }

 private:
  // Overridden from content::WebContentsObserver:
  void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override {
    GURL url = web_contents()->GetURL();
    if (cloud_devices::IsCloudPrintURL(url)) {
      base::string16 origin = base::UTF8ToUTF16(url.GetOrigin().spec());
      content::MessagePortProvider::PostMessageToFrame(web_contents(), origin,
                                                       origin, message_data_);
    }
  }

  void WebContentsDestroyed() override { delete this; }

  base::string16 message_data_;
  DISALLOW_COPY_AND_ASSIGN(PrintDataSetter);
};

void CreatePrintDialog(content::BrowserContext* browser_context,
                       const base::string16& print_job_title,
                       const base::string16& print_ticket,
                       const std::string& file_type,
                       scoped_refptr<base::RefCountedMemory> data) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  Profile* profile = Profile::FromBrowserContext(browser_context);
  chrome::ScopedTabbedBrowserDisplayer displayer(profile);
  GURL url = cloud_devices::GetCloudPrintRelativeURL("client/dialog.html");
  content::WebContents* web_contents =
      displayer.browser()->OpenURL(content::OpenURLParams(
          google_util::AppendGoogleLocaleParam(
              url, g_browser_process->GetApplicationLocale()),
          content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
          ui::PAGE_TRANSITION_AUTO_BOOKMARK, false));
  if (data && data->size()) {
    new PrintDataSetter(web_contents, data, print_job_title, print_ticket,
                        file_type);
  }
}

scoped_refptr<base::RefCountedMemory> ReadFile(
    const base::FilePath& path_to_file) {
  scoped_refptr<base::RefCountedMemory> data;
  int64_t file_size = 0;
  if (base::GetFileSize(path_to_file, &file_size) && file_size != 0) {
    if (file_size > kMaxFileSize) {
      DLOG(WARNING) << " print data file too large to reserve space";
      return data;
    }
    std::string file_data;
    file_data.reserve(static_cast<size_t>(file_size));
    if (base::ReadFileToString(path_to_file, &file_data))
      data = base::RefCountedString::TakeString(&file_data);
  }
  base::DeleteFile(path_to_file, false);
  return data;
}

void CreatePrintDialogForFile(content::BrowserContext* browser_context,
                              const base::FilePath& path_to_file,
                              const base::string16& print_job_title,
                              const base::string16& print_ticket,
                              const std::string& file_type) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      base::BindOnce(&ReadFile, path_to_file),
      base::BindOnce(&CreatePrintDialog, browser_context, print_job_title,
                     print_ticket, file_type));
}

}  // namespace

bool CreatePrintDialogFromCommandLine(Profile* profile,
                                      const base::CommandLine& command_line) {
  base::FilePath cloud_print_file =
      command_line.GetSwitchValuePath(switches::kCloudPrintFile);
  DCHECK(!cloud_print_file.empty());
  if (cloud_print_file.empty())
    return false;
  base::string16 print_job_title =
      command_line.GetSwitchValueNative(switches::kCloudPrintJobTitle);
  base::string16 print_job_print_ticket =
      command_line.GetSwitchValueNative(switches::kCloudPrintPrintTicket);
  std::string file_type =
      command_line.GetSwitchValueASCII(switches::kCloudPrintFileType);
  if (file_type.empty())
    file_type = "application/pdf";
  CreatePrintDialogForFile(profile, cloud_print_file, print_job_title,
                           print_job_print_ticket, file_type);
  return true;
}

}  // namespace print_dialog_cloud


text:
(function () {
    'use strict';

    // サービス登録
    angular
        .module('app')
        .factory('BookService', Service);

    // DI
    Service.$inject = ['$log', '$q', '$timeout', '$filter','$ncmb', 'UserService'];

    // サービス
    function Service($log, $q, $timeout, $filter, $ncmb, UserService) {
        // DB
        var BookClass = $ncmb.DataStore("book");

        return {
            'findAll': findAll,
            'findAllByUser': findAllByUser,
            'find': find,
            'uploadBook': uploadBook,
            'remove': remove,
            'update': update,
            'tradeComplete': tradeComplete,
        };

        // 書籍データ
        // var book = {
        //   id: 書籍ID
        //   name: 書籍名
        //   userId: ユーザID
        //   file: {
        //     fileId:  ファイルID,
        //     name:    ファイル名,
        //     dataUri: ファイルデータ
        //   }
        // }

        /**
         * dataURI(base64)をBlobに変換
         * @param {*} base64
         */
        function toBlob(base64) {
            var bin = atob(base64.replace(/^.*,/, ""));
            var buffer = new Uint8Array(bin.length);
            for (var i = 0; i < bin.length; i++) {
                buffer[i] = bin.charCodeAt(i);
            }
            try {
                var blob = new Blob([buffer.buffer], {
                    type: "image/jpeg"
                });
            } catch (e) {
                return false;
            }
            return blob;
        }

        /**
         * ファイル一覧取得
         */
        function findAll(schoolCode) {
            // 取得
            var deferred = $q.defer();
            var query = BookClass.include("user").order("createDate", true);
            if (schoolCode) {
                query = query.equalTo("schoolCode", schoolCode)
            }
            var loginUser = UserService.getCurrentUser();
            UserService.findAllBlockUserIds().then(function(blockUserIds) {
              query.fetchAll().then(function (results) {
                var books = [];
                var promises = [];
                angular.forEach(results, function(book) {
                  promises.push(
                    UserService.findAllBlockUserIdsByUser(book.user).then(function(blockedUserIds) {
                      if (blockUserIds.indexOf(book.user.objectId) < 0 && blockedUserIds.indexOf(loginUser.objectId) < 0) {
                        books.push(book);
                      }
                    })
                  );
                });
                $q.all(promises).then(function() {
                  var result = $filter('orderBy')(books, 'updateDate', true);
                  deferred.resolve(result);
                });
              });
            })
            .catch(function (error) {
                $log.error(error);
                deferred.reject(error);
            });
            return deferred.promise;
        }

        /**
         * 指定されたユーザの本を全件取得
         */
        function findAllByUser(user) {
            // 取得
            var deferred = $q.defer();
            BookClass
                .include("user")
                .equalTo("user.objectId", user.objectId)
                .order("createDate", true)
                .fetchAll().then(function (results) {
                    deferred.resolve(results);
                }).catch(function (error) {
                    $log.error(error);
                    deferred.reject(error);
                });
            return deferred.promise;
        }

        /**
         * 1件取得
         */
        function find(objectId) {
            // 取得
            var deferred = $q.defer();
            BookClass
                .include("user")
                .equalTo("objectId", objectId)
                .fetchAll().then(function (results) {
                    deferred.resolve(results[0]);
                }).catch(function (error) {
                    $log.error(error);
                    deferred.reject(error);
                });

            return deferred.promise;
        }

        /**
         * アップロード
         * @param {*} book
         */
        function uploadBook(book) {
            var deferred = $q.defer();

            // Data URL -> Blob
            //var imageUri = "data:image/jpeg;base64," + book.file.dataUrl;
            var blob = toBlob(book.file.dataUrl);
            var fileName = new Date().getTime().toString();

            // アップロード
            $ncmb.File.upload(fileName, blob).then(function (response) {
                var bookClass = new BookClass();
                var user = $ncmb.User.getCurrentUser();
                bookClass
                    .set("user", user)
                    .set("name", book.name)
                    .set("price", book.price)
                    .set("grade", book.grade)
                    .set("state", book.state)
                    .set("comment", book.comment)
                    .set("thumbnail", book.thumbnail)
                    .set("fileName", response.fileName)
                if (user.school && user.school.code) {
                    bookClass.set("schoolCode", user.school.code);
                    if (user.campus && user.campus.code) {
                        bookClass.set("campusCode", user.campus.code);
                    }
                }
                bookClass.save().then(function (bookClass) {
                    deferred.resolve(bookClass);
                }).catch(function (error) {
                    $log.error(error);
                    deferred.reject(error);
                });
            });
            return deferred.promise;
        }

        function update(book, objectId) {
            var deferred = $q.defer();
            var user = $ncmb.User.getCurrentUser();

            // 商品編集
            BookClass
                .equalTo("objectId", book.objectId)
                .fetchAll().then(function (results) {
                    var bookClass = results[0];
                    bookClass
                        //.set("user", user)
                        .set("name", book.name)
                        .set("schoolCode", user.school.code)
                        .set("campusCode", user.campus.code)
                        .set("price", book.price)
                        .set("grade", book.grade)
                        .set("state", book.state)
                        .set("comment", book.comment)
                        .set("fileName", book.fileName);

                    bookClass.update().then(function (bookClass) {
                        deferred.resolve(bookClass);
                    }).catch(function (error) {
                        $log.error(error);
                        deferred.reject(error);
                    });

                });
            return deferred.promise;
        }

        // 削除
        function remove(book) {
            $log.debug('BookService.remove(data)');

            // objectIDの一致するデータを削除
            var deferred = $q.defer();
            BookClass.equalTo("objectId", book.objectId).fetchAll().then(function (results) {
                var bookClass = results[0];
                deferred.resolve(bookClass.delete());
            }).catch(function (error) {
                deferred.reject(error);
            });
            return deferred.promise;
        }

        //取引完了関数。商品状態を取引完了(1)にする
        function tradeComplete(book) {
            var deferred = $q.defer();
            var user = $ncmb.User.getCurrentUser();
            BookClass
                .equalTo("objectId", book.objectId)
                .fetchAll().then(function (results) {
                    var bookClass = results[0];
                    bookClass
                        .set("state", 1);
                    bookClass.update().then(function (bookClass) {
                        deferred.resolve(bookClass);
                    }).catch(function (error) {
                        $log.error(error);
                        deferred.reject(error);
                    });
                });
        }
        // function bookDelete() {
        //     var deferred = $q.defer();
        //     BookClass.delete()
        //         .then(function (result) {
        //             console.log(result); // true
        //         })
        //         .catch(function (err) {
        //             // エラー処理
        //         });
        //     return deferred.promise;
        //     console.log("削除成功");
        // }

        // // ダウンロード
        // function downloadFile(fileId) {
        //     var deferred = $q.defer();
        //     $ncmb.File.download(fileId, 'blob').then(function (response) {
        //         deferred.resolve(response);
        //     });
        //     return deferred.promise;
        // }

        // // 削除
        // function deleteFile(fileId) {
        //     var deferred = $q.defer();
        //     $ncmb.File.delete(fileId).then(function (response) {
        //         deferred.resolve(response);
        //     });
        //     return deferred.promise;
        // }
    }
})();


text:
/*
 * Minio Cloud Storage, (C) 2016 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"hash/crc32"
	"path"
	"sync"
	"time"

	"github.com/tidwall/gjson"
)

// Returns number of errors that occurred the most (incl. nil) and the
// corresponding error value. N B when there is more than one error value that
// occurs maximum number of times, the error value returned depends on how
// golang's map orders keys. This doesn't affect correctness as long as quorum
// value is greater than or equal to simple majority, since none of the equally
// maximal values would occur quorum or more number of times.

func reduceErrs(errs []error, ignoredErrs []error) error {
	errorCounts := make(map[error]int)
	errs = errorsCause(errs)
	for _, err := range errs {
		if isErrIgnored(err, ignoredErrs) {
			continue
		}
		errorCounts[err]++
	}
	max := 0
	var errMax error
	for err, count := range errorCounts {
		if max < count {
			max = count
			errMax = err
		}
	}
	return traceError(errMax, errs...)
}

// Validates if we have quorum based on the errors related to disk only.
// Returns 'true' if we have quorum, 'false' if we don't.
func isDiskQuorum(errs []error, minQuorumCount int) bool {
	var count int
	errs = errorsCause(errs)
	for _, err := range errs {
		switch err {
		case errDiskNotFound, errFaultyDisk, errDiskAccessDenied:
			continue
		}
		count++
	}

	return count >= minQuorumCount
}

// Similar to 'len(slice)' but returns  the actual elements count
// skipping the unallocated elements.
func diskCount(disks []StorageAPI) int {
	diskCount := 0
	for _, disk := range disks {
		if disk == nil {
			continue
		}
		diskCount++
	}
	return diskCount
}

// hashOrder - hashes input key to return returns consistent
// hashed integer slice. Returned integer order is salted
// with an input key. This results in consistent order.
// NOTE: collisions are fine, we are not looking for uniqueness
// in the slices returned.
func hashOrder(key string, cardinality int) []int {
	if cardinality < 0 {
		// Returns an empty int slice for negative cardinality.
		return nil
	}
	nums := make([]int, cardinality)
	keyCrc := crc32.Checksum([]byte(key), crc32.IEEETable)

	start := int(uint32(keyCrc)%uint32(cardinality)) | 1
	for i := 1; i <= cardinality; i++ {
		nums[i-1] = 1 + ((start + i) % cardinality)
	}
	return nums
}

func parseXLStat(xlMetaBuf []byte) (statInfo, error) {
	// obtain stat info.
	stat := statInfo{}
	// fetching modTime.
	modTime, err := time.Parse(time.RFC3339, gjson.GetBytes(xlMetaBuf, "stat.modTime").String())
	if err != nil {
		return statInfo{}, err
	}
	stat.ModTime = modTime
	// obtain Stat.Size .
	stat.Size = gjson.GetBytes(xlMetaBuf, "stat.size").Int()
	return stat, nil
}

func parseXLVersion(xlMetaBuf []byte) string {
	return gjson.GetBytes(xlMetaBuf, "version").String()
}

func parseXLFormat(xlMetaBuf []byte) string {
	return gjson.GetBytes(xlMetaBuf, "format").String()
}

func parseXLRelease(xlMetaBuf []byte) string {
	return gjson.GetBytes(xlMetaBuf, "minio.release").String()
}

func parseXLErasureInfo(xlMetaBuf []byte) erasureInfo {
	erasure := erasureInfo{}
	erasureResult := gjson.GetBytes(xlMetaBuf, "erasure")
	// parse the xlV1Meta.Erasure.Distribution.
	disResult := erasureResult.Get("distribution").Array()

	distribution := make([]int, len(disResult))
	for i, dis := range disResult {
		distribution[i] = int(dis.Int())
	}
	erasure.Distribution = distribution

	erasure.Algorithm = erasureResult.Get("algorithm").String()
	erasure.DataBlocks = int(erasureResult.Get("data").Int())
	erasure.ParityBlocks = int(erasureResult.Get("parity").Int())
	erasure.BlockSize = erasureResult.Get("blockSize").Int()
	erasure.Index = int(erasureResult.Get("index").Int())
	// Pare xlMetaV1.Erasure.Checksum array.
	checkSumsResult := erasureResult.Get("checksum").Array()
	checkSums := make([]checkSumInfo, len(checkSumsResult))
	for i, checkSumResult := range checkSumsResult {
		checkSum := checkSumInfo{}
		checkSum.Name = checkSumResult.Get("name").String()
		checkSum.Algorithm = checkSumResult.Get("algorithm").String()
		checkSum.Hash = checkSumResult.Get("hash").String()
		checkSums[i] = checkSum
	}
	erasure.Checksum = checkSums

	return erasure
}

func parseXLParts(xlMetaBuf []byte) []objectPartInfo {
	// Parse the XL Parts.
	partsResult := gjson.GetBytes(xlMetaBuf, "parts").Array()
	partInfo := make([]objectPartInfo, len(partsResult))
	for i, p := range partsResult {
		info := objectPartInfo{}
		info.Number = int(p.Get("number").Int())
		info.Name = p.Get("name").String()
		info.ETag = p.Get("etag").String()
		info.Size = p.Get("size").Int()
		partInfo[i] = info
	}
	return partInfo
}

func parseXLMetaMap(xlMetaBuf []byte) map[string]string {
	// Get xlMetaV1.Meta map.
	metaMapResult := gjson.GetBytes(xlMetaBuf, "meta").Map()
	metaMap := make(map[string]string)
	for key, valResult := range metaMapResult {
		metaMap[key] = valResult.String()
	}
	return metaMap
}

// Constructs XLMetaV1 using `gjson` lib to retrieve each field.
func xlMetaV1UnmarshalJSON(xlMetaBuf []byte) (xlMetaV1, error) {
	xlMeta := xlMetaV1{}
	// obtain version.
	xlMeta.Version = parseXLVersion(xlMetaBuf)
	// obtain format.
	xlMeta.Format = parseXLFormat(xlMetaBuf)
	// Parse xlMetaV1.Stat .
	stat, err := parseXLStat(xlMetaBuf)
	if err != nil {
		return xlMetaV1{}, err
	}

	xlMeta.Stat = stat
	// parse the xlV1Meta.Erasure fields.
	xlMeta.Erasure = parseXLErasureInfo(xlMetaBuf)

	// Parse the XL Parts.
	xlMeta.Parts = parseXLParts(xlMetaBuf)
	// Get the xlMetaV1.Realse field.
	xlMeta.Minio.Release = parseXLRelease(xlMetaBuf)
	// parse xlMetaV1.
	xlMeta.Meta = parseXLMetaMap(xlMetaBuf)

	return xlMeta, nil
}

// read xl.json from the given disk, parse and return xlV1MetaV1.Parts.
func readXLMetaParts(disk StorageAPI, bucket string, object string) ([]objectPartInfo, error) {
	// Reads entire `xl.json`.
	xlMetaBuf, err := disk.ReadAll(bucket, path.Join(object, xlMetaJSONFile))
	if err != nil {
		return nil, traceError(err)
	}
	// obtain xlMetaV1{}.Partsusing `github.com/tidwall/gjson`.
	xlMetaParts := parseXLParts(xlMetaBuf)

	return xlMetaParts, nil
}

// read xl.json from the given disk and parse xlV1Meta.Stat and xlV1Meta.Meta using gjson.
func readXLMetaStat(disk StorageAPI, bucket string, object string) (statInfo, map[string]string, error) {
	// Reads entire `xl.json`.
	xlMetaBuf, err := disk.ReadAll(bucket, path.Join(object, xlMetaJSONFile))
	if err != nil {
		return statInfo{}, nil, traceError(err)
	}
	// obtain xlMetaV1{}.Meta using `github.com/tidwall/gjson`.
	xlMetaMap := parseXLMetaMap(xlMetaBuf)

	// obtain xlMetaV1{}.Stat using `github.com/tidwall/gjson`.
	xlStat, err := parseXLStat(xlMetaBuf)
	if err != nil {
		return statInfo{}, nil, traceError(err)
	}
	// Return structured `xl.json`.
	return xlStat, xlMetaMap, nil
}

// readXLMeta reads `xl.json` and returns back XL metadata structure.
func readXLMeta(disk StorageAPI, bucket string, object string) (xlMeta xlMetaV1, err error) {
	// Reads entire `xl.json`.
	xlMetaBuf, err := disk.ReadAll(bucket, path.Join(object, xlMetaJSONFile))
	if err != nil {
		return xlMetaV1{}, traceError(err)
	}
	// obtain xlMetaV1{} using `github.com/tidwall/gjson`.
	xlMeta, err = xlMetaV1UnmarshalJSON(xlMetaBuf)
	if err != nil {
		return xlMetaV1{}, traceError(err)
	}
	// Return structured `xl.json`.
	return xlMeta, nil
}

// Reads all `xl.json` metadata as a xlMetaV1 slice.
// Returns error slice indicating the failed metadata reads.
func readAllXLMetadata(disks []StorageAPI, bucket, object string) ([]xlMetaV1, []error) {
	errs := make([]error, len(disks))
	metadataArray := make([]xlMetaV1, len(disks))
	var wg = &sync.WaitGroup{}
	// Read `xl.json` parallelly across disks.
	for index, disk := range disks {
		if disk == nil {
			errs[index] = errDiskNotFound
			continue
		}
		wg.Add(1)
		// Read `xl.json` in routine.
		go func(index int, disk StorageAPI) {
			defer wg.Done()
			var err error
			metadataArray[index], err = readXLMeta(disk, bucket, object)
			if err != nil {
				errs[index] = err
				return
			}
		}(index, disk)
	}

	// Wait for all the routines to finish.
	wg.Wait()

	// Return all the metadata.
	return metadataArray, errs
}

// Return ordered partsMetadata depeinding on distribution.
func getOrderedPartsMetadata(distribution []int, partsMetadata []xlMetaV1) (orderedPartsMetadata []xlMetaV1) {
	orderedPartsMetadata = make([]xlMetaV1, len(partsMetadata))
	for index := range partsMetadata {
		blockIndex := distribution[index]
		orderedPartsMetadata[blockIndex-1] = partsMetadata[index]
	}
	return orderedPartsMetadata
}

// getOrderedDisks - get ordered disks from erasure distribution.
// returns ordered slice of disks from their actual distribution.
func getOrderedDisks(distribution []int, disks []StorageAPI) (orderedDisks []StorageAPI) {
	orderedDisks = make([]StorageAPI, len(disks))
	// From disks gets ordered disks.
	for index := range disks {
		blockIndex := distribution[index]
		orderedDisks[blockIndex-1] = disks[index]
	}
	return orderedDisks
}


text:
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_SPARSETRIANGULARSOLVER_H
#define EIGEN_SPARSETRIANGULARSOLVER_H

namespace Eigen {

namespace internal {

template<typename Lhs, typename Rhs, int Mode,
  int UpLo = (Mode & Lower)
           ? Lower
           : (Mode & Upper)
           ? Upper
           : -1,
  int StorageOrder = int(traits<Lhs>::Flags) & RowMajorBit>
struct sparse_solve_triangular_selector;

// forward substitution, row-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,RowMajor>
{
  typedef typename Rhs::Scalar Scalar;
  typedef evaluator<Lhs> LhsEval;
  typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
  static void run(const Lhs& lhs, Rhs& other)
  {
    LhsEval lhsEval(lhs);
    for(Index col=0 ; col<other.cols() ; ++col)
    {
      for(Index i=0; i<lhs.rows(); ++i)
      {
        Scalar tmp = other.coeff(i,col);
        Scalar lastVal(0);
        Index lastIndex = 0;
        for(LhsIterator it(lhsEval, i); it; ++it)
        {
          lastVal = it.value();
          lastIndex = it.index();
          if(lastIndex==i)
            break;
          tmp -= lastVal * other.coeff(lastIndex,col);
        }
        if (Mode & UnitDiag)
          other.coeffRef(i,col) = tmp;
        else
        {
          eigen_assert(lastIndex==i);
          other.coeffRef(i,col) = tmp/lastVal;
        }
      }
    }
  }
};

// backward substitution, row-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,RowMajor>
{
  typedef typename Rhs::Scalar Scalar;
  typedef evaluator<Lhs> LhsEval;
  typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
  static void run(const Lhs& lhs, Rhs& other)
  {
    LhsEval lhsEval(lhs);
    for(Index col=0 ; col<other.cols() ; ++col)
    {
      for(Index i=lhs.rows()-1 ; i>=0 ; --i)
      {
        Scalar tmp = other.coeff(i,col);
        Scalar l_ii(0);
        LhsIterator it(lhsEval, i);
        while(it && it.index()<i)
          ++it;
        if(!(Mode & UnitDiag))
        {
          eigen_assert(it && it.index()==i);
          l_ii = it.value();
          ++it;
        }
        else if (it && it.index() == i)
          ++it;
        for(; it; ++it)
        {
          tmp -= it.value() * other.coeff(it.index(),col);
        }

        if (Mode & UnitDiag)  other.coeffRef(i,col) = tmp;
        else                  other.coeffRef(i,col) = tmp/l_ii;
      }
    }
  }
};

// forward substitution, col-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,ColMajor>
{
  typedef typename Rhs::Scalar Scalar;
  typedef evaluator<Lhs> LhsEval;
  typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
  static void run(const Lhs& lhs, Rhs& other)
  {
    LhsEval lhsEval(lhs);
    for(Index col=0 ; col<other.cols() ; ++col)
    {
      for(Index i=0; i<lhs.cols(); ++i)
      {
        Scalar& tmp = other.coeffRef(i,col);
        if (tmp!=Scalar(0)) // optimization when other is actually sparse
        {
          LhsIterator it(lhsEval, i);
          while(it && it.index()<i)
            ++it;
          if(!(Mode & UnitDiag))
          {
            eigen_assert(it && it.index()==i);
            tmp /= it.value();
          }
          if (it && it.index()==i)
            ++it;
          for(; it; ++it)
            other.coeffRef(it.index(), col) -= tmp * it.value();
        }
      }
    }
  }
};

// backward substitution, col-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,ColMajor>
{
  typedef typename Rhs::Scalar Scalar;
  typedef evaluator<Lhs> LhsEval;
  typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
  static void run(const Lhs& lhs, Rhs& other)
  {
    LhsEval lhsEval(lhs);
    for(Index col=0 ; col<other.cols() ; ++col)
    {
      for(Index i=lhs.cols()-1; i>=0; --i)
      {
        Scalar& tmp = other.coeffRef(i,col);
        if (tmp!=Scalar(0)) // optimization when other is actually sparse
        {
          if(!(Mode & UnitDiag))
          {
            // TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements
            LhsIterator it(lhsEval, i);
            while(it && it.index()!=i)
              ++it;
            eigen_assert(it && it.index()==i);
            other.coeffRef(i,col) /= it.value();
          }
          LhsIterator it(lhsEval, i);
          for(; it && it.index()<i; ++it)
            other.coeffRef(it.index(), col) -= tmp * it.value();
        }
      }
    }
  }
};

} // end namespace internal

template<typename ExpressionType,unsigned int Mode>
template<typename OtherDerived>
void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(MatrixBase<OtherDerived>& other) const
{
  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
  eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));

  enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit };

  typedef typename internal::conditional<copy,
    typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::type OtherCopy;
  OtherCopy otherCopy(other.derived());

  internal::sparse_solve_triangular_selector<ExpressionType, typename internal::remove_reference<OtherCopy>::type, Mode>::run(derived().nestedExpression(), otherCopy);

  if (copy)
    other = otherCopy;
}

// pure sparse path

namespace internal {

template<typename Lhs, typename Rhs, int Mode,
  int UpLo = (Mode & Lower)
           ? Lower
           : (Mode & Upper)
           ? Upper
           : -1,
  int StorageOrder = int(Lhs::Flags) & (RowMajorBit)>
struct sparse_solve_triangular_sparse_selector;

// forward substitution, col-major
template<typename Lhs, typename Rhs, int Mode, int UpLo>
struct sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor>
{
  typedef typename Rhs::Scalar Scalar;
  typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
                                      typename traits<Rhs>::StorageIndex>::type StorageIndex;
  static void run(const Lhs& lhs, Rhs& other)
  {
    const bool IsLower = (UpLo==Lower);
    AmbiVector<Scalar,StorageIndex> tempVector(other.rows()*2);
    tempVector.setBounds(0,other.rows());

    Rhs res(other.rows(), other.cols());
    res.reserve(other.nonZeros());

    for(Index col=0 ; col<other.cols() ; ++col)
    {
      // FIXME estimate number of non zeros
      tempVector.init(.99/*float(other.col(col).nonZeros())/float(other.rows())*/);
      tempVector.setZero();
      tempVector.restart();
      for (typename Rhs::InnerIterator rhsIt(other, col); rhsIt; ++rhsIt)
      {
        tempVector.coeffRef(rhsIt.index()) = rhsIt.value();
      }

      for(Index i=IsLower?0:lhs.cols()-1;
          IsLower?i<lhs.cols():i>=0;
          i+=IsLower?1:-1)
      {
        tempVector.restart();
        Scalar& ci = tempVector.coeffRef(i);
        if (ci!=Scalar(0))
        {
          // find
          typename Lhs::InnerIterator it(lhs, i);
          if(!(Mode & UnitDiag))
          {
            if (IsLower)
            {
              eigen_assert(it.index()==i);
              ci /= it.value();
            }
            else
              ci /= lhs.coeff(i,i);
          }
          tempVector.restart();
          if (IsLower)
          {
            if (it.index()==i)
              ++it;
            for(; it; ++it)
              tempVector.coeffRef(it.index()) -= ci * it.value();
          }
          else
          {
            for(; it && it.index()<i; ++it)
              tempVector.coeffRef(it.index()) -= ci * it.value();
          }
        }
      }

      Index count = 0;
      // FIXME compute a reference value to filter zeros
      for (typename AmbiVector<Scalar,StorageIndex>::Iterator it(tempVector/*,1e-12*/); it; ++it)
      {
        ++ count;
//         std::cerr << "fill " << it.index() << ", " << col << "\n";
//         std::cout << it.value() << "  ";
        // FIXME use insertBack
        res.insert(it.index(), col) = it.value();
      }
//       std::cout << "tempVector.nonZeros() == " << int(count) << " / " << (other.rows()) << "\n";
    }
    res.finalize();
    other = res.markAsRValue();
  }
};

} // end namespace internal

template<typename ExpressionType,unsigned int Mode>
template<typename OtherDerived>
void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const
{
  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
  eigen_assert( (!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));

//   enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit };

//   typedef typename internal::conditional<copy,
//     typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::type OtherCopy;
//   OtherCopy otherCopy(other.derived());

  internal::sparse_solve_triangular_sparse_selector<ExpressionType, OtherDerived, Mode>::run(derived().nestedExpression(), other.derived());

//   if (copy)
//     other = otherCopy;
}

} // end namespace Eigen

#endif // EIGEN_SPARSETRIANGULARSOLVER_H


text:
const request = require('request');
const express = require('express'),
    router = express.Router();

router.get('/', (req, res) => {
    res.render('register/register.pug', {
        title: 'HackFSU 5 | Register'
    });
});

router.post('/', (req, res) => {

    // VERY IMPORTANT:
    // This will not work if body-parser is enabled
    // upstream.

    let host = req.app.get('api-host');
    let stream = req.pipe(request.post(host + '/api/hacker/register')).pipe(res);

});

module.exports = router;