text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>ChicagoRuby Expands to BLUE1647 and 1871 - RayHightower.com</title>
  <meta name="author" content="Raymond T. Hightower - Chicago Ruby on Rails & iOS Developer">

  <meta name="description" content="When smart people
challenge each other to grow,
great things happen.

~The ChicagoRuby Motto If you're a developer itchin' to ramp up your Ruby …">

  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="canonical" href="http://RayHightower.com/blog/2015/04/10/chicagoruby-blue1647-1871">
  <link href="/favicon.png" rel="icon">
  <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  <link href="/atom.xml" rel="alternate" title="RayHightower.com" type="application/atom+xml">

<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">

<link href='http://fonts.googleapis.com/css?family=Arvo:700' rel='stylesheet' type='text/css'>

  <hgroup>

RayHightower.com

Thoughts about Ruby, Rails, iOS, the Internet of Things, software development, and business growth.

</hgroup>

RSS

  <form action="/search" method="get">
  <fieldset role ="search">
    <input type="text" id="search-query" name="q" placeholder="Search" autocomplete="off" class="search" />
  </fieldset>
</form>

Home

Archives

Speaking

If

Contact

ChicagoRuby Expands to BLUE1647 and 1871

<time class='entry-date' datetime='2015-04-10T17:41:32-05:00'>April 10, 2015 </time>

When smart people

challenge each other to grow,

great things happen.

~The ChicagoRuby Motto

If you're a developer itchin' to ramp up your Ruby skills, Chicago is a great place to be. The local Ruby user group, ChicagoRuby, continues to expand in time, space, expertise, and numbers. The group is over 3,200 strong, with six events each month plus the annual WindyCityRails conference.

The newest locations on ChicagoRuby’s monthly list are BLUE1647 and 1871.

ChicagoRuby: BLUE1647

BLUE1647
BLUE 1647 is an amazing maker space on Chicago's South Side, in the Pilsen neighborhood. The leadership of BLUE1647 invited ChicagoRuby to host our first meeting in the space on March 19, 2015. The presenter, John Contreras of Matchup, took us through the nuances of Rails background processing.

Rebecca Miller-Webster of thoughtbot will present at our next BLUE1647 meeting on April 17, 2015.

Check the ChicagoRuby calendar for details and to RSVP.

ChicagoRuby: 1871

1871
1871 was an early player in Chicago’s startup incubator industry. Community leaders at 1871 invited ChicagoRuby to lead some Ruby-oriented sessions at the incubator. Marty Lavin will lead our first 1871 event on April 30, 2015.

Organizer Team

Eleven (yes, eleven!) organizers work in concert to make ChicagoRuby run well. Current members of the organizer team are:

Ginny Hendry – Started and co-organizes the ChicagoRuby Hack Nights.

Justin Love – Started in Elmhurst, acts as our liaison with the JavaScript community.

Alonda McCree – Manages downtown video and logistics overall.

Marty Lavin – Runs Elmhurst and leads intro sessions at 1871.

Sarah Cnota – ThoughtWorker, manages the downtown meetups.

LaToya Allen – Co-organizes the ChicagoRuby Hack Nights.

Doug Harman – Co-organizes ChicagoRuby: North Shore.

Stu Gerstein – Co-organizes ChicagoRuby: North Shore.

Bobby Reyes – Driving force behind ChicagoRuby’s activities at BLUE1647 and 1871.

Dexter Teng – ThoughtWorker and newest member of the organizer team.

Ray Hightower – author of this article.

ChicagoRuby excels because the work is shared amongst many people. Hats off to our Organizer Alumni too!

Something For You

As of this writing, ChicagoRuby manages six events per month. You are certain to find something that fits you.

ChicagoRuby: Elmhurst – The first ChicagoRuby location. Meeting space provided by one of our members, Lee DeForest of DeForest Group.

ChicagoRuby: Downtown – Currently at ThoughtWorks. Added when we merged with Chirb.

ChicagoRuby: Hack Night – Currently at Enova. Added when Ginny Hendry said “we should have hack nights”.

ChicagoRuby: North Shore – Added when Doug Harman and Stu Gerstein said “we should be on the North Shore”.

ChicagoRuby: BLUE1647 – Added when Bobby Reyes formed relationships at the BLUE1647 maker space.

ChicagoRuby: 1871 – Added when 1871 members asked ChicagoRuby to run some beginner-oriented sessions.

Exact dates and locations are on the ChicagoRuby calendar. Come out and collaborate with your fellow learning enthusiasts. You’ll be glad that you did.

Posted by Raymond T. Hightower - Chicago Ruby on Rails & iOS Developer

<time class='entry-date' datetime='2015-04-10T17:41:32-05:00'>April 10, 2015 </time>

    community

  Tweet

        « Amazon Dash and Instant Gratification

        pgcli - Command Line Interface for PostgreSQL »

Comments

Please enable JavaScript to view the comments powered by Disqus.

About

Raymond T. Hightower is a software developer, founder of WisdomGroup, organizer of ChicagoRuby, and producer of WindyCityRails & RubyCaribe. He is currently exploring parallelism and concurrency.

Observations

The best way to make dreams come true is to wake up.
 ~Mae C. Jemison

Tact is the art of making a point without making an enemy.
~Isaac Newton

Find a need and fulfill it. Successful businesses are founded on the needs of people.
~A. G. Gaston

It’s kind of fun to do the impossible.
~Walt Disney

If one ox could not do the job they did not try to grow a bigger ox, but used two oxen. When we need greater computer power, the answer is not to get a bigger computer, but to build systems of computers and operate them in parallel.
~Grace Hopper

A person with a new idea is a crank until the idea succeeds.
 ~Mark Twain

My over arching framework is 1) Pure appreciation. 2) Spend time with good people. 3) Leave the world a little better.
~Mellody Hobson

Everybody told me no at first, including my wife. I turned the nos into yeses and the disadvantages into advantages.
~John H.  Johnson

I would have been fired a hundred times at a company run by MBAs. But I never went into business to make money. I went… so that I could do interesting things that hadn’t been done before.
~Amar Bose

Don’t undertake a project unless it is manifestly important and nearly impossible.
~Edwin Land

Speaking

in5 hub Innovation Hub
in Dubai, UAE

DevNights at The Cribb
in Dubai, UAE

Rubyfuza
in Cape Town, South Africa

NYC Node JS Meetup
in New York, NY

Chicago Node.js
in Chicago, IL

CloudCamp Chicago - Developer Night
in Chicago, IL

LinuxBarbados
at University of the West Indies
at Cave Hill, Barbados

Flourish Open Source Conference
at University of Illinois at Chicago

Chicago RubyMotion at DevBootcamp
in Chicago, IL

Chippewa Valley Code Camp
in Eau Claire, WI

Aloha Ruby in Honolulu, HI

Magic Ruby in Orlando, FL

Social Media

				Twitter

				GitHub

				LinkedIn

				Vimeo

Blog Categories

arduino (2)

beaglebone black (8)

business (35)

community (38)

education (48)

environment of respect (3)

functional programming (1)

git (6)

high performance computing (8)

ios (13)

iot (13)

linux (15)

node (4)

objective-c (5)

openrov (13)

os x (13)

parallella (10)

rails (11)

raspberri pi (1)

raspberry pi (4)

ruby (27)

rubymotion (13)

solar (1)

ux (3)

vim (5)

xcode (5)

Featured Articles

Parallella Quick Start Guide

Citizen Science With OpenROV

Ruby on BeagleBone Black

Ruby on Raspberry Pi

Recursion and Memoization

How to Grow a User Group

Upgrading Ruby With RVM

Vim

I don’t always use a modal editor. But when I do, I use Vim.

  Copyright © 2015 - Raymond T. Hightower - Chicago Ruby on Rails & iOS Developer -
  Powered by Octopress


text:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace PlaylistManager.ViewModel.Other
{
    /// <summary>
    /// Class for communications between ViewModels
    /// Source: https://stackoverflow.com/a/23909882/5985593  && https://github.com/Yeah69/MessengerPattern/blob/master/Messenger.cs
    /// TODO: extend messenger key (second link)
    /// </summary>
    public class Messenger
    {
        protected class MessengerKey
        {
            public object Recipient { get; }
            public object Context { get; }
            public Type Type { get; }

            public MessengerKey(object _recipient, object _context, Type _type)
            {
                Recipient = _recipient;
                Context = _context;
                Type = _type;
            }

            /// <summary>
            /// Determines if the specified MessengerKey is the same to the current messengerkey
            /// </summary>
            /// <param name="_other"></param>
            /// <returns></returns>
            public bool Equals(MessengerKey _other)
            {
                if (ReferenceEquals(null, _other)) return false;
                if (ReferenceEquals(this, _other)) return true;

                return Equals(Recipient, _other.Recipient) && Equals(Context, _other.Context) && Equals(Context, _other.Type);
            }

            /// <summary>
            /// Determines if the specified MessengerKey is the same to the current messengerkey
            /// </summary>
            /// <param name="_obj"></param>
            /// <returns></returns>
            public override bool Equals(object _obj)
            {
                if (ReferenceEquals(null, _obj)) return false;
                if (ReferenceEquals(this, _obj)) return true;
                if (_obj.GetType() != GetType()) return false;

                return Equals((MessengerKey) _obj);
            }

            /// <summary>
            /// hash function
            /// </summary>
            /// <returns></returns>
            public override int GetHashCode()
            {
                unchecked
                {
                    var hashCode = Recipient?.GetHashCode() ?? 0;
                    hashCode = (hashCode * 397) ^ (Context?.GetHashCode() ?? 0);
                    hashCode = (hashCode * 397) ^ (Type?.GetHashCode() ?? 0);
                    return hashCode;
                }
            }

            public static bool operator ==(MessengerKey _left, MessengerKey _right)
            {
                return Equals(_left, _right);
            }

            public static bool operator !=(MessengerKey _left, MessengerKey _right)
            {
                return !Equals(_left, _right);
            }
        }

        #region Attributes

        private static Messenger instance;
        private static readonly object lockObject = new object();

        private static readonly ConcurrentDictionary<MessengerKey, object> dictionary = new ConcurrentDictionary<MessengerKey, object>();

        #endregion

        #region Properties

        public static Messenger Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (lockObject)
                    {
                        if (instance == null)
                        {
                            instance = new Messenger();
                        }
                    }
                }

                return instance;
            }
        }

        #endregion

        private Messenger()
        {
        }

        #region Register methods

        /// <summary>
        /// Registers a recipient for a type of message T.
        /// The action parameter will be executed when a corresponding message is send
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_recipient"></param>
        /// <param name="_action"></param>
        public void Register<T>(object _recipient, Action<T> _action)
        {
            Register(_recipient, _action, null);
        }

        /// <summary>
        /// Registers a recipient for a type of message T and a matching context.
        /// The action parameter will be executed when a corresponding message is send
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_recipient"></param>
        /// <param name="_action"></param>
        /// <param name="_context"></param>
        public void Register<T>(object _recipient, Action<T> _action, object _context)
        {
            var key = new MessengerKey(_recipient, _context, typeof(T));
            dictionary.TryAdd(key, _action);
        }

        /// <summary>
        /// Unregisters a messenger recipient completely.
        /// After this method is executed, the recipient will no longer receive any messages.
        /// </summary>
        /// <param name="_recipient"></param>
        public void Unregister<T>(object _recipient)
        {
            Unregister<T>(_recipient, null);
        }

        /// <summary>
        /// Unregisters a messenger recipient with a matching context completely.
        /// After this method is executed, the recipient will no longer receive any messages
        /// </summary>
        /// <param name="_recipient"></param>
        /// <param name="_context"></param>
        public void Unregister<T>(object _recipient, object _context)
        {
            object action;
            var key = new MessengerKey(_recipient, _context, typeof(T));
            dictionary.TryRemove(key, out action);
        }

        #endregion

        #region Send methods

        /// <summary>
        /// Sends a message to registered recipients.
        /// The message will reach all recipients that are registered for this message type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_message"></param>
        public void Send<T>(T _message)
        {
            Send(_message, null);
        }

        /// <summary>
        /// Sends a message to registered recipients.
        /// The message will reach all recipients that are registered for this message type and matching context.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_message"></param>
        /// <param name="_context"></param>
        public void Send<T>(T _message, object _context)
        {
            IEnumerable<KeyValuePair<MessengerKey, object>> result;

            if (_context == null)
            {
                result = from r in dictionary where r.Key.Context == null select r;
            }
            else
            {
                result = from r in dictionary where r.Key.Context != null && r.Key.Context.Equals(_context) select r;
            }

            foreach (var action in result.Select(x => x.Value).OfType<Action<T>>())
            {
                action(_message);
            }
        }

        #endregion
    }
}

redpajama_set_name: RedPajamaGithub


text:
<resources>
    <string name="app_name">500px Blurring View for Android</string>
</resources>


text:
recycling-fun-upsg
==================

A #upsg hackathon project


text:
import onnx_graphsurgeon as gs
import onnx

graph = gs.import_onnx(onnx.load("model.onnx"))

fake_node = [node for node in graph.nodes if node.op == "FakeNodeToRemove"][0]

# Get the input node of the fake node
# Node provides i() and o() functions that can optionally be provided an index (default is 0)
# These serve as convenience functions for the alternative, which would be to fetch the input/output
# tensor first, then fetch the input/output node of the tensor.
# For example, node.i() is equivalent to node.inputs[0].inputs[0]
inp_node = fake_node.i()

# Reconnect the input node to the output tensors of the fake node, so that the first identity
# node in the example graph now skips over the fake node.
inp_node.outputs = fake_node.outputs
fake_node.outputs.clear()

# Remove the fake node from the graph completely
graph.cleanup()
onnx.save(gs.export_onnx(graph), "removed.onnx")


text:
package org.apache.storm.kafka.spout.trident;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyList;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.kafka.clients.consumer.ConsumerRebalanceListener;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.TopicPartition;
import org.apache.storm.kafka.spout.KafkaSpoutConfig;
import org.apache.storm.kafka.spout.SpoutWithMockedConsumerSetupHelper;
import org.apache.storm.kafka.spout.config.builder.SingleTopicKafkaSpoutConfiguration;
import org.apache.storm.kafka.spout.internal.KafkaConsumerFactory;
import org.apache.storm.kafka.spout.subscription.ManualPartitioner;
import org.apache.storm.kafka.spout.subscription.TopicAssigner;
import org.apache.storm.kafka.spout.subscription.TopicFilter;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.trident.operation.TridentCollector;
import org.apache.storm.trident.topology.TransactionAttempt;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

public class KafkaTridentSpoutEmitterTest {

    @Rule
    public MockitoRule mockito = MockitoJUnit.rule();

    @Captor
    public ArgumentCaptor<Collection<TopicPartition>> assignmentCaptor;

    private final TopicPartitionSerializer tpSerializer = new TopicPartitionSerializer();

    @Test
    public void testGetOrderedPartitionsIsConsistent() {
        KafkaTridentSpoutEmitter<String, String> emitter = new KafkaTridentSpoutEmitter<>(
            SingleTopicKafkaSpoutConfiguration.createKafkaSpoutConfigBuilder(-1)
                .build(),
            mock(TopologyContext.class),
            mock(KafkaConsumerFactory.class), new TopicAssigner());

        Set<TopicPartition> allPartitions = new HashSet<>();
        int numPartitions = 10;
        for (int i = 0; i < numPartitions; i++) {
            allPartitions.add(new TopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, i));
        }
        List<Map<String, Object>> serializedPartitions = allPartitions.stream()
            .map(tp -> tpSerializer.toMap(tp))
            .collect(Collectors.toList());

        List<KafkaTridentSpoutTopicPartition> orderedPartitions = emitter.getOrderedPartitions(serializedPartitions);
        assertThat("Should contain all partitions", orderedPartitions.size(), is(allPartitions.size()));
        Collections.shuffle(serializedPartitions);
        List<KafkaTridentSpoutTopicPartition> secondGetOrderedPartitions = emitter.getOrderedPartitions(serializedPartitions);
        assertThat("Ordering must be consistent", secondGetOrderedPartitions, is(orderedPartitions));

        serializedPartitions.add(tpSerializer.toMap(new TopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, numPartitions)));
        List<KafkaTridentSpoutTopicPartition> orderedPartitionsWithNewPartition = emitter.getOrderedPartitions(serializedPartitions);
        orderedPartitionsWithNewPartition.remove(orderedPartitionsWithNewPartition.size() - 1);
        assertThat("Adding new partitions should not shuffle the existing ordering", orderedPartitionsWithNewPartition, is(orderedPartitions));
    }

    @Test
    public void testGetPartitionsForTask() {
        //Verify correct wrapping/unwrapping of partition and delegation of partition assignment
        ManualPartitioner partitionerMock = mock(ManualPartitioner.class);
        when(partitionerMock.getPartitionsForThisTask(any(), any()))
            .thenAnswer(invocation -> {
                List<TopicPartition> partitions = new ArrayList<>((List<TopicPartition>) invocation.getArguments()[0]);
                partitions.remove(0);
                return new HashSet<>(partitions);
            });

        KafkaTridentSpoutEmitter<String, String> emitter = new KafkaTridentSpoutEmitter<>(
            SingleTopicKafkaSpoutConfiguration.createKafkaSpoutConfigBuilder(mock(TopicFilter.class), partitionerMock, -1)
                .build(),
            mock(TopologyContext.class),
            mock(KafkaConsumerFactory.class), new TopicAssigner());

        List<KafkaTridentSpoutTopicPartition> allPartitions = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            allPartitions.add(new KafkaTridentSpoutTopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, i));
        }
        List<TopicPartition> unwrappedPartitions = allPartitions.stream()
            .map(kttp -> kttp.getTopicPartition())
            .collect(Collectors.toList());

        List<KafkaTridentSpoutTopicPartition> partitionsForTask = emitter.getPartitionsForTask(0, 2, allPartitions);
        verify(partitionerMock).getPartitionsForThisTask(eq(unwrappedPartitions), any(TopologyContext.class));
        allPartitions.remove(0);
        assertThat("Should have assigned all except the first partition to this task", new HashSet<>(partitionsForTask), is(new HashSet<>(allPartitions)));
    }

    @Test
    public void testAssignPartitions() {
        //Verify correct unwrapping of partitions and delegation of assignment
        KafkaConsumer<String, String> consumerMock = mock(KafkaConsumer.class);
        KafkaConsumerFactory<String, String> consumerFactory = spoutConfig -> consumerMock;
        TopicAssigner assignerMock = mock(TopicAssigner.class);

        KafkaTridentSpoutEmitter<String, String> emitter = new KafkaTridentSpoutEmitter<>(
            SingleTopicKafkaSpoutConfiguration.createKafkaSpoutConfigBuilder(-1)
                .build(),
            mock(TopologyContext.class),
            consumerFactory, assignerMock);

        List<KafkaTridentSpoutTopicPartition> allPartitions = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            allPartitions.add(new KafkaTridentSpoutTopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, i));
        }
        Set<TopicPartition> unwrappedPartitions = allPartitions.stream()
            .map(kttp -> kttp.getTopicPartition())
            .collect(Collectors.toSet());

        emitter.refreshPartitions(allPartitions);

        verify(assignerMock).assignPartitions(any(KafkaConsumer.class), eq(unwrappedPartitions), any(ConsumerRebalanceListener.class));
    }

    private Map<String, Object> doEmitBatchTest(KafkaConsumer<String, String> consumerMock, TridentCollector collectorMock, TopicPartition tp, long firstOffset, int numRecords, Map<String, Object> previousBatchMeta) {
        when(consumerMock.assignment()).thenReturn(Collections.singleton(tp));
        when(consumerMock.poll(anyLong())).thenReturn(new ConsumerRecords<>(Collections.singletonMap(
            tp, SpoutWithMockedConsumerSetupHelper.createRecords(tp, firstOffset, numRecords))));
        KafkaConsumerFactory<String, String> consumerFactory = spoutConfig -> consumerMock;

        KafkaTridentSpoutEmitter<String, String> emitter = new KafkaTridentSpoutEmitter<>(
            SingleTopicKafkaSpoutConfiguration.createKafkaSpoutConfigBuilder(-1)
                .setFirstPollOffsetStrategy(KafkaSpoutConfig.FirstPollOffsetStrategy.UNCOMMITTED_EARLIEST)
                .build(),
            mock(TopologyContext.class),
            consumerFactory, new TopicAssigner());

        TransactionAttempt txid = new TransactionAttempt(10L, 0);
        KafkaTridentSpoutTopicPartition kttp = new KafkaTridentSpoutTopicPartition(tp);
        return emitter.emitPartitionBatch(txid, collectorMock, kttp, previousBatchMeta);
    }

    @Test
    public void testEmitBatchWithNullMeta() {
        //Check that null meta makes the spout seek according to FirstPollOffsetStrategy, and that the returned meta is correct
        KafkaConsumer<String, String> consumerMock = mock(KafkaConsumer.class);
        TridentCollector collectorMock = mock(TridentCollector.class);
        TopicPartition tp = new TopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, 0);
        long firstOffset = 0;
        int numRecords = 10;
        Map<String, Object> batchMeta = doEmitBatchTest(consumerMock, collectorMock, tp, firstOffset, numRecords, null);

        InOrder inOrder = inOrder(consumerMock, collectorMock);
        inOrder.verify(consumerMock).seekToBeginning(Collections.singleton(tp));
        inOrder.verify(consumerMock).poll(anyLong());
        inOrder.verify(collectorMock, times(numRecords)).emit(anyList());
        KafkaTridentSpoutBatchMetadata deserializedMeta = KafkaTridentSpoutBatchMetadata.fromMap(batchMeta);
        assertThat("The batch should start at the first offset of the polled records", deserializedMeta.getFirstOffset(), is(firstOffset));
        assertThat("The batch should end at the last offset of the polled messages", deserializedMeta.getLastOffset(), is(firstOffset + numRecords - 1));
    }

    @Test
    public void testEmitBatchWithPreviousMeta() {
        //Check that non-null meta makes the spout seek according to the provided metadata, and that the returned meta is correct
        KafkaConsumer<String, String> consumerMock = mock(KafkaConsumer.class);
        TridentCollector collectorMock = mock(TridentCollector.class);
        TopicPartition tp = new TopicPartition(SingleTopicKafkaSpoutConfiguration.TOPIC, 0);
        long firstOffset = 50;
        int numRecords = 10;
        KafkaTridentSpoutBatchMetadata previousBatchMeta = new KafkaTridentSpoutBatchMetadata(0, firstOffset - 1);
        Map<String, Object> batchMeta = doEmitBatchTest(consumerMock, collectorMock, tp, firstOffset, numRecords, previousBatchMeta.toMap());

        InOrder inOrder = inOrder(consumerMock, collectorMock);
        inOrder.verify(consumerMock).seek(tp, firstOffset);
        inOrder.verify(consumerMock).poll(anyLong());
        inOrder.verify(collectorMock, times(numRecords)).emit(anyList());
        KafkaTridentSpoutBatchMetadata deserializedMeta = KafkaTridentSpoutBatchMetadata.fromMap(batchMeta);
        assertThat("The batch should start at the first offset of the polled records", deserializedMeta.getFirstOffset(), is(firstOffset));
        assertThat("The batch should end at the last offset of the polled messages", deserializedMeta.getLastOffset(), is(firstOffset + numRecords - 1));
    }

}


text:
package utils.helpers

import play.api.i18n.Lang
import views.html.helper.FieldConstructor

case class CarersTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.carersTemplate.f(_)(lang))
}

case class CheckTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.checkTemplate.f(_)(lang))
}

case class EmptyTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.emptyTemplate.f(_)(lang))
}

case class ShortFieldTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.shortFieldTemplate.f(_)(lang))
}

case class CurrencyTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.shortFieldCurrencyTemplate.f(_)(lang))
}

case class EligibilityTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.eligibilityTemplate.f(_)(lang))
}

case class CheckboxTemplate(lang: Lang) {
  implicit val fieldConstructor = FieldConstructor(views.html.helper.templates.checkboxTemplate.f(_)(lang))
}


text:
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <quic/state/OutstandingPacket.h>

#include <quic/codec/Types.h>
#include <quic/common/test/TestUtils.h>
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
#include <quic/server/state/ServerStateMachine.h>
#include <quic/state/QuicStateFunctions.h>
#include <quic/state/stream/StreamReceiveHandlers.h>
#include <quic/state/stream/StreamSendHandlers.h>
#include <quic/state/test/Mocks.h>
#include <chrono>
#include <cstdint>
#include <deque>

using namespace testing;

namespace quic::test {

bool verifyToAckImmediatelyAndZeroPacketsReceived(
    const QuicConnectionStateBase& conn,
    const AckState& ackState) {
  return !conn.pendingEvents.scheduleAckTimeout &&
      ackState.needsToSendAckImmediately && ackState.numRxPacketsRecvd == 0 &&
      ackState.numNonRxPacketsRecvd == 0;
}

bool verifyToScheduleAckTimeout(const QuicConnectionStateBase& conn) {
  return conn.pendingEvents.scheduleAckTimeout;
}

RegularQuicWritePacket makeTestShortPacket() {
  ShortHeader header(
      ProtectionType::KeyPhaseZero, getTestConnectionId(), 2 /* packetNum */);
  RegularQuicWritePacket packet(std::move(header));
  return packet;
}

RegularQuicWritePacket makeTestLongPacket(LongHeader::Types type) {
  LongHeader header(
      type,
      getTestConnectionId(0),
      getTestConnectionId(1),
      2 /* packetNum */,
      QuicVersion::QUIC_DRAFT);
  RegularQuicWritePacket packet(std::move(header));
  return packet;
}

class UpdateLargestReceivedPacketNumTest
    : public TestWithParam<PacketNumberSpace> {};

TEST_P(UpdateLargestReceivedPacketNumTest, FirstPacketNotOutOfOrder) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  /**
   * We skip setting the getAckState(conn, GetParam()).largestReceivedPacketNum
   * to simulate that we haven't received any packets yet.
   * `updateLargestReceivedPacketNum()` should return false for the first packet
   * received.
   */
  PacketNum firstPacket = folly::Random::rand32(1, 100);
  EXPECT_FALSE(updateLargestReceivedPacketNum(
      getAckState(conn, GetParam()), firstPacket, Clock::now()));
}

TEST_P(UpdateLargestReceivedPacketNumTest, ReceiveNew) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  getAckState(conn, GetParam()).largestRecvdPacketNum = 100;
  auto currentLargestReceived =
      *getAckState(conn, GetParam()).largestRecvdPacketNum;
  PacketNum newReceived = currentLargestReceived + 1;
  auto distance = updateLargestReceivedPacketNum(
      getAckState(conn, GetParam()), newReceived, Clock::now());
  EXPECT_EQ(distance, 0);
  EXPECT_GT(
      *getAckState(conn, GetParam()).largestRecvdPacketNum,
      currentLargestReceived);
}

TEST_P(UpdateLargestReceivedPacketNumTest, ReceiveNewWithGap) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  getAckState(conn, GetParam()).largestRecvdPacketNum = 100;
  auto currentLargestReceived =
      *getAckState(conn, GetParam()).largestRecvdPacketNum;
  PacketNum newReceived = currentLargestReceived + 3;
  auto distance = updateLargestReceivedPacketNum(
      getAckState(conn, GetParam()), newReceived, Clock::now());
  EXPECT_EQ(distance, 2); // newReceived is 2 after the expected pkt num
  EXPECT_GT(
      *getAckState(conn, GetParam()).largestRecvdPacketNum,
      currentLargestReceived);
}

TEST_P(UpdateLargestReceivedPacketNumTest, ReceiveOld) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  getAckState(conn, GetParam()).largestRecvdPacketNum = 100;
  auto currentLargestReceived =
      *getAckState(conn, GetParam()).largestRecvdPacketNum;
  PacketNum newReceived = currentLargestReceived - 1;
  auto distance = updateLargestReceivedPacketNum(
      getAckState(conn, GetParam()), newReceived, Clock::now());
  EXPECT_EQ(distance, 2); // newReceived is 2 before the expected pkt num
  EXPECT_EQ(
      *getAckState(conn, GetParam()).largestRecvdPacketNum,
      currentLargestReceived);
}

TEST_P(UpdateLargestReceivedPacketNumTest, ReceiveOldWithGap) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  getAckState(conn, GetParam()).largestRecvdPacketNum = 100;
  auto currentLargestReceived =
      *getAckState(conn, GetParam()).largestRecvdPacketNum;
  PacketNum newReceived = currentLargestReceived - 5;
  auto distance = updateLargestReceivedPacketNum(
      getAckState(conn, GetParam()), newReceived, Clock::now());
  EXPECT_EQ(distance, 6); // newReceived is 6 before the expected pkt num
  EXPECT_EQ(
      *getAckState(conn, GetParam()).largestRecvdPacketNum,
      currentLargestReceived);
}

INSTANTIATE_TEST_SUITE_P(
    UpdateLargestReceivedPacketNumTests,
    UpdateLargestReceivedPacketNumTest,
    Values(
        PacketNumberSpace::Initial,
        PacketNumberSpace::Handshake,
        PacketNumberSpace::AppData));

class UpdateReceivedPacketTimestampsTest
    : public TestWithParam<PacketNumberSpace> {};

TEST_P(UpdateReceivedPacketTimestampsTest, TestUpdatePktReceiveTimestamps) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());

  PacketNum nextPacketNum = 0;
  TimePoint latestTimeStamp = Clock::now();
  conn.ackStates = AckStates(nextPacketNum);
  for (int i = 0; i < kMaxReceivedPktsTimestampsStored + 2; i++) {
    updateAckState(
        conn,
        PacketNumberSpace::AppData,
        nextPacketNum++,
        true /* pktHasRetransmattableData */,
        false /* pktHasCryptoData */,
        latestTimeStamp);
    latestTimeStamp += 1ms;
  }
  auto& ackState = getAckState(conn, PacketNumberSpace::AppData);
  EXPECT_EQ(ackState.recvdPacketInfos.size(), kMaxReceivedPktsTimestampsStored);
  // First 2 packets (0, 1) should be popped.
  EXPECT_EQ(ackState.recvdPacketInfos.front().pktNum, 2);
  EXPECT_TRUE(ackState.largestRecvdPacketNum.has_value());
  EXPECT_TRUE(ackState.lastRecvdPacketInfo.has_value());

  EXPECT_EQ(
      ackState.largestRecvdPacketNum.value(),
      kMaxReceivedPktsTimestampsStored + 1);
  EXPECT_EQ(
      ackState.lastRecvdPacketInfo.value().pktNum,
      kMaxReceivedPktsTimestampsStored + 1);
}

TEST_P(
    UpdateReceivedPacketTimestampsTest,
    TestUpdateOutOfOrderPktReceiveTimestamps) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());

  std::vector<PacketNum> receivedPkts = {0, 2, 3, 1, 4, 6, 5};
  conn.ackStates = AckStates(receivedPkts.front());
  auto recvdTs = Clock::now();
  for (auto pktNum : receivedPkts) {
    updateAckState(
        conn,
        PacketNumberSpace::AppData,
        pktNum,
        true /* pktHasRetransmattableData */,
        false /* pktHasCryptoData */,
        recvdTs);
  }
  // Packets 1 and 5 are out of order and will not be stored.
  auto& ackState = getAckState(conn, PacketNumberSpace::AppData);
  std::deque<RecvdPacketInfo> expectedPktsInfo = {
      {0, recvdTs}, {2, recvdTs}, {3, recvdTs}, {4, recvdTs}, {6, recvdTs}};
  EXPECT_EQ(expectedPktsInfo.size(), ackState.recvdPacketInfos.size());
  for (unsigned long i = 0; i < expectedPktsInfo.size(); i++) {
    EXPECT_EQ(expectedPktsInfo[i].pktNum, ackState.recvdPacketInfos[i].pktNum);
    EXPECT_EQ(
        expectedPktsInfo[i].timeStamp, ackState.recvdPacketInfos[i].timeStamp);
  }
  EXPECT_EQ(ackState.lastRecvdPacketInfo.value().pktNum, 5);
  EXPECT_EQ(ackState.lastRecvdPacketInfo.value().timeStamp, recvdTs);
}

INSTANTIATE_TEST_SUITE_P(
    UpdateReceivedPacketTimestampsTests,
    UpdateReceivedPacketTimestampsTest,
    Values(PacketNumberSpace::AppData));

class UpdateAckStateTest : public TestWithParam<PacketNumberSpace> {};

TEST_P(UpdateAckStateTest, TestUpdateAckState) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  PacketNum nextPacketNum = 0;
  auto& ackState = getAckState(conn, GetParam());
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  EXPECT_EQ(ackState.acks.size(), 1);
  EXPECT_EQ(ackState.acks.front().start, 0);
  EXPECT_EQ(ackState.acks.front().end, 0);
  EXPECT_FALSE(ackState.needsToSendAckImmediately);
  EXPECT_EQ(ackState.numRxPacketsRecvd, 1);
  EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);

  conn.pendingEvents.scheduleAckTimeout = false;
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  EXPECT_EQ(ackState.acks.size(), 1);
  EXPECT_EQ(ackState.acks.front().start, 0);
  EXPECT_EQ(ackState.acks.front().end, 1);
  EXPECT_FALSE(ackState.needsToSendAckImmediately);
  EXPECT_EQ(ackState.numRxPacketsRecvd, 2);
  EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);

  // Have a gap for next packet
  nextPacketNum += 2;
  conn.pendingEvents.scheduleAckTimeout = false;
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  EXPECT_EQ(ackState.acks.size(), 2);
  EXPECT_EQ(ackState.acks.front().start, 0);
  EXPECT_EQ(ackState.acks.front().end, 1);
  EXPECT_EQ(ackState.acks.back().start, 4);
  EXPECT_EQ(ackState.acks.back().end, 4);
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  EXPECT_EQ(0, ackState.numRxPacketsRecvd);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
  ackState.needsToSendAckImmediately = false;
  conn.pendingEvents.scheduleAckTimeout = false;

  // Reaching retx limit
  for (uint8_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 1;
       ++i) {
    updateAckState(
        conn, GetParam(), nextPacketNum++, true, false, Clock::now());
    EXPECT_FALSE(ackState.needsToSendAckImmediately);
    EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);
    EXPECT_EQ(ackState.numRxPacketsRecvd, i + 1);
  }
  // Hit the limit
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  // Should send ack immediately once we have
  // conn.transportSettings.rxPacketsBeforeAckBeforeInit retransmittable packets
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);

  ackState.needsToSendAckImmediately = false;
  conn.pendingEvents.scheduleAckTimeout = false;

  // Nonrx limit
  for (uint64_t i = 0; i < kNonRtxRxPacketsPendingBeforeAck; ++i) {
    EXPECT_FALSE(ackState.needsToSendAckImmediately);
    EXPECT_EQ(ackState.numNonRxPacketsRecvd, i);
    updateAckState(
        conn, GetParam(), nextPacketNum++, false, false, Clock::now());
  }
  // Should send ack immediately once we have
  // kNonRtxRxPacketsPendingBeforeAck non retransmittable packets
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  // Non-rx packets don't turn on Ack timer:
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);

  ackState.needsToSendAckImmediately = false;

  // Crypto always triggers immediately ack:
  updateAckState(conn, GetParam(), nextPacketNum++, true, true, Clock::now());
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
}

TEST_P(UpdateAckStateTest, TestUpdateAckStateFrequency) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.transportSettings.rxPacketsBeforeAckInitThreshold = 20;
  conn.transportSettings.rxPacketsBeforeAckBeforeInit = 2;
  conn.transportSettings.rxPacketsBeforeAckAfterInit = 10;
  PacketNum nextPacketNum = 0;
  auto& ackState = getAckState(conn, GetParam());

  for (uint8_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 1;
       ++i) {
    updateAckState(
        conn, GetParam(), nextPacketNum++, true, false, Clock::now());
    EXPECT_FALSE(ackState.needsToSendAckImmediately);
    EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);
    EXPECT_EQ(ackState.numRxPacketsRecvd, i + 1);
  }
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
  ackState.needsToSendAckImmediately = false;
  conn.pendingEvents.scheduleAckTimeout = false;

  for (;
       nextPacketNum <= conn.transportSettings.rxPacketsBeforeAckInitThreshold;
       nextPacketNum++) {
    updateAckState(conn, GetParam(), nextPacketNum, true, false, Clock::now());
  }
  ASSERT_EQ(
      ackState.largestRecvdPacketNum.value(),
      conn.transportSettings.rxPacketsBeforeAckInitThreshold);
  ackState.needsToSendAckImmediately = false;
  conn.pendingEvents.scheduleAckTimeout = false;
  ackState.numRxPacketsRecvd = 0;
  for (uint8_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckAfterInit - 1;
       ++i) {
    updateAckState(
        conn, GetParam(), nextPacketNum++, true, false, Clock::now());
    EXPECT_FALSE(ackState.needsToSendAckImmediately);
    EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);
    EXPECT_EQ(ackState.numRxPacketsRecvd, i + 1);
  }
  updateAckState(conn, GetParam(), nextPacketNum++, true, false, Clock::now());
  EXPECT_TRUE(ackState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
}

TEST_P(UpdateAckStateTest, TestUpdateAckStateFrequencyFromTolerance) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  PacketNum nextPacketNum = 1;
  auto& ackState = getAckState(conn, GetParam());
  ackState.largestRecvdPacketNum = nextPacketNum - 1;
  ackState.tolerance = 2;
  for (; nextPacketNum <= 10; nextPacketNum++) {
    updateAckState(conn, GetParam(), nextPacketNum, true, false, Clock::now());
    if (nextPacketNum < 2) {
      EXPECT_FALSE(ackState.needsToSendAckImmediately);
      EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);
      EXPECT_EQ(nextPacketNum, ackState.numRxPacketsRecvd);
    } else {
      EXPECT_TRUE(ackState.needsToSendAckImmediately);
      EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
      EXPECT_EQ(0, ackState.numRxPacketsRecvd);
    }
    EXPECT_EQ(0, ackState.numNonRxPacketsRecvd);
  }
  ackState.tolerance = 10;
  for (; nextPacketNum <= 40; nextPacketNum++) {
    updateAckState(conn, GetParam(), nextPacketNum, true, false, Clock::now());
    if (nextPacketNum < 10) {
      EXPECT_FALSE(ackState.needsToSendAckImmediately);
      EXPECT_TRUE(conn.pendingEvents.scheduleAckTimeout);
      EXPECT_EQ(nextPacketNum, ackState.numRxPacketsRecvd);
    } else {
      EXPECT_TRUE(ackState.needsToSendAckImmediately);
      EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
      EXPECT_EQ(0, ackState.numRxPacketsRecvd);
    }
    EXPECT_EQ(0, ackState.numRxPacketsRecvd);
  }
}

TEST_F(UpdateAckStateTest, UpdateAckStateOnAckTimeout) {
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& initialAckState = getAckState(conn, PacketNumberSpace::Initial);
  auto& handshakeAckState = getAckState(conn, PacketNumberSpace::Handshake);
  auto& appDataAckState = getAckState(conn, PacketNumberSpace::AppData);
  initialAckState.numRxPacketsRecvd = 1;
  handshakeAckState.numRxPacketsRecvd = 2;
  appDataAckState.numRxPacketsRecvd = 3;
  initialAckState.numNonRxPacketsRecvd = 4;
  handshakeAckState.numNonRxPacketsRecvd = 5;
  appDataAckState.numNonRxPacketsRecvd = 6;

  updateAckStateOnAckTimeout(conn);

  EXPECT_TRUE(appDataAckState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
  EXPECT_EQ(0, appDataAckState.numRxPacketsRecvd);
  EXPECT_EQ(0, appDataAckState.numNonRxPacketsRecvd);

  EXPECT_FALSE(initialAckState.needsToSendAckImmediately);
  EXPECT_EQ(1, initialAckState.numRxPacketsRecvd);
  EXPECT_EQ(4, initialAckState.numNonRxPacketsRecvd);

  EXPECT_FALSE(handshakeAckState.needsToSendAckImmediately);
  EXPECT_FALSE(conn.pendingEvents.scheduleAckTimeout);
  EXPECT_EQ(2, handshakeAckState.numRxPacketsRecvd);
  EXPECT_EQ(5, handshakeAckState.numNonRxPacketsRecvd);
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsCrypto) {
  // Crypto always leads to immediate ack
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, true);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsInitCryptoExperimental) {
  // Crypto data leads to immediate ack unless init packet space.
  QuicConnectionStateBase conn(QuicNodeType::Server);

  bool isInitPktNumSpace = GetParam() == PacketNumberSpace::Initial;

  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(
      conn, ackState, false, true, true, isInitPktNumSpace);

  EXPECT_EQ(
      verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState),
      !isInitPktNumSpace);
  EXPECT_EQ(verifyToScheduleAckTimeout(conn), isInitPktNumSpace);
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsRxLimit) {
  // Retx packets reach thresh
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  for (size_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 1;
       i++) {
    updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_TRUE(verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a retx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsNonRxLimit) {
  // Non-rx packets reach thresh
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  for (size_t i = 0; i < kNonRtxRxPacketsPendingBeforeAck - 1; i++) {
    updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a non-rx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsNonRxLimitWithRxPackets) {
  // Non-rx packets reach thresh
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  // use 1 rx packet
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  for (size_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 2;
       i++) {
    updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_TRUE(verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a non-rx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsRxLimitFollowedByNonRx) {
  // Retx packets reach thresh
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  for (size_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 1;
       i++) {
    updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_TRUE(verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a non-retx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsNonRxLimitFollowedByRx) {
  // Non-rx packets reach thresh
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  for (size_t i = 0; i < kNonRtxRxPacketsPendingBeforeAck - 1; i++) {
    updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, false, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a retx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsRxAndNonRxMixed) {
  // Rx and non-rx mixed together. We should still just need
  // conn.transportSettings.rxPacketsBeforeAckBeforeInit to trigger an ack
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  for (size_t i = 0;
       i < conn.transportSettings.rxPacketsBeforeAckBeforeInit - 1;
       i++) {
    bool isRetransmittable = i % 2;
    updateAckSendStateOnRecvPacket(conn, ackState, 0, isRetransmittable, false);
    EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
    EXPECT_EQ(i >= 1, verifyToScheduleAckTimeout(conn));
  }
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a retx packet, we will still need to ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsRxOutOfOrder) {
  // Retransmittable & out of order: ack immediately
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(conn, ackState, 1, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsRxOutOfOrderThresholdNotExceeded) {
  // Retransmittable & out of order: don't ack immediately if threshold not
  // exceeded.
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  ackState.reorderThreshold = 3;
  updateAckSendStateOnRecvPacket(conn, ackState, 3, true, false);
  EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_TRUE(verifyToScheduleAckTimeout(conn));
}

TEST_P(UpdateAckStateTest, UpdateAckSendStateOnRecvPacketsNonRxOutOfOrder) {
  // Non-retransmittable & out of order: not ack immediately
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(conn, ackState, 3, false, false);
  EXPECT_FALSE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsRxOutOfOrderFollowedByInOrder) {
  // Retransmittable & out of order: ack immediately
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(conn, ackState, 1, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a retransmittable & in order: still ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

TEST_P(
    UpdateAckStateTest,
    UpdateAckSendStateOnRecvPacketsCryptoFollowedByNonCrypto) {
  // Retransmittable & Crypto: ack immediately
  QuicConnectionStateBase conn(QuicNodeType::Client);
  auto& ackState = getAckState(conn, GetParam());
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, true);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));

  // Followed by a retransmittable & non Crypo: still ack immediately
  updateAckSendStateOnRecvPacket(conn, ackState, 0, true, false);
  EXPECT_TRUE(verifyToAckImmediatelyAndZeroPacketsReceived(conn, ackState));
  EXPECT_FALSE(verifyToScheduleAckTimeout(conn));
}

INSTANTIATE_TEST_SUITE_P(
    UpdateAckStateTests,
    UpdateAckStateTest,
    Values(
        PacketNumberSpace::Initial,
        PacketNumberSpace::Handshake,
        PacketNumberSpace::AppData));

class QuicStateFunctionsTest : public TestWithParam<PacketNumberSpace> {};

TEST_F(QuicStateFunctionsTest, RttCalculationZeroAckDelayFirstRtt) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  const auto rttSample = 1100us;
  const auto ackDelay = 0us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(1100, conn.lossState.srtt.count());
  EXPECT_EQ(1100, conn.lossState.lrtt.count());
  EXPECT_EQ(1100 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(1100, conn.lossState.mrtt.count());
  EXPECT_EQ(0us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithAckDelayFirstRtt) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  const auto rttSample = 1000us;
  const auto ackDelay = 300us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(1000, conn.lossState.srtt.count());
  EXPECT_EQ(1000, conn.lossState.lrtt.count());
  EXPECT_EQ(1000, conn.lossState.mrtt.count());
  EXPECT_EQ(1000 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(300us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithExistingMrttNewLower) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  const auto rttSample = 50us;
  const auto ackDelay = 100us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(50, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithExistingMrttStaysSame) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 25us;
  const auto rttSample = 50us;
  const auto ackDelay = 100us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(25, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithExistingMrttZeroAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 500us;
  const auto rttSample = 1100us;
  const auto ackDelay = 0us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(1100, conn.lossState.srtt.count());
  EXPECT_EQ(1100, conn.lossState.lrtt.count());
  EXPECT_EQ(100, conn.lossState.mrtt.count());
  EXPECT_EQ(1100 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(500us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithExistingMrttSubtractAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  const auto rttSample = 1000us;
  const auto ackDelay = 300us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(700, conn.lossState.srtt.count()); // 700 as ack delay subtracted
  EXPECT_EQ(1000, conn.lossState.lrtt.count()); // 1000 as lrtt = rttSample
  EXPECT_EQ(100, conn.lossState.mrtt.count());
  EXPECT_EQ(
      700 / 2, conn.lossState.rttvar.count()); // 700 as ack delay subtracted
  EXPECT_EQ(300us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithExistingMrttIgnoreAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 700us;
  const auto rttSample = 900us;
  const auto ackDelay = 300us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(900, conn.lossState.srtt.count());
  EXPECT_EQ(900, conn.lossState.lrtt.count());
  EXPECT_EQ(700, conn.lossState.mrtt.count());
  EXPECT_EQ(450, conn.lossState.rttvar.count());
  EXPECT_EQ(300us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithNewLowerMrttZeroAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 500us;
  const auto rttSample = 50us;
  const auto ackDelay = 0us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(50, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(500us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationWithNewLowerMrttIgnoreAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  const auto rttSample = 50us;
  const auto ackDelay = 25us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(50, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(25us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationMaxAckDelayIncreases) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 50us;
  const auto rttSample = 500us;
  const auto ackDelay = 100us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(400, conn.lossState.srtt.count()); // 400 as ack delay subtracted
  EXPECT_EQ(500, conn.lossState.lrtt.count()); // 500 as lrtt = rttSample
  EXPECT_EQ(100, conn.lossState.mrtt.count());
  EXPECT_EQ(400 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(100us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationMaxAckDelayStaysSame) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 5000us;
  const auto rttSample = 500us;
  const auto ackDelay = 100us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(400, conn.lossState.srtt.count()); // 400 as ack delay subtracted
  EXPECT_EQ(500, conn.lossState.lrtt.count()); // 500 as lrtt = rttSample
  EXPECT_EQ(100, conn.lossState.mrtt.count());
  EXPECT_EQ(400 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(5000us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationNewLowerMrttMaxAckDelayIncreases) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 50us;
  const auto rttSample = 50us;
  const auto ackDelay = 100us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(50, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(100us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationNewLowerMrttMaxAckDelayStaysSame) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  conn.lossState.maxAckDelay = 5000us;
  const auto rttSample = 50us;
  const auto ackDelay = 10us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(50, conn.lossState.srtt.count());
  EXPECT_EQ(50, conn.lossState.lrtt.count());
  EXPECT_EQ(50, conn.lossState.mrtt.count());
  EXPECT_EQ(50 / 2, conn.lossState.rttvar.count());
  EXPECT_EQ(5000us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationAckDelayLargerThanSample) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  const auto rttSample = 10us;
  const auto ackDelay = 300us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(10, conn.lossState.srtt.count());
  EXPECT_EQ(10, conn.lossState.lrtt.count());
  EXPECT_EQ(10, conn.lossState.mrtt.count());
  EXPECT_EQ(5, conn.lossState.rttvar.count());
  EXPECT_EQ(300us, conn.lossState.maxAckDelay);
}

TEST_F(
    QuicStateFunctionsTest,
    RttCalculationWithNewLowerMrttAckDelayLargerThanSample) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  conn.lossState.mrtt = 100us;
  const auto rttSample = 10us;
  const auto ackDelay = 300us;
  updateRtt(conn, rttSample, ackDelay);
  EXPECT_EQ(10, conn.lossState.srtt.count());
  EXPECT_EQ(10, conn.lossState.lrtt.count());
  EXPECT_EQ(10, conn.lossState.mrtt.count());
  EXPECT_EQ(5, conn.lossState.rttvar.count());
  EXPECT_EQ(300us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, RttCalculationExtraRttMetricsStoredInLossState) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());

  // Test cases
  //
  //                                     ||   [ Value Expected ]   |
  //  Case | RTT (delay) | RTT w/o delay ||  mRTT  |  w/o ACK delay | Updated
  //  -----|-------------|---------------||------- |----------------|----------
  //    1  | 31ms (5 ms) |     26ms      ||   31   |       26       | (both)
  //    2  | 30ms (3 ms) |     27ms      ||   30   |       26       | (1)
  //    3  | 30ms (8 ms) |     22ms      ||   30   |       22       | (2)
  //    4  | 37ms (8 ms) |     29ms      ||   30   |       22       | (none)
  //    5  | 25ms (0 ms) |     29ms      ||   25   |       22       | (1)
  //    6  | 25ms (4 ms) |     29ms      ||   25   |       21       | (2)
  //    7  | 20ms (0 ms) |     29ms      ||   20   |       20       | (both)
  //    8  | 0ms (0 ms)  |     0ms       ||   0    |       0        | (both)
  //    9  | 0ms (10 ms) |     0ms       ||   0    |       0        | (none)

  // case 1
  updateRtt(conn, 31ms /* RTT sample */, 5ms /* ack delay */);
  EXPECT_EQ(31ms, conn.lossState.mrtt);
  EXPECT_EQ(26ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(31ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(5ms, conn.lossState.maybeLrttAckDelay);

  // case 2
  updateRtt(conn, 30ms /* RTT sample */, 3ms /* ack delay */);
  EXPECT_EQ(30ms, conn.lossState.mrtt);
  EXPECT_EQ(26ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(30ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(3ms, conn.lossState.maybeLrttAckDelay);

  // case 3
  updateRtt(conn, 30ms /* RTT sample */, 8ms /* ack delay */);
  EXPECT_EQ(30ms, conn.lossState.mrtt);
  EXPECT_EQ(22ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(30ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(8ms, conn.lossState.maybeLrttAckDelay);

  // case 4
  updateRtt(conn, 37ms /* RTT sample */, 8ms /* ack delay */);
  EXPECT_EQ(30ms, conn.lossState.mrtt);
  EXPECT_EQ(22ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(37ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(8ms, conn.lossState.maybeLrttAckDelay);

  // case 5
  updateRtt(conn, 25ms /* RTT sample */, 0ms /* ack delay */);
  EXPECT_EQ(25ms, conn.lossState.mrtt);
  EXPECT_EQ(22ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(25ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(0ms, conn.lossState.maybeLrttAckDelay);

  // case 6
  updateRtt(conn, 25ms /* RTT sample */, 4ms /* ack delay */);
  EXPECT_EQ(25ms, conn.lossState.mrtt);
  EXPECT_EQ(21ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(25ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(4ms, conn.lossState.maybeLrttAckDelay);

  // case 7
  updateRtt(conn, 20ms /* RTT sample */, 0ms /* ack delay */);
  EXPECT_EQ(20ms, conn.lossState.mrtt);
  EXPECT_EQ(20ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(20ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(0ms, conn.lossState.maybeLrttAckDelay);

  // case 8
  updateRtt(conn, 0ms /* RTT sample */, 0ms /* ack delay */);
  EXPECT_EQ(0ms, conn.lossState.mrtt);
  EXPECT_EQ(0ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(0ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(0ms, conn.lossState.maybeLrttAckDelay);

  // case 9
  updateRtt(conn, 0ms /* RTT sample */, 10ms /* ack delay */);
  EXPECT_EQ(0ms, conn.lossState.mrtt);
  EXPECT_EQ(0ms, conn.lossState.maybeMrttNoAckDelay);
  EXPECT_EQ(0ms, conn.lossState.maybeLrtt);
  EXPECT_EQ(10ms, conn.lossState.maybeLrttAckDelay);
}

TEST_F(QuicStateFunctionsTest, TestInvokeStreamStateMachineConnectionError) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  QuicStreamState stream(1, conn);
  RstStreamFrame rst(1, GenericApplicationErrorCode::UNKNOWN, 100);
  stream.finalReadOffset = 1024;
  EXPECT_THROW(
      receiveRstStreamSMHandler(stream, std::move(rst)),
      QuicTransportException);
  // This doesn't change the send state machine implicitly anymore
  bool matches = (stream.sendState == StreamSendState::Open);
  EXPECT_TRUE(matches);
}

TEST_F(QuicStateFunctionsTest, InvokeResetDoesNotSendFlowControl) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  QuicStreamState stream(1, conn);
  RstStreamFrame rst(1, GenericApplicationErrorCode::UNKNOWN, 90);
  // this would normally trigger a flow control update.
  stream.flowControlState.advertisedMaxOffset = 100;
  stream.flowControlState.windowSize = 100;
  conn.flowControlState.advertisedMaxOffset = 100;
  conn.flowControlState.windowSize = 100;
  receiveRstStreamSMHandler(stream, std::move(rst));
  bool matches = (stream.recvState == StreamRecvState::Closed);
  EXPECT_TRUE(matches);
  EXPECT_FALSE(conn.streamManager->hasWindowUpdates());
  EXPECT_TRUE(conn.pendingEvents.connWindowUpdate);
}

TEST_F(QuicStateFunctionsTest, TestInvokeStreamStateMachineStreamError) {
  // We isolate invalid events on streams to affect only the streams. Is that
  // a good idea? We'll find out.
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  QuicStreamState stream(1, conn);
  RstStreamFrame rst(1, GenericApplicationErrorCode::UNKNOWN, 100);
  try {
    sendRstAckSMHandler(stream);
    ADD_FAILURE();
  } catch (QuicTransportException& ex) {
    EXPECT_EQ(ex.errorCode(), TransportErrorCode::STREAM_STATE_ERROR);
  }
  bool matches = (stream.sendState == StreamSendState::Open);
  EXPECT_TRUE(matches);
}

TEST_F(QuicStateFunctionsTest, UpdateMinRtt) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  auto qLogger = std::make_shared<FileQLogger>(VantagePoint::Server);
  conn.qLogger = qLogger;

  // First rtt sample, will be assign to both srtt and mrtt
  auto rttSample = 100us;
  updateRtt(conn, rttSample, 0us);
  EXPECT_EQ(100us, conn.lossState.lrtt);
  EXPECT_EQ(conn.lossState.lrtt, conn.lossState.mrtt);
  EXPECT_EQ(conn.lossState.lrtt, conn.lossState.srtt);
  auto oldMrtt = conn.lossState.mrtt;

  // Slower packet
  rttSample = 550us;
  updateRtt(conn, rttSample, 0us);
  EXPECT_EQ(oldMrtt, conn.lossState.mrtt);

  // Faster packet
  rttSample = 20us;
  updateRtt(conn, rttSample, 0us);
  EXPECT_EQ(20us, conn.lossState.mrtt);

  std::vector<int> indices =
      getQLogEventIndices(QLogEventType::MetricUpdate, qLogger);
  EXPECT_EQ(indices.size(), 3);
  std::array<std::chrono::microseconds, 3> rttSampleArr = {100us, 550us, 20us};
  std::array<std::chrono::microseconds, 3> mrttArr = {oldMrtt, oldMrtt, 20us};
  std::array<std::chrono::microseconds, 3> srttArr = {100us, 155us, 137us};

  for (int i = 0; i < 3; ++i) {
    auto tmp = std::move(qLogger->logs[indices[i]]);
    auto event = dynamic_cast<QLogMetricUpdateEvent*>(tmp.get());
    EXPECT_EQ(event->latestRtt, rttSampleArr[i]);
    EXPECT_EQ(event->mrtt, mrttArr[i]);
    EXPECT_EQ(event->srtt, srttArr[i]);
    EXPECT_EQ(event->ackDelay, 0us);
  }
}

TEST_F(QuicStateFunctionsTest, UpdateMaxAckDelay) {
  QuicServerConnectionState conn(
      FizzServerQuicHandshakeContext::Builder().build());
  EXPECT_EQ(0us, conn.lossState.maxAckDelay);
  auto rttSample = 100us;

  // update maxAckDelay
  updateRtt(conn, rttSample, 30us);
  EXPECT_EQ(30us, conn.lossState.maxAckDelay);

  // smaller ackDelay
  updateRtt(conn, rttSample, 3us);
  EXPECT_EQ(30us, conn.lossState.maxAckDelay);
}

TEST_F(QuicStateFunctionsTest, IsConnectionPaced) {
  QuicConnectionStateBase state(QuicNodeType::Client);
  EXPECT_FALSE(isConnectionPaced(state));

  state.canBePaced = true;
  EXPECT_FALSE(isConnectionPaced(state));

  state.transportSettings.pacingEnabled = true;
  EXPECT_FALSE(isConnectionPaced(state));
}

TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
  QuicConnectionStateBase conn(QuicNodeType::Client);
  conn.outstandings.packets.emplace_back(
      makeTestLongPacket(LongHeader::Types::Initial),
      Clock::now(),
      135,
      0,
      false,
      0,
      0,
      0,
      0,
      LossState(),
      0,
      OutstandingPacketMetadata::DetailsPerStream());
  conn.outstandings.packets.emplace_back(
      makeTestLongPacket(LongHeader::Types::Handshake),
      Clock::now(),
      1217,
      0,
      false,
      0,
      0,
      0,
      0,
      LossState(),
      0,
      OutstandingPacketMetadata::DetailsPerStream());
  conn.outstandings.packets.emplace_back(
      makeTestShortPacket(),
      Clock::now(),
      5556,
      5000,
      false,
      0,
      0,
      0,
      0,
      LossState(),
      0,
      OutstandingPacketMetadata::DetailsPerStream());
  conn.outstandings.packets.emplace_back(
      makeTestLongPacket(LongHeader::Types::Initial),
      Clock::now(),
      56,
      0,
      false,
      0,
      0,
      0,
      0,
      LossState(),
      0,
      OutstandingPacketMetadata::DetailsPerStream());
  conn.outstandings.packets.emplace_back(
      makeTestShortPacket(),
      Clock::now(),
      6665,
      6000,
      false,
      0,
      0,
      0,
      0,
      LossState(),
      0,
      OutstandingPacketMetadata::DetailsPerStream());
  EXPECT_EQ(
      135,
      getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)
          ->metadata.encodedSize);
  EXPECT_EQ(
      0,
      getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)
          ->metadata.encodedBodySize);
  EXPECT_EQ(
      56,
      getLastOutstandingPacket(conn, PacketNumberSpace::Initial)
          ->metadata.encodedSize);
  EXPECT_EQ(
      0,
      getLastOutstandingPacket(conn, PacketNumberSpace::Initial)
          ->metadata.encodedBodySize);
  EXPECT_EQ(
      1217,
      getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
          ->metadata.encodedSize);
  EXPECT_EQ(
      0,
      getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
          ->metadata.encodedBodySize);
  EXPECT_EQ(
      5556,
      getFirstOutstandingPacket(conn, PacketNumberSpace::AppData)
          ->metadata.encodedSize);
  EXPECT_EQ(
      5000,
      getFirstOutstandingPacket(conn, PacketNumberSpace::AppData)
          ->metadata.encodedBodySize);
  EXPECT_EQ(
      6665,
      getLastOutstandingPacket(conn, PacketNumberSpace::AppData)
          ->metadata.encodedSize);
  EXPECT_EQ(
      6000,
      getLastOutstandingPacket(conn, PacketNumberSpace::AppData)
          ->metadata.encodedBodySize);
}

TEST_F(QuicStateFunctionsTest, UpdateLargestReceivePacketsAtLatCloseSent) {
  QuicConnectionStateBase conn(QuicNodeType::Client);
  EXPECT_FALSE(conn.ackStates.initialAckState.largestReceivedAtLastCloseSent);
  EXPECT_FALSE(conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent);
  EXPECT_FALSE(conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent);
  conn.ackStates.initialAckState.largestRecvdPacketNum = 123;
  conn.ackStates.handshakeAckState.largestRecvdPacketNum = 654;
  conn.ackStates.appDataAckState.largestRecvdPacketNum = 789;
  updateLargestReceivedPacketsAtLastCloseSent(conn);
  EXPECT_EQ(
      123, *conn.ackStates.initialAckState.largestReceivedAtLastCloseSent);
  EXPECT_EQ(
      654, *conn.ackStates.handshakeAckState.largestReceivedAtLastCloseSent);
  EXPECT_EQ(
      789, *conn.ackStates.appDataAckState.largestReceivedAtLastCloseSent);
}

TEST_P(QuicStateFunctionsTest, HasReceivedPackets) {
  QuicConnectionStateBase conn(QuicNodeType::Server);
  EXPECT_FALSE(hasReceivedPackets(conn));
  getAckState(conn, GetParam()).largestRecvdPacketNum = 123;
  EXPECT_TRUE(hasReceivedPackets(conn));
}

TEST_P(QuicStateFunctionsTest, HasReceivedPacketsAtLastCloseSent) {
  QuicConnectionStateBase conn(QuicNodeType::Server);
  EXPECT_FALSE(hasReceivedPacketsAtLastCloseSent(conn));
  getAckState(conn, GetParam()).largestReceivedAtLastCloseSent = 1;
  EXPECT_TRUE(hasReceivedPacketsAtLastCloseSent(conn));
}

TEST_P(QuicStateFunctionsTest, HasNotReceivedNewPacketsSinceLastClose) {
  QuicConnectionStateBase conn(QuicNodeType::Server);
  EXPECT_TRUE(hasNotReceivedNewPacketsSinceLastCloseSent(conn));
  getAckState(conn, GetParam()).largestRecvdPacketNum = 1;
  EXPECT_FALSE(hasNotReceivedNewPacketsSinceLastCloseSent(conn));
  getAckState(conn, GetParam()).largestReceivedAtLastCloseSent = 1;
  EXPECT_TRUE(hasReceivedPacketsAtLastCloseSent(conn));
}

TEST_F(QuicStateFunctionsTest, EarliestLossTimer) {
  QuicConnectionStateBase conn(QuicNodeType::Server);
  EXPECT_FALSE(earliestLossTimer(conn).first.has_value());
  auto currentTime = Clock::now();

  // Before handshake completed
  conn.lossState.lossTimes[PacketNumberSpace::Initial] = currentTime;
  EXPECT_EQ(PacketNumberSpace::Initial, earliestLossTimer(conn).second);
  EXPECT_EQ(currentTime, earliestLossTimer(conn).first.value());
  conn.lossState.lossTimes[PacketNumberSpace::AppData] = currentTime - 2s;
  EXPECT_EQ(PacketNumberSpace::Initial, earliestLossTimer(conn).second);
  EXPECT_EQ(currentTime, earliestLossTimer(conn).first.value());
  conn.lossState.lossTimes[PacketNumberSpace::Handshake] = currentTime - 1s;
  EXPECT_EQ(PacketNumberSpace::Handshake, earliestLossTimer(conn).second);
  EXPECT_EQ(currentTime - 1s, earliestLossTimer(conn).first.value());

  conn.oneRttWriteCipher = createNoOpAead();

  // After one-rtt cipher is available
  EXPECT_EQ(PacketNumberSpace::AppData, earliestLossTimer(conn).second);
  EXPECT_EQ(currentTime - 2s, earliestLossTimer(conn).first.value());
  conn.lossState.lossTimes[PacketNumberSpace::AppData] = currentTime + 1s;
  EXPECT_EQ(PacketNumberSpace::Handshake, earliestLossTimer(conn).second);
  EXPECT_EQ(currentTime - 1s, earliestLossTimer(conn).first.value());
}

TEST_P(QuicStateFunctionsTest, CloseTranportStateChange) {
  QuicConnectionStateBase conn(QuicNodeType::Server);
  getAckState(conn, GetParam()).nextPacketNum = kMaxPacketNumber - 2;
  EXPECT_FALSE(conn.pendingEvents.closeTransport);
  increaseNextPacketNum(conn, GetParam());
  EXPECT_TRUE(conn.pendingEvents.closeTransport);
}

INSTANTIATE_TEST_SUITE_P(
    QuicStateFunctionsTests,
    QuicStateFunctionsTest,
    Values(
        PacketNumberSpace::Initial,
        PacketNumberSpace::Handshake,
        PacketNumberSpace::AppData));

} // namespace quic::test


text:
function [logllh,dhyp] = fastLikelihood(likfunc,y,fs,hyp,N,Q)
%FASTLIKELIHOOD [logllh,dhyp] = fastLikelihood(y,fs,hyp,N,Q)
%
% Vectorized computation of likelihood 'likfunc' for multiple sets of latent values
% e.g. samples. Each column in fs a sample of the latent values.
%
% 03/05/14
nsamples = size(fs,2);
% vectorize computation for log llh
% cfs{i} = i-th sample with size (NxQ)x1 i.e. column vector
cfs = mat2cell(fs(:),repmat(N*Q,nsamples,1),1);
% cfs{i} = i-th sample with size NxQ, i.e. matrix
cfsmat = cellfun(@(A) reshape(A,N,Q),cfs,'UniformOutput',false);
fsmat = cell2mat(cfsmat); % size (N*S)xQ
if nargout == 1
  logllh = feval(likfunc, repmat(y,nsamples,1), fsmat, hyp);
else
  [logllh,dhyp] = feval(likfunc, repmat(y,nsamples,1), fsmat, hyp);
end


text:
import java.util.ArrayList;

class B {
  static void bar(String s){}
  {
    new ArrayList<String>().forEach(b<caret>);
  }
}


text:
package com.busbycreations.usafpfacalc;

import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;

public class AboutDialogFragment extends DialogFragment {

    @Override
    public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstance) {
        View inflated = layoutInflater.inflate(R.layout.dialog_about, container, false);

        WebView webView = (WebView) inflated.findViewById(R.id.aboutDialogWebView);
        webView.loadData(getString(R.string.about_dialog_text), "text/html", "utf-8");

        return inflated;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);

        // For some reason, when we try this, the WebView never gets populated.
//        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

        // So, instead, just set a Title and live with it.
        dialog.setTitle(getString(R.string.about_dialog_title));

        return dialog;
    }
}


text:
class Api {

  performRequest(url, method, body, headers = {}) {

    const reqHeaders = new Headers();
    reqHeaders.append('Accept', 'application/json');

    for (let key in headers) {
      reqHeaders.append(key, headers[key]);
    }

    const opts = {
      headers: reqHeaders,
      method: method,
      credentials: "same-origin"
    };

    if (body) {
      opts.body = body;
    }

    return fetch(url, opts);
  }

  getJson(url, params) {
    let body = params || null;
    if (body) {
      body = JSON.stringify(body);
    }
    return this.performRequest(url, "GET", body, {"Content-Type": "application/json"}).then(response => {
      if (response.ok) {
        return response.json();
      } else {
        throw "invalid response: " + response.status
      }
    })
  }

  postFormData(url, data) {
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute("content");
    return this.performRequest(url, "POST", data, {"X-CSRF-Token": csrfToken}).then(response => {
      if (response.ok) {
        return response.json();
      } else {
        throw "invalid response: " + response.status
      }
    });
  }

}

export default new Api();


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>ListFieldChangeListener (Java Class Library API)</title>
<meta name="date" content="2015-04-16">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

org.jsimpledb.core

Interface ListFieldChangeListener

public interface ListFieldChangeListener

Listener interface for notifications of a change in value of a ListField.

See Also:

Transaction.addListFieldChangeListener()

Method Summary

All Methods Instance Methods Abstract Methods

Modifier and Type
Method and Description

<E> void
onListFieldAdd(Transaction tx,
              ObjId id,
              ListField<E> field,
              int[] path,
              NavigableSet<ObjId> referrers,
              int index,
              E value)

Receive notification of the addition (or insertion) of an element to a ListField.

void
onListFieldClear(Transaction tx,
                ObjId id,
                ListField<?> field,
                int[] path,
                NavigableSet<ObjId> referrers)

Receive notification of the clearing of a ListField.

<E> void
onListFieldRemove(Transaction tx,
                 ObjId id,
                 ListField<E> field,
                 int[] path,
                 NavigableSet<ObjId> referrers,
                 int index,
                 E value)

Receive notification of a removal of an element from a ListField.

<E> void
onListFieldReplace(Transaction tx,
                  ObjId id,
                  ListField<E> field,
                  int[] path,
                  NavigableSet<ObjId> referrers,
                  int index,
                  E oldValue,
                  E newValue)

Receive notification of the change in element at a specific position in a ListField.

Method Detail

onListFieldAdd

<E> void onListFieldAdd(Transaction tx,
                        ObjId id,
                        ListField<E> field,
                        int[] path,
                        NavigableSet<ObjId> referrers,
                        int index,
                        E value)

Receive notification of the addition (or insertion) of an element to a ListField.

 Notifications are only delivered when referrers is non-empty.

 Notifications are delivered in the same thread that made the change, before the outermost mutation operation returns.

Type Parameters:

E - Java type for field's elements

Parameters:

tx - associated transaction

id - the ID of the affected object (i.e., the object containing the field that changed)

field - the field that changed

path - path of reference fields (represented by storage IDs) that lead to id

referrers - all objects that (indirectly) refer to the affected object via path

index - the position in the list at which value was added or inserted

value - the value added to the list

onListFieldRemove

<E> void onListFieldRemove(Transaction tx,
                           ObjId id,
                           ListField<E> field,
                           int[] path,
                           NavigableSet<ObjId> referrers,
                           int index,
                           E value)

Receive notification of a removal of an element from a ListField.

 Notifications are only delivered when referrers is non-empty.

 Notifications are delivered in the same thread that made the change, before the outermost mutation operation returns.

Type Parameters:

E - Java type for field's elements

Parameters:

tx - associated transaction

id - the ID of the affected object (i.e., the object containing the field that changed)

field - the field that changed

path - path of reference fields (represented by storage IDs) that lead to id

referrers - all objects that (indirectly) refer to the affected object via path

index - the position in the list at which value was removed

value - the value removed from the list

onListFieldReplace

<E> void onListFieldReplace(Transaction tx,
                            ObjId id,
                            ListField<E> field,
                            int[] path,
                            NavigableSet<ObjId> referrers,
                            int index,
                            E oldValue,
                            E newValue)

Receive notification of the change in element at a specific position in a ListField.

 Notifications are only delivered when referrers is non-empty.

 Notifications are delivered in the same thread that made the change, before the outermost mutation operation returns.

Type Parameters:

E - Java type for field's elements

Parameters:

tx - associated transaction

id - the ID of the affected object (i.e., the object containing the field that changed)

field - the field that changed

path - path of reference fields (represented by storage IDs) that lead to id

referrers - all objects that (indirectly) refer to the affected object via path

index - the position in the list at which the change occurred

oldValue - the old value at list position index

newValue - the new value at list position index

onListFieldClear

void onListFieldClear(Transaction tx,
                      ObjId id,
                      ListField<?> field,
                      int[] path,
                      NavigableSet<ObjId> referrers)

Receive notification of the clearing of a ListField.

 This method is only used when the whole list is cleared; when a sub-range of a list is cleared, individual
 onListFieldRemove() invocations for each removed element are made instead.

 Notifications are only delivered when referrers is non-empty.

 Notifications are delivered in the same thread that made the change, before the outermost mutation operation returns.

Parameters:

tx - associated transaction

id - the ID of the affected object (i.e., the object containing the field that was cleared)

field - the field that changed

path - path of reference fields (represented by storage IDs) that lead to id

referrers - all objects that (indirectly) refer to the affected object via path

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
let dot = require('../../lib/doT.js');
let css = require('./header.css');
let tpl = require('./tpl.js');
let d = require('./data.js');
// console.log($);
class Header{
	constructor(){
		this.title = d.title;
	}
	init(){
		let tplFn = dot.template(tpl);
		let html = tplFn(d);
		$('body').prepend(html);
	}
	show(){

	}
}

module.exports = Header;


text:
ALTER TABLE  `varelagerline` ADD  `Department` VARCHAR( 128 ) NOT NULL ,
ADD  `Project` VARCHAR( 128 ) NOT NULL ,
ADD  `Shelf` VARCHAR( 128 ) NOT NULL ,
ADD  `UnitSize` FLOAT NOT NULL ,
ADD  `BulkSize` INT NOT NULL ,
ADD  `RealProductNumber` VARCHAR( 128 ) NOT NULL COMMENT  'ProductNr has been used for ProductID'


text:
#include "extensions/filters/network/thrift_proxy/router/config.h"

#include "envoy/registry/registry.h"

#include "extensions/filters/network/thrift_proxy/router/router_impl.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace ThriftProxy {
namespace Router {

ThriftFilters::FilterFactoryCb RouterFilterConfig::createFilterFactoryFromProtoTyped(
    const envoy::config::filter::thrift::router::v2alpha1::Router& proto_config,
    const std::string& stat_prefix, Server::Configuration::FactoryContext& context) {
  UNREFERENCED_PARAMETER(proto_config);
  UNREFERENCED_PARAMETER(stat_prefix);

  return [&context](ThriftFilters::FilterChainFactoryCallbacks& callbacks) -> void {
    callbacks.addDecoderFilter(std::make_shared<Router>(context.clusterManager()));
  };
}

/**
 * Static registration for the router filter. @see RegisterFactory.
 */
REGISTER_FACTORY(RouterFilterConfig, ThriftFilters::NamedThriftFilterConfigFactory);

} // namespace Router
} // namespace ThriftProxy
} // namespace NetworkFilters
} // namespace Extensions
} // namespace Envoy


text:
layout: default
modal-id: 10
date: 2018-03-10
title: Dreams
img: dreams-thumb.gif
alt: image-alt
project-date: July 2017
download: Google Play Store
source: Not Available
description: A VR gallery of experiences based on the theme: Dreams. Each experience was created by members of HVRE as part of a community project. Members were given the opportunity to create experiences as an individual within a larger community of developers and artists ready to help. Members were asked to brainstorm, establish a design document, manage the project scope, set goals, as well as publicly present project progress.
inspiration: I worked on Toy Room, one of the many experiences, by myself. Dreams was part of Rules and Play in 2017, an exhibition of interactive installation art, running at the Living Arts and Science Center in Lexington, KY.
---


text:
/*
 * Written by Robert Harder and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 */
package io.netty.handler.codec.base64;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

/**
 * Utility class for {@link ByteBuf} that encodes and decodes to and from
 * Base64 notation.
 *

 * The encoding and decoding algorithm in this class has been derived from
 * Robert Harder's Public Domain
 * Base64 Encoder/Decoder.
 */
public final class Base64 {

    /** Maximum line length (76) of Base64 output. */
    private static final int MAX_LINE_LENGTH = 76;

    /** The equals sign (=) as a byte. */
    private static final byte EQUALS_SIGN = (byte) '=';

    /** The new line character (\n) as a byte. */
    private static final byte NEW_LINE = (byte) '\n';

    private static final byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding

    private static final byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding

    private static byte[] alphabet(Base64Dialect dialect) {
        if (dialect == null) {
            throw new NullPointerException("dialect");
        }
        return dialect.alphabet;
    }

    private static byte[] decodabet(Base64Dialect dialect) {
        if (dialect == null) {
            throw new NullPointerException("dialect");
        }
        return dialect.decodabet;
    }

    private static boolean breakLines(Base64Dialect dialect) {
        if (dialect == null) {
            throw new NullPointerException("dialect");
        }
        return dialect.breakLinesByDefault;
    }

    public static ByteBuf encode(ByteBuf src) {
        return encode(src, Base64Dialect.STANDARD);
    }

    public static ByteBuf encode(ByteBuf src, Base64Dialect dialect) {
        return encode(src, breakLines(dialect), dialect);
    }

    public static ByteBuf encode(ByteBuf src, boolean breakLines) {
        return encode(src, breakLines, Base64Dialect.STANDARD);
    }

    public static ByteBuf encode(ByteBuf src, boolean breakLines, Base64Dialect dialect) {

        if (src == null) {
            throw new NullPointerException("src");
        }

        ByteBuf dest = encode(src, src.readerIndex(), src.readableBytes(), breakLines, dialect);
        src.readerIndex(src.writerIndex());
        return dest;
    }

    public static ByteBuf encode(ByteBuf src, int off, int len) {
        return encode(src, off, len, Base64Dialect.STANDARD);
    }

    public static ByteBuf encode(ByteBuf src, int off, int len, Base64Dialect dialect) {
        return encode(src, off, len, breakLines(dialect), dialect);
    }

    public static ByteBuf encode(
            ByteBuf src, int off, int len, boolean breakLines) {
        return encode(src, off, len, breakLines, Base64Dialect.STANDARD);
    }

    public static ByteBuf encode(
            ByteBuf src, int off, int len, boolean breakLines, Base64Dialect dialect) {

        if (src == null) {
            throw new NullPointerException("src");
        }
        if (dialect == null) {
            throw new NullPointerException("dialect");
        }

        int len43 = len * 4 / 3;
        ByteBuf dest = Unpooled.buffer(
                len43 +
                        (len % 3 > 0 ? 4 : 0) + // Account for padding
                        (breakLines ? len43 / MAX_LINE_LENGTH : 0)).order(src.order()); // New lines
        int d = 0;
        int e = 0;
        int len2 = len - 2;
        int lineLength = 0;
        for (; d < len2; d += 3, e += 4) {
            encode3to4(src, d + off, 3, dest, e, dialect);

            lineLength += 4;
            if (breakLines && lineLength == MAX_LINE_LENGTH) {
                dest.setByte(e + 4, NEW_LINE);
                e ++;
                lineLength = 0;
            } // end if: end of line
        } // end for: each piece of array

        if (d < len) {
            encode3to4(src, d + off, len - d, dest, e, dialect);
            e += 4;
        } // end if: some padding needed

        return dest.slice(0, e);
    }

    private static void encode3to4(
            ByteBuf src, int srcOffset, int numSigBytes,
            ByteBuf dest, int destOffset, Base64Dialect dialect) {

        byte[] ALPHABET = alphabet(dialect);

        //           1         2         3
        // 01234567890123456789012345678901 Bit position
        // --------000000001111111122222222 Array position from threeBytes
        // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
        //          >>18  >>12  >> 6  >> 0  Right shift necessary
        //                0x3f  0x3f  0x3f  Additional AND

        // Create buffer with zero-padding if there are only one or two
        // significant bytes passed in the array.
        // We have to shift left 24 in order to flush out the 1's that appear
        // when Java treats a value as negative that is cast from a byte to an int.
        int inBuff =
                (numSigBytes > 0? src.getByte(srcOffset)     << 24 >>>  8 : 0) |
                (numSigBytes > 1? src.getByte(srcOffset + 1) << 24 >>> 16 : 0) |
                (numSigBytes > 2? src.getByte(srcOffset + 2) << 24 >>> 24 : 0);

        switch (numSigBytes) {
        case 3:
            dest.setByte(destOffset    , ALPHABET[inBuff >>> 18       ]);
            dest.setByte(destOffset + 1, ALPHABET[inBuff >>> 12 & 0x3f]);
            dest.setByte(destOffset + 2, ALPHABET[inBuff >>>  6 & 0x3f]);
            dest.setByte(destOffset + 3, ALPHABET[inBuff        & 0x3f]);
            break;
        case 2:
            dest.setByte(destOffset    , ALPHABET[inBuff >>> 18       ]);
            dest.setByte(destOffset + 1, ALPHABET[inBuff >>> 12 & 0x3f]);
            dest.setByte(destOffset + 2, ALPHABET[inBuff >>> 6  & 0x3f]);
            dest.setByte(destOffset + 3, EQUALS_SIGN);
            break;
        case 1:
            dest.setByte(destOffset    , ALPHABET[inBuff >>> 18       ]);
            dest.setByte(destOffset + 1, ALPHABET[inBuff >>> 12 & 0x3f]);
            dest.setByte(destOffset + 2, EQUALS_SIGN);
            dest.setByte(destOffset + 3, EQUALS_SIGN);
            break;
        }
    }

    public static ByteBuf decode(ByteBuf src) {
        return decode(src, Base64Dialect.STANDARD);
    }

    public static ByteBuf decode(ByteBuf src, Base64Dialect dialect) {

        if (src == null) {
            throw new NullPointerException("src");
        }

        ByteBuf dest = decode(src, src.readerIndex(), src.readableBytes(), dialect);
        src.readerIndex(src.writerIndex());
        return dest;
    }

    public static ByteBuf decode(
            ByteBuf src, int off, int len) {
        return decode(src, off, len, Base64Dialect.STANDARD);
    }

    public static ByteBuf decode(
            ByteBuf src, int off, int len, Base64Dialect dialect) {

        if (src == null) {
            throw new NullPointerException("src");
        }
        if (dialect == null) {
            throw new NullPointerException("dialect");
        }

        byte[] DECODABET = decodabet(dialect);

        int len34 = len * 3 / 4;
        ByteBuf dest = Unpooled.buffer(len34).order(src.order()); // Upper limit on size of output
        int outBuffPosn = 0;

        byte[] b4 = new byte[4];
        int b4Posn = 0;
        int i;
        byte sbiCrop;
        byte sbiDecode;
        for (i = off; i < off + len; i ++) {
            sbiCrop = (byte) (src.getByte(i) & 0x7f); // Only the low seven bits
            sbiDecode = DECODABET[sbiCrop];

            if (sbiDecode >= WHITE_SPACE_ENC) { // White space, Equals sign or better
                if (sbiDecode >= EQUALS_SIGN_ENC) { // Equals sign or better
                    b4[b4Posn ++] = sbiCrop;
                    if (b4Posn > 3) { // Quartet built
                        outBuffPosn += decode4to3(
                                b4, 0, dest, outBuffPosn, dialect);
                        b4Posn = 0;

                        // If that was the equals sign, break out of 'for' loop
                        if (sbiCrop == EQUALS_SIGN) {
                            break;
                        }
                    }
                }
            } else {
                throw new IllegalArgumentException(
                        "bad Base64 input character at " + i + ": " +
                        src.getUnsignedByte(i) + " (decimal)");
            }
        }

        return dest.slice(0, outBuffPosn);
    }

    private static int decode4to3(
            byte[] src, int srcOffset,
            ByteBuf dest, int destOffset, Base64Dialect dialect) {

        byte[] DECODABET = decodabet(dialect);

        if (src[srcOffset + 2] == EQUALS_SIGN) {
            // Example: Dk==
            int outBuff =
                    (DECODABET[src[srcOffset    ]] & 0xFF) << 18 |
                    (DECODABET[src[srcOffset + 1]] & 0xFF) << 12;

            dest.setByte(destOffset, (byte) (outBuff >>> 16));
            return 1;
        } else if (src[srcOffset + 3] == EQUALS_SIGN) {
            // Example: DkL=
            int outBuff =
                    (DECODABET[src[srcOffset    ]] & 0xFF) << 18 |
                    (DECODABET[src[srcOffset + 1]] & 0xFF) << 12 |
                    (DECODABET[src[srcOffset + 2]] & 0xFF) <<  6;

            dest.setByte(destOffset    , (byte) (outBuff >>> 16));
            dest.setByte(destOffset + 1, (byte) (outBuff >>>  8));
            return 2;
        } else {
            // Example: DkLE
            int outBuff;
            try {
                outBuff =
                        (DECODABET[src[srcOffset    ]] & 0xFF) << 18 |
                        (DECODABET[src[srcOffset + 1]] & 0xFF) << 12 |
                        (DECODABET[src[srcOffset + 2]] & 0xFF) <<  6 |
                         DECODABET[src[srcOffset + 3]] & 0xFF;
            } catch (IndexOutOfBoundsException e) {
                throw new IllegalArgumentException("not encoded in Base64");
            }

            dest.setByte(destOffset    , (byte) (outBuff >> 16));
            dest.setByte(destOffset + 1, (byte) (outBuff >>  8));
            dest.setByte(destOffset + 2, (byte)  outBuff);
            return 3;
        }
    }

    private Base64() {
        // Unused
    }
}