text:
from __future__ import division
from collections import namedtuple
from math import ceil, cos, floor, pi, sin, sqrt, trunc
from operator import __truediv__
from random import uniform

PointTuple = namedtuple('PointTuple', ('x', 'y'))

class Point(PointTuple):

    def __new__(cls, x, y):
        assert isinstance(x, float) or isinstance(x, int) or isinstance(x, bool) or isinstance(x, str)
        assert isinstance(y, float) or isinstance(y, int) or isinstance(y, bool) or isinstance(y, str)
        if isinstance(x, str) and isinstance(y, str):
            x = float(x)
            y = float(y)
        return super(Point, cls).__new__(cls, x, y)

    @staticmethod
    def from_angle(angle):
        assert isinstance(angle, float) and 0.0 <= angle < 1.0
        angle = angle * 2.0 * pi
        return Point(cos(angle), sin(angle))

    def __str__(self):
        return '({}/{})'.format(self.x, self.y)

    def model(self):
        return {'x': self.x, 'y': self.y}

    @staticmethod
    def from_model(model):
        return Point(x=model['x'], y=model['y'])

    def lower(self):
        return min(self.x, self.y)

    def upper(self):
        return max(self.x, self.y)

    def length(self):
        return sqrt(self.x * self.x + self.y * self.y)

    def distance(self, other):
        x_diff = self.x - other.x
        y_diff = self.y - other.y
        return sqrt(x_diff * x_diff + y_diff * y_diff)

    def is_right(self, angle):
        assert isinstance(angle, float) and 0.0 <= angle < 1.0
        angle = angle * 2.0 * pi
        return self.x * sin(angle) - self.y * cos(angle) > 0.0

    def __eq__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x == other.x and self.y == other.y
        else:
            return self.x == other and self.y == other

    def __ne__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x != other.x or self.y != other.y
        else:
            return self.x != other or self.y != other

    def __lt__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x < other.x and self.y < other.y
        else:
            return self.x < other and self.y < other

    def __gt__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x > other.x and self.y > other.y
        else:
            return self.x > other and self.y > other

    def __le__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x <= other.x and self.y <= other.y
        else:
            return self.x <= other and self.y <= other

    def __ge__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return self.x >= other.x and self.y >= other.y
        else:
            return self.x >= other and self.y >= other

    def __pos__(self):
        return Point(self.x, self.y)

    def __neg__(self):
        return Point(-self.x, -self.y)

    def __add__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x + other.x, self.y + other.y)
        else:
            return Point(self.x + other, self.y + other)

    def __sub__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x - other.x, self.y - other.y)
        else:
            return Point(self.x - other, self.y - other)

    def __mul__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x * other.x, self.y * other.y)
        else:
            return Point(self.x * other, self.y * other)

    def __truediv__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(__truediv__(self.x, other.x), __truediv__(self.y, other.y))
        else:
            return Point(__truediv__(self.x, other), __truediv__(self.y, other))

    def __floordiv__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x // other.x, self.y // other.y)
        else:
            return Point(self.x // other, self.y // other)

    def __div__(self, other):
        return self.__truediv__(other)

    def __mod__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x % other.x, self.y % other.y)
        else:
            return Point(self.x % other, self.y % other)

    def __divmod__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(self.x // other.x, self.y // other.y), Point(self.x % other.x, self.y % other.y)
        else:
            return Point(self.x // other, self.y // other), Point(self.x % other, self.y % other)

    def __pow__(self, other, modulo=None):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if modulo is None:
            if isinstance(other, Point):
                return Point(self.x ** other.x, self.y ** other.y)
            else:
                return Point(self.x ** other, self.y ** other)
        else:
            if isinstance(other, Point):
                return Point(pow(self.x, other.x, modulo), pow(self.y, other.y, modulo))
            else:
                return Point(pow(self.x, other, modulo), pow(self.y, other, modulo))

    def __radd__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other + self.x, other + self.y)

    def __rsub__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other - self.x, other - self.y)

    def __rmul__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other * self.x, other * self.y)

    def __rtruediv__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(__truediv__(other, self.x), __truediv__(other, self.y))

    def __rfloordiv__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other // self.x, other // self.y)

    def __rmod__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other % self.x, other % self.y)

    def __rdivmod__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other // self.x, other // self.y), Point(other % self.x, other % self.y)

    def __rpow__(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool)
        return Point(other ** self.x, other ** self.y)

    def __abs__(self):
        if isinstance(self.x, bool):
            return Point(self.x, self.y)
        else:
            return Point(abs(self.x), abs(self.y))

    def __round__(self, n=0):
        return Point(round(self.x, n), round(self.y, n))

    def __floor__(self):
        return Point(floor(self.x), floor(self.y))

    def __ceil__(self):
        return Point(ceil(self.x), ceil(self.y))

    def __trunc__(self):
        return Point(trunc(self.x), trunc(self.y))

    def square(self):
        return Point(self.x * self.x, self.y * self.y)

    def sum(self):
        return self.x + self.y

    def positive(self):
        if isinstance(self.x, bool):
            return Point(self.x, self.y)
        elif isinstance(self.x, int):
            return Point(max(self.x, 0), max(self.y, 0))
        else:
            return Point(max(self.x, 0.0), max(self.y, 0.0))

    def min(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(min(self.x, other.x), min(self.y, other.y))
        else:
            return Point(min(self.x, other), min(self.y, other))

    def max(self, other):
        assert isinstance(other, float) or isinstance(other, int) or isinstance(other, bool) or isinstance(other, Point)
        if isinstance(other, Point):
            return Point(max(self.x, other.x), max(self.y, other.y))
        else:
            return Point(max(self.x, other), max(self.y, other))

    def rotate(self, angle_sin, angle_cos):
        return Point(self.x * angle_cos - self.y * angle_sin, self.x * angle_sin + self.y * angle_cos)

    @staticmethod
    def range(start, end=None, size=None):
        assert isinstance(start, Point)
        assert end is None or isinstance(end, Point)
        assert size is None or isinstance(size, Point)
        if end is None:
            end = start.__ceil__()
            start = Point.izero
        else:
            start = start.__floor__()
            end = end.__ceil__()
        assert start <= end
        if size is None:
            for x in range(int(start.x), int(end.x)):
                for y in range(int(start.y), int(end.y)):
                    yield Point(x, y)
        else:
            size -= Point.ione
            for x in range(int(start.x), int(end.x)):
                for y in range(int(start.y), int(end.y)):
                    point = Point(x, y)
                    yield point, Point(x / size.x, y / size.y)

    @staticmethod
    def random_instance(topleft, bottomright):
        return Point(uniform(topleft.x, bottomright.x), uniform(topleft.y, bottomright.y))

Point.zero = Point(0.0, 0.0)
Point.one = Point(1.0, 1.0)
Point.neg_one = Point(-1.0, -1.0)
Point.half = Point(0.5, 0.5)

Point.izero = Point(0, 0)
Point.ione = Point(1, 1)
Point.right = Point(1, 0)
Point.top_right = Point(1, 1)
Point.top = Point(0, 1)
Point.top_left = Point(-1, 1)
Point.left = Point(-1, 0)
Point.bottom_left = Point(-1, -1)
Point.bottom = Point(0, -1)
Point.bottom_right = Point(1, -1)
Point.directions = (Point.right, Point.top, Point.left, Point.bottom)
Point.directions_ext = (Point.right, Point.top_right, Point.top, Point.top_left, Point.left, Point.bottom_left, Point.bottom, Point.bottom_right)


text:
\documentclass[11pt,spanish]{article}

%----------------------------------------------------------------------------------------
% Codificación, y usar una fuente similar a la Palatino (y no Latin Modern Roman)
\usepackage[utf8]{inputenc} % Acentos, etc.
\usepackage[spanish]{babel} % Castellano
\usepackage{tgpagella}      % Fuente similar a Palatino
\usepackage[T1]{fontenc}

%----------------------------------------------------------------------------------------
% MODIFICAR EL ESTILO DE LAS SECCIONES Y EL ABSTRACT
\usepackage{titlesec}
\titleformat{\section}{\bfseries\Large}{\thesection.}{0.6em}{}
\titleformat{\subsection}{\bfseries\large}{\thesubsection.}{0.6em}{}
\titleformat{\subsubsection}{\bfseries\large}{\thesubsubsection.}{0.6em}{}
%\newcommand{\sectionbreak}{\clearpage} % Empezar secciones en nueva página

\renewenvironment{abstract}
 {\small\em
  \vspace{2mm}
  \list{}{%
    \setlength{\leftmargin}{2.5mm}% <- -- -- -- -- - Cambiar márgenes
    \setlength{\rightmargin}{\leftmargin}%
  }%
  \item\relax}
 {\endlist}

% Incluir Anexos
\usepackage[title,titletoc,toc]{appendix}

%----------------------------------------------------------------------------------------
% COLORES
\usepackage{xcolor}
\usepackage{color}
\newcommand{\termWhite}[1]{\textcolor{white}{\ttfamily{#1}}} % MDFRAMED: shell
\newcommand{\termGray}[1]{\textcolor[RGB]{175,175,175}{\ttfamily{#1}}} % MDFRAMED: shell
\newcommand{\termGreen}[1]{\textcolor[RGB]{136,249,57}{\ttfamily{#1}}} % MDFRAMED: shell
\newcommand{\termPurple}[1]{\textcolor[RGB]{76,80,173}{\ttfamily{#1}}} % MDFRAMED: shell
\newcommand{\termRed}[1]{\textcolor{red}{\textbf{#1}}}                 % MDFRAMED: important

\definecolor{gitkeyword}{RGB}{143,35,92}
\definecolor{gitstring}{RGB}{218,98,7}
\definecolor{gitcomment}{RGB}{150,151,149}

%----------------------------------------------------------------------------------------
% Imagenes: Que se pongan donde yo quiero
\usepackage{graphicx}
\DeclareGraphicsExtensions{.eps,.ps,.pdf,.png,.jpg,.jpeg}

%----------------------------------------------------------------------------------------
% CAJAS DE TEXTO: TERMINAL

\newcommand{\shellRC}{\termGray{a611244@central}> }

\usepackage[framemethod=tikz]{mdframed}
\mdfdefinestyle{termStyle}{
    font=\footnotesize\ttfamily,
    linecolor=black,outerlinewidth=2pt,
    leftmargin=0pt, rightmargin=0pt,
    backgroundcolor=black,fontcolor=white,
    innermargin=2pt, roundcorner=1pt,
    splittopskip=20pt, splitbottomskip=20pt,
}
\newmdenv[style=termStyle]{exa}
\newenvironment{terminal}
  {\vspace{0.5em}\begin{exa}}
  {\end{exa}\vspace{1em}}

%----------------------------------------------------------------------------------------
% ALGORITMOS

\usepackage{listings}

% Comando para lstset -> ARM
\lstdefinestyle{c}{%
	language=C,%
	showspaces=false, showtabs=false,%
	showstringspaces=false,%
	basicstyle=\scriptsize\ttfamily,%
	tabsize=3,%
	breaklines=true,%
	keywordstyle=\color{gitkeyword}\bfseries,
	stringstyle=\color{gitstring},
	commentstyle=\color{gitcomment},
	morecomment=[s][\color{gitcomment}]{/**}{*/}
}

% Plain text style listing
\lstdefinestyle{plain}{%
	language={},%
	basicstyle=\footnotesize\ttfamily,%
	showspaces=false,showtabs=false,showstringspaces=false,%
	tabsize=3,breaklines=true,%
	numbers=left, numberstyle=\ttfamily\tiny\color{gray},%
	stepnumber=1, numbersep=5pt,%
}

%----------------------------------------------------------------------------------------
% ASPECTOS DEL FORMATO
\newcommand{\singlelinebreak}{\\[\baselineskip]}
\newcommand{\multiplelinebreak}[1]{\\[#1\baselineskip]}
\usepackage{geometry}
\newgeometry{top=5em}
\newcommand{\tab}{\indent\hspace{5mm}}
\newcommand{\brkline}{\leavevmode{\parindent=1em\indent}}

% Cortar lineas en fuente tt
\newcommand*\justify{%
  \fontdimen2\font=0.4em% interword space
  \fontdimen3\font=0.2em% interword stretch
  \fontdimen4\font=0.1em% interword shrink
  \fontdimen7\font=0.1em% extra space
  \hyphenchar\font=`\-% allowing hyphenation
}

\newcommand{\code}[1]{\texttt{\justify #1}}

%----------------------------------------------------------------------------------------
% TABLE OF CONTENTS
\AtBeginDocument{
  \addtocontents{toc}{\footnotesize}
  %\addtocontents{lof}{\footnotesize}
}
\usepackage{tocloft}
\setlength\cftaftertoctitleskip{0pt}
\setlength{\cftbeforetoctitleskip}{-0.5em}
\addto\captionsspanish{\renewcommand\contentsname{}}

%----------------------------------------------------------------------------------------
% METADATOS DEL PDF Y PDF CLICKEABLE
\usepackage{hyperref}
\usepackage{hyperxmp}
\providecommand\phantomsection{} % Necesario para hyperref
\usepackage{url}

\newcommand\docsubject{SISTEMAS EMPOTRADOS II}
\newcommand\doctitle{Trabajo de laboratorio}

\hypersetup{
	baseurl={611244@unizar.es},
	pdftitle={\doctitle},
	pdfauthor={Simón Ortego Parra},
	pdfsubject={\docsubject. EINA. Unizar},
	pdfkeywords={},
	pdfcopyright={Copyright (C) 2014 by Simón Ortego Parra. All rights reserved.},
	pdfproducer={PDFLatex},
	pdfcreator={ps2pdf},
	colorlinks=false
}

\usepackage{cleveref} % load after hyperref package
\crefdefaultlabelformat{\textbf{#2#1#3}} % boldface only the number

\crefname{figure}{figura}{figuras}
\Crefname{figure}{Figura}{Figuras}

\crefname{listing}{algoritmo}{algoritmos}
\Crefname{listing}{Algoritmo}{Algoritmos}

\crefname{section}{sección}{secciones}
\Crefname{section}{Sección}{Secciones}

\crefname{appendix}{anexo}{anexos}
\Crefname{appendix}{Anexo}{Anexos}

%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
% INICIO DEL DOCUMENTO
%----------------------------------------------------------------------------------------

\begin{document}
\noindent
{\huge\bf \docsubject}\multiplelinebreak{1.5}
{\huge\tt \doctitle}\singlelinebreak
{\Large\it Simón Ortego Parra}\\
\rule{\textwidth}{1.5pt}

%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
\section{Descripción del problema}
Se trata de modelar un programa concurrente con restricciones tiempo real en el cual
varias tareas periódicas acceden a unos servidores compartidos con el fin de realizar
una sincronización. Los servidores ofrecen una serie de funciones, cada una de ellas
es accesible únicamente en exclusión mutua.

El tener restricciones de tiempo real implica que las tareas tengan asignadas prioridades
estáticas, definidas en función de la urgencia del cumplimiento de sus plazos de
entrega. En principio, una tarea de mayor prioridad no tiene por qué verse afectada por
tareas de prioridad inferior al compartir recursos con estas últimas. En caso contrario,
se provocan las denominadas inversiones de prioridad. El análisis de este tipo de situaciones
y la garantía del cumplimiento de los plazos de las tareas es el objetivo de este trabajo.

El desarrollo del trabajo se ha realizado sobre un kernel de linux de tiempo real (en
concreto, el patch PREEMPT\_RT), y se ha utilizado la interfaz de programación POSIX.

%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
\section{Desarrollo del algoritmo básico}
El algoritmo básico del cual partir para más adelante realizar el análisis temporal y de
cumplimiento de plazos consta de tres partes claramente diferenciadas. Un programa
principal, en el cual se ponen en funcionamiento todas las partes; las tareas periódicas y los
servidores de acceso concurrente. Se ha realizado en cada parte una programación lo más
genérica posible, con el fin de poder reutilizar el código, y que el algoritmo sea lo más
conciso y claro posible. A continuación se examinan cada una de las partes.

\subsection{Tareas periódicas}
Lo primero a realizar para cada tarea es la inicialización. Ya que se implementan
sobre la interfaz POSIX, esto además implica establecer los atributos apropiados para los
hilos (\code{pthreads}) que ejecutan el código de cada una de las tareas. En la función
\code{create\_tasks()} se inicializan todas las tareas con los parámetros (\code{task\_params})
y los atributos de los \code{pthreads} apropiados.

Las tareas periódicas ejecutan una función específica, pero el comportamiento temporal
y la estructura es para todas la misma. A continuación se muestra un extracto de código
en dónde se puede apreciar la función genérica utilizada como base para todas tareas
(\code{periodic\_task()}). El parámetro que se le pasa a la función genérica contiene,
entre otras cosas, la dirección de la función específica que ejecuta cada una de las
diferentes tareas.

\begin{lstlisting}[style=c]
void periodic_task(void *task)
{
    int task_id;
    void (*task_body) (struct timespec, events_history *);
    events_history *history;
    struct timespec next, comp_time, period;

    task_id = ((task_params *) task) -> task_id;
    task_body = ((task_params *) task) -> task_body;
    history = ((task_params *) task) -> history;

    /* Fills the TIMESPEC struct from the computation time given in milliseconds */
    comp_time.tv_sec = ((task_params *) task) -> computation_time / MILLIS_IN_ONE_SEC;
    comp_time.tv_nsec = (((task_params *) task) -> computation_time % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    /* Fills the TIMESPEC struct from the period value given in milliseconds */
    period.tv_sec = ((task_params *) task) -> period / MILLIS_IN_ONE_SEC;
    period.tv_nsec = (((task_params *) task) -> period % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    if (clock_gettime (CLOCK_MONOTONIC, &next)) {
        fprintf(stderr, "T%d: periodic_task(): failed to get the current time: ", task_id);
        perror(NULL);
        return;
    }
    add_event(TASK_BIRTH, 0, history);

    /* Main loop of the task */
    int i;
    add_event(TASK_ACTIVATION, 0, history);
    for (i = 0; i < NUM_TASK_ITERATIONS; i++) {
        task_body(comp_time,history);
        add_event(TASK_FINISHED, 0, history);
        next = tsAdd(next, period);
        clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &next, 0);
        add_event(TASK_ACTIVATION, 0, history);
    }

    add_event(TASK_DEATH, 0, history);
    pthread_exit(task);
}
\end{lstlisting}

Ahora, tan sólo es necesario realizar la función que se le pasa como parámetro a esta
función genérica comentada con anterioridad, de tal forma que, en el cuerpo de la función
genérica, para cada tarea, se realice una llamada a la función correspondiente. Un ejemplo de las
funciones específicas se puede observar a continuación (para el caso de la tarea 1).

\begin{lstlisting}[style=c]
void t1_body(struct timespec comp_time, events_history *history)
{
    add_event(TASK_BUSY, 0, history);
    calc(comp_time); /* doing stuff */
    s11(1, history);
}
\end{lstlisting}

Lo único que falta por aclarar es el qué ejecuta cada tarea periódicamente (en el algoritmo
anterior aparece una llamada a la función \code{calc()}, que no es más que un código arbitrario
que mantiene a la tarea ocupada durante el tiempo que se le pase como parámetro.
Esta función se detalla en la siguiente sección.

\subsubsection{Tiempos de cómputo}
Con el fin de garantizar unos tiempos de cómputo constantes para cada una de las tareas, y así
poder realizar el análisis temporal correctamente, se ha programado una función que
realiza una espera activa hasta que haya transcurrido el tiempo que se le pase como parámetro
(es importante recalcar lo de espera activa: la tarea no se puede dormir ya que se supone que
se está modelando un sistema en el cual la tarea estaría ejecutando una sección de código real,
que dura aproximadamente el tiempo de cómputo que se le pasa a la función como parámetro).

\begin{lstlisting}[style=c]
void calc (struct timespec ms)
{
    struct timespec now, end;

    clock_gettime(CLOCK_REALTIME, &now);
    end = tsAdd(now, ms);

    while (tsCompare(now, end) != 1) {
        clock_gettime(CLOCK_REALTIME, &now);
    }
}
\end{lstlisting}

\subsection{Servidores}
La metodología de programación a la hora de realizar los servidores es exactamente
la misma.

Al igual que las tareas, los servidores requieren de una inicialización (\code{create\_servers()}).

También, se ha programado una función genérica (\code{server\_function()}), a la
que se le pasa como parámetros una serie de datos para distinguir cada una de las
funciones de los servidores ya específicas. Dicha función genérica aparece a
continuación.

\begin{lstlisting}[style=c]
void server_function (unsigned int func_id, struct timespec comp_time, pthread_mutex_t *mutex, events_history *history)
{
    add_event(SERVER_ENTRY, func_id, history);

	/* tries to aquire mutex */
    add_event(MUTEX_LOCK, func_id, history);
	pthread_mutex_lock(mutex);

	/* --- Critical Section ----- */
    add_event(MUTEX_AQUIRE, func_id, history);
	calc(comp_time);
	/* ------------------------- */

	/* releases mutex */
    add_event(MUTEX_RELEASE, func_id, history);
	pthread_mutex_unlock(mutex);

	add_event(SERVER_EXIT, func_id, history);
}
\end{lstlisting}

De nuevo, se ha utilizado la función genérica en cada una de las diferentes
funciones que ofrece como interfaz el servidor. Un ejemplo se muestra en el siguiente
extracto.

\begin{lstlisting}[style=c]
void s11 (int task_id, events_history *history)
{
	server_function (S11, s11_comp_time, &s1_mutex, history);
}
\end{lstlisting}

\subsection{Programa principal}
En el programa principal se inicializan las tareas, los servidores y se ponen
en funcionamiento las tareas, cada una de ellas en un \code{pthread} diferente.
En algún momento, acaba el programa (se ha limitado la ejecución de las tareas a un
número de iteraciones), y entonces se realiza la labor de liberación de recursos, etc.

Este programa principal, que representa el punto de entrada del programa concurrente,
se muestra (con alguna edición) en el siguiente extracto de código.

\begin{lstlisting}[style=c]
int main (int argc, char **argv)
{
    /* Threads that execute tasks and its attributes */
    pthread_t threads[NUM_TASKS];
    pthread_attr_t thread_attributes[NUM_TASKS];

    /* Timespec structure to set the timer to zero at
     * the beginning of the program execution */
    struct timespec start;

    /* Data needed for the execution of each periodic task:
     * id, period, computation time & task code executed */
    task_params params[NUM_TASKS];

    /* Set the parameters for the tasks (including thread attributes) */
    create_tasks(threads, thread_attributes, params);

    /* Create the servers, which the tasks make use of */
    create_servers();

    /* Initialize clock */
    start.tv_sec = 0;
    start.tv_nsec = 0;
    if (clock_settime(CLOCK_REALTIME, &start)) {
        fprintf(stderr, "main(): failed to reset the timer: ");
        perror(NULL);
        return -1;
    }

    int i;
    /* Create one independent thread for each task */
    for (i = 0; i < NUM_TASKS; i++) {
        if (pthread_create(&threads[i], &thread_attributes[i], (void *)periodic_task, &params[i])) {
            fprintf(stderr, "pthread_create(): failed to create thread#%d: ", i);
            perror(NULL);
            return -1;
        }
    }

    /* Dead code (supposedly, if tasks run forever) */
    for (i = 0; i < NUM_TASKS; i++) {
        if (pthread_join(threads[i], NULL)) {
            fprintf(stderr, "pthread_join(): Thread %d did not terminate normally: ", i);
            perror(NULL);
            return -1;
        }
        print_events(*params[i].history);
        clear_history(params[i].history);
    }

    return 0;
}
\end{lstlisting}

%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
\section{Análisis de tiempo real}

\subsection{Recolección de eventos. Temporización}
Antes de poder realizar ninguna clase de análisis, es necesario tener (si no se realiza
de manera teórica) un historial de eventos para así poder sacar conclusiones.

Se han programado una serie de funciones para recolectar los eventos que se deseen
en los instantes que se estime oportuno. Éstas se describen a continuación.

\subsubsection{Inicialización}
Ya que en primera instancia se desconoce el número de eventos que va a ser capturado,
se ha pensado que éstos no pueden ser almacenados en una estructura estática porque
resulta complicado dimensionarla sin que haya desbordamientos y se pierdan eventos o, se
reserve una cantidad de memoria innecesaria.

Como se puede apreciar a continuación, se ha definido la estructura dónde almacenar los
eventos como una lista encadenada simple.

\begin{lstlisting}[style=c]
/* events.h */
...
#define TASK_BIRTH 0
#define TASK_ACTIVATION 1
#define TASK_BUSY 2
#define TASK_FINISHED 3
#define SERVER_ENTRY 4
#define MUTEX_LOCK 5
#define MUTEX_AQUIRE 6
#define MUTEX_RELEASE 7
#define SERVER_EXIT 8
#define TASK_DEATH 9

typedef struct event {
    unsigned char type, server_id;
    struct timespec timestamp;
    struct event *next_event;
} event;

typedef struct events_history {
	int task_id, task_comp_time;
	event *first_event, *last_event;
} events_history;
\end{lstlisting}

En la inicialización de la lista simplemente se reserva una cantidad de memoria para la estructura
que almacenará los eventos:

\begin{lstlisting}[style=c]
events_history *create_events_history (int task_id)
{
	events_history *new_history;
	new_history = malloc(sizeof(events_history));
	if (new_history != NULL) {
		new_history->task_id = task_id;
		new_history->first_event = NULL;
		new_history->last_event = NULL;
	}
	return new_history;
}
\end{lstlisting}

\subsubsection{Almacenar un evento}
En el momento de la ejecución de una tarea que se desee tener registro de un evento,
se realizará una llamada a la función \code{add\_event()}, que almacenará dicho evento
en la estructura comentada con anterioridad. En esta función, se eleva la prioridad
del hilo que la ejecuta a la máxima, para que no haya expulsión. Una vez se tiene registro
del evento, se vuelve a bajar la prioridad.

\begin{lstlisting}[style=c]
void add_event (unsigned char type, unsigned char server_id, events_history *history)
{
    int thread_priority;
    pthread_attr_t thread_attr;
    struct sched_param thread_sched;
    struct timespec timestamp;
	event *new_event;

    // Retrieve the thread attributes and with those, the scheduling parameters: thread priority
    if (pthread_getattr_np(pthread_self(), &thread_attr)) {
        fprintf(stderr, "add_event(): failed to get the running thread attributes: ");
        perror(NULL);
        return;
    } else if (pthread_attr_getschedparam(&thread_attr, &thread_sched)) {
        fprintf(stderr, "add_event(): failed to get the running thread scheduling parameters (priority): ");
        perror(NULL);
        return;
    }

    // Save the current thread's priority
    thread_priority = thread_sched.sched_priority;

    // Set the thread's priority to the max level
    if (pthread_setschedprio(pthread_self(), max_sched_priority)) {
        fprintf(stderr, "add_event(): failed to elevate the thread's priority: ");
        perror(NULL);
        return;
    }

   	clock_gettime(CLOCK_REALTIME, &timestamp);
	new_event = malloc(sizeof(event));

	if (new_event != NULL) {
		/* if could allocate memory for the new event */
		new_event->type = type;
		new_event->server_id = server_id;
		new_event->timestamp.tv_sec = timestamp.tv_sec;
		new_event->timestamp.tv_nsec = timestamp.tv_nsec;
		new_event->next_event = NULL;

		if (history->last_event != NULL) {
			/* if history is not empty */
			history->last_event->next_event = new_event;
		} else {
			/* if history is empty */
			history->first_event = new_event;
		}
		history->last_event = new_event;
	} else {
        fprintf(stderr, "add_event(): could not allocate memory for new event: ");
	}

    // Restore the original thread priority
    if (pthread_setschedprio(pthread_self(), thread_priority)) {
        fprintf(stderr, "add_event(): failed to restore the thread's priority: ");
        perror(NULL);
        return;
    }
}\end{lstlisting}

\subsubsection{Imprimir los eventos y liberar la memoria}
Únicamente cuando ha terminado la ejecución del programa concurrente (todas las
tareas han terminado), se muestra por pantalla la recolección de eventos (\code{print\_event()}),
y a continuación, se libera la memoria reservada (\code{clear\_history()}).

\subsection{Inversión de prioridad. Protocolo de Techo de Prioridad Inmediato}
Después de realizar la versión sencilla, se ha pasado a utilizar el protocolo
de techo de prioridad inmediato para así evitar las inversiones de prioridad provocadas
por el acceso a recursos compartidos entre las diferentes tareas.

Esto implica únicamente modificar el comportamiento de los mutex que protegen
la sección crítica de las funciones de los servidores que son llamadas por las tareas.
A continuación se muestra dicha modificación.

\begin{lstlisting}[style=c]
void create_servers (void)
{
	pthread_mutexattr_t s1_mutex_attr, s2_mutex_attr;

    /* server 1 - function 1 */
    s11_comp_time.tv_sec = S11_COMP_TIME / MILLIS_IN_ONE_SEC;
    s11_comp_time.tv_nsec = (S11_COMP_TIME % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    /* server 1 - function 2 */
    s12_comp_time.tv_sec = S12_COMP_TIME / MILLIS_IN_ONE_SEC;
    s12_comp_time.tv_nsec = (S12_COMP_TIME % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    /* Init mutex for ICPP (ceiling = highest priority task, T1) */
    pthread_mutexattr_setprotocol(&s1_mutex_attr, PTHREAD_PRIO_PROTECT);
    pthread_mutexattr_setprioceiling (&s1_mutex_attr, T1_PRIORITY);
    pthread_mutex_init(&s1_mutex, &s1_mutex_attr);

    /* server 2 - function 1 */
    s21_comp_time.tv_sec = S21_COMP_TIME / MILLIS_IN_ONE_SEC;
    s21_comp_time.tv_nsec = (S21_COMP_TIME % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    /* server 2 - function 2 */
    s22_comp_time.tv_sec = S22_COMP_TIME / MILLIS_IN_ONE_SEC;
    s22_comp_time.tv_nsec = (S22_COMP_TIME % MILLIS_IN_ONE_SEC) * NANOS_IN_MILLIS;

    /* Init mutex for ICPP (ceiling = highest priority task, T2) */
    pthread_mutexattr_setprotocol(&s2_mutex_attr, PTHREAD_PRIO_PROTECT);
    pthread_mutexattr_setprioceiling (&s2_mutex_attr, T2_PRIORITY);
    pthread_mutex_init(&s2_mutex, &s2_mutex_attr);
}
\end{lstlisting}

%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------

\section{Bolas extra}
Además de la recolección de eventos básica, se quería realizar una recolección
de eventos más fina, para determinar de manera exacta y con total precisión los instantes de
expulsión de las tareas. El trabajo realizado (sin acabar) está en un repositorio de Github
(\url{https://github.com/saimusdev/bone-rt}).

Se pretendía modificar la función \code{\_\_schedule()} de Linux, para que en el instante
de expulsión de una tarea, se almacene junto con una estampilla temporal, el identificador de
proceso de la tarea expulsada. El almacenamiento de esta clase de eventos se podría realizar
basándose en el código ya realizado en este trabajo, pero utilizando un módulo del Kernel
(compilado junto con el Kernel) para que al ser cargado active un flag (variable global) que
le indique al planificador de Linux que haga una llamada (\code{write()}, por ejemplo) para
almacenar la información pertinente en un buffer.

Se ha conseguido imprimir por pantalla los pids de todos los procesos en el instante de
expulsión (inútil), y también se ha conseguido compilar un driver (utilizando la convención
de Linux para añadirlo dentro de la jerarquía de directorios del kernel y no fuera: Kconfig, Makefile,...)
No se han conseguido utilizar variables globales al desconocer dónde realizar la declaración
para ser visible en todo el kernel (y que no falle la compilación) y tampoco se ha conseguido
realizar una llamada \code{ioctl()} o \code{write()} sencilla al driver, por falta de tiempo.

\section{Metodología de trabajo. Entorno de desarrollo}
Además de la configuración de una máquina virtual Linux para poder trabajar
desde casa, y poder realizar la compilación cruzada, el formateado de la tarjeta sd, etc.
(aspectos que obviamente no entran dentro del ámbito de esta asignatura); se quiere
hacer hincapié en una serie de herramientas que han sido imprescindibles para agilizar
el desarrollo y evitar quebraderos de cabeza:

\begin{itemize}
	\item \code{make}. Lo que primero se hizo cuando se comenzó	el desarrollo del trabajo,
	es la configuración de un \code{Makefile}. La utilización de órdenes para realizar
	la depuración del código resultó gran utilidad.
	\item Gestión de versiones (\code{git}). Para la parte extra del trabajo no solamente
    es imprescindible sino que no existe otro método de trabajo eficaz (no es concebible realizar
    modificaciones en el kernel de Linux, o 	descargárselo sin perder mucho tiempo, si no se
    utilizan esta clase de herramientas).
	Por otro lado, el código tanto de la parte obligatoria, como de la parte opcional
	se encuentra alojado un repositorio de \code{github}, lo cual ha permitido cambiar de
	entorno de trabajo de manera eficaz.
	\begin{itemize}
		\item Repositorio con la parte obligatoria:

		\url{https://github.com/saimusdev/SE2Proyecto}
		\item Repositorio con lo desarrollado como inicio de parte la opcional:

		\url{https://github.com/saimusdev/bone-rt}
	\end{itemize}
	\item \code{screen}. No solamente para poderse conectar a la beaglebone, sino como entorno
	de trabajo: para poder cambiar instantáneamente entre el host/target.
	\item En la parte extra desarrollada ha sido muy valioso el contar con máquinas 	virtuales
    en la nube (digitalocean) para: primero, descargarse repositorios de manera casi instantánea,
    y segundo, reducir el tiempo de construcción del núcleo considerablemente (las máquinas utilizadas
    poseían 12-20 cpus). Estas máquinas, aunque en circunstancias normales son muy costosas,
    con la oferta que se obtuvo de Github para estudiantes, resultó completamente gratis.

\end{itemize}

\end{document}

redpajama_set_name: RedPajamaGithub


text:
set -e # exit with nonzero exit code if anything fails

# clear and re-create the out directory
rm -rf build || exit 0;
mkdir build;

# run our compile script, discussed above
(cd docs; qdoc quickandroid.qdocconf)

REPO=$(git config remote.origin.url)

# go to the out directory and create a *new* Git repo
cd build
cp -a ../docs/html/* .
git init

# The first and only commit to this new Git repo contains all the
# files present with the commit message "Deploy to GitHub Pages".
git add .
git commit --author="Ben Lau <xbenlau@gmail.com>"  -m "Deploy to GitHub Pages"

# Force push from the current repo's master branch to the remote
# repo's gh-pages branch. (All previous history on the gh-pages branch
# will be lost, since we are overwriting it.) We redirect any output to
# /dev/null to hide any sensitive credential data that might otherwise be exposed.
git push --force $REPO master:gh-pages


text:
namespace openscreen {
namespace cast {

using ::cast::channel::CastMessage;
using ::cast::channel::CastMessage_PayloadType;

namespace {

bool IsValidProtocolVersion(int version) {
  return ::cast::channel::CastMessage_ProtocolVersion_IsValid(version);
}

absl::optional<int> FindMaxProtocolVersion(const Json::Value* version,
                                           const Json::Value* version_list) {
  using ArrayIndex = Json::Value::ArrayIndex;
  static_assert(std::is_integral<ArrayIndex>::value,
                "Assuming ArrayIndex is integral");
  absl::optional<int> max_version;
  if (version_list && version_list->isArray()) {
    max_version = ::cast::channel::CastMessage_ProtocolVersion_CASTV2_1_0;
    for (auto it = version_list->begin(), end = version_list->end(); it != end;
         ++it) {
      if (it->isInt()) {
        int version_int = it->asInt();
        if (IsValidProtocolVersion(version_int) && version_int > *max_version) {
          max_version = version_int;
        }
      }
    }
  }
  if (version && version->isInt()) {
    int version_int = version->asInt();
    if (IsValidProtocolVersion(version_int)) {
      if (!max_version) {
        max_version = ::cast::channel::CastMessage_ProtocolVersion_CASTV2_1_0;
      }
      if (version_int > max_version) {
        max_version = version_int;
      }
    }
  }
  return max_version;
}

VirtualConnection::CloseReason GetCloseReason(
    const Json::Value& parsed_message) {
  VirtualConnection::CloseReason reason =
      VirtualConnection::CloseReason::kClosedByPeer;
  absl::optional<int> reason_code = MaybeGetInt(
      parsed_message, JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyReasonCode));
  if (reason_code) {
    int code = reason_code.value();
    if (code >= VirtualConnection::CloseReason::kFirstReason &&
        code <= VirtualConnection::CloseReason::kLastReason) {
      reason = static_cast<VirtualConnection::CloseReason>(code);
    }
  }
  return reason;
}

}  // namespace

ConnectionNamespaceHandler::ConnectionNamespaceHandler(
    VirtualConnectionManager* vc_manager,
    VirtualConnectionPolicy* vc_policy)
    : vc_manager_(vc_manager), vc_policy_(vc_policy) {
  OSP_DCHECK(vc_manager);
  OSP_DCHECK(vc_policy);
}

ConnectionNamespaceHandler::~ConnectionNamespaceHandler() = default;

void ConnectionNamespaceHandler::OnMessage(VirtualConnectionRouter* router,
                                           CastSocket* socket,
                                           CastMessage message) {
  if (message.payload_type() !=
      CastMessage_PayloadType::CastMessage_PayloadType_STRING) {
    return;
  }
  ErrorOr<Json::Value> result = json::Parse(message.payload_utf8());
  if (result.is_error()) {
    return;
  }

  Json::Value& value = result.value();
  if (!value.isObject()) {
    return;
  }

  absl::optional<absl::string_view> type =
      MaybeGetString(value, JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyType));
  if (!type) {
    // TODO(btolsch): Some of these paths should have error reporting.  One
    // possibility is to pass errors back through |router| so higher-level code
    // can decide whether to show an error to the user, stop talking to a
    // particular device, etc.
    return;
  }

  absl::string_view type_str = type.value();
  if (type_str == kMessageTypeConnect) {
    HandleConnect(router, socket, std::move(message), std::move(value));
  } else if (type_str == kMessageTypeClose) {
    HandleClose(router, socket, std::move(message), std::move(value));
  } else {
    // NOTE: Unknown message type so ignore it.
    // TODO(btolsch): Should be included in future error reporting.
  }
}

void ConnectionNamespaceHandler::HandleConnect(VirtualConnectionRouter* router,
                                               CastSocket* socket,
                                               CastMessage message,
                                               Json::Value parsed_message) {
  if (message.destination_id() == kBroadcastId ||
      message.source_id() == kBroadcastId) {
    return;
  }

  VirtualConnection virtual_conn{std::move(message.destination_id()),
                                 std::move(message.source_id()),
                                 socket->socket_id()};
  if (!vc_policy_->IsConnectionAllowed(virtual_conn)) {
    SendClose(router, std::move(virtual_conn));
    return;
  }

  absl::optional<int> maybe_conn_type = MaybeGetInt(
      parsed_message, JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyConnType));
  VirtualConnection::Type conn_type = VirtualConnection::Type::kStrong;
  if (maybe_conn_type) {
    int int_type = maybe_conn_type.value();
    if (int_type < static_cast<int>(VirtualConnection::Type::kMinValue) ||
        int_type > static_cast<int>(VirtualConnection::Type::kMaxValue)) {
      SendClose(router, std::move(virtual_conn));
      return;
    }
    conn_type = static_cast<VirtualConnection::Type>(int_type);
  }

  VirtualConnection::AssociatedData data;

  data.type = conn_type;

  absl::optional<absl::string_view> user_agent = MaybeGetString(
      parsed_message, JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyUserAgent));
  if (user_agent) {
    data.user_agent = std::string(user_agent.value());
  }

  const Json::Value* sender_info_value = parsed_message.find(
      JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeySenderInfo));
  if (!sender_info_value || !sender_info_value->isObject()) {
    // TODO(btolsch): Should this be guessed from user agent?
    OSP_DVLOG << "No sender info from protocol.";
  }

  const Json::Value* version_value = parsed_message.find(
      JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyProtocolVersion));
  const Json::Value* version_list_value = parsed_message.find(
      JSON_EXPAND_FIND_CONSTANT_ARGS(kMessageKeyProtocolVersionList));
  absl::optional<int> negotiated_version =
      FindMaxProtocolVersion(version_value, version_list_value);
  if (negotiated_version) {
    data.max_protocol_version = static_cast<VirtualConnection::ProtocolVersion>(
        negotiated_version.value());
  } else {
    data.max_protocol_version = VirtualConnection::ProtocolVersion::kV2_1_0;
  }

  data.ip_fragment = socket->GetSanitizedIpAddress();

  OSP_DVLOG << "Connection opened: " << virtual_conn.local_id << ", "
            << virtual_conn.peer_id << ", " << virtual_conn.socket_id;

  // NOTE: Only send a response for senders that actually sent a version.  This
  // maintains compatibility with older senders that don't send a version and
  // don't expect a response.
  if (negotiated_version) {
    SendConnectedResponse(router, virtual_conn, negotiated_version.value());
  }

  vc_manager_->AddConnection(std::move(virtual_conn), std::move(data));
}

void ConnectionNamespaceHandler::HandleClose(VirtualConnectionRouter* router,
                                             CastSocket* socket,
                                             CastMessage message,
                                             Json::Value parsed_message) {
  VirtualConnection virtual_conn{std::move(message.destination_id()),
                                 std::move(message.source_id()),
                                 socket->socket_id()};
  if (!vc_manager_->GetConnectionData(virtual_conn)) {
    return;
  }

  VirtualConnection::CloseReason reason = GetCloseReason(parsed_message);

  OSP_DVLOG << "Connection closed (reason: " << reason
            << "): " << virtual_conn.local_id << ", " << virtual_conn.peer_id
            << ", " << virtual_conn.socket_id;
  vc_manager_->RemoveConnection(virtual_conn, reason);
}

void ConnectionNamespaceHandler::SendClose(VirtualConnectionRouter* router,
                                           VirtualConnection virtual_conn) {
  Json::Value close_message(Json::ValueType::objectValue);
  close_message[kMessageKeyType] = kMessageTypeClose;

  ErrorOr<std::string> result = json::Stringify(close_message);
  if (result.is_error()) {
    return;
  }

  router->Send(
      std::move(virtual_conn),
      MakeSimpleUTF8Message(kConnectionNamespace, std::move(result.value())));
}

void ConnectionNamespaceHandler::SendConnectedResponse(
    VirtualConnectionRouter* router,
    const VirtualConnection& virtual_conn,
    int max_protocol_version) {
  Json::Value connected_message(Json::ValueType::objectValue);
  connected_message[kMessageKeyType] = kMessageTypeConnected;
  connected_message[kMessageKeyProtocolVersion] =
      static_cast<int>(max_protocol_version);

  ErrorOr<std::string> result = json::Stringify(connected_message);
  if (result.is_error()) {
    return;
  }

  router->Send(virtual_conn, MakeSimpleUTF8Message(kConnectionNamespace,
                                                   std::move(result.value())));
}

}  // namespace cast
}  // namespace openscreen


text:
.class public interface abstract Ljava/util/EventListener;
.super Ljava/lang/Object;
.source "EventListener.java"


text:
package com.soriole.web.webrtc_signaling_server.domain;

import com.soriole.web.webrtc_signaling_server.cases.connection.ConnectionContext;
import org.junit.Test;
import com.soriole.web.webrtc_signaling_server.BaseTest;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class RTCConnectionsTest extends BaseTest {

    @Autowired
    private RTCConnections connections;

    @Test
    public void shouldInitBiDirectionalConnectionBetweenTwoMembers() {
        // given
        Member john = mockMember("John");
        Member stan = mockMember("Stan");
        ConnectionContext context = mock(ConnectionContext.class);

        // when
        connections.put(john, stan, context);

        // then
        Optional<ConnectionContext> result = connections.get(john, stan);
        assertTrue(result.isPresent());
        Optional<ConnectionContext> reverse = connections.get(stan, john);
        assertTrue(reverse.isPresent());
        assertThat(result.get(), is(context));
        assertThat(reverse.get(), is(result.get()));
    }

    @Test
    public void shouldRemoveOldConnections() throws Exception {
        // given
        Member john = mockMember("John");
        Member stan = mockMember("Stan");
        ConnectionContext context = mock(ConnectionContext.class);
        when(context.getMaster()).thenReturn(john);
        when(context.getSlave()).thenReturn(stan);
        when(context.isCurrent()).thenReturn(false);
        connections.put(john, stan, context);

        // when
        connections.removeOldConnections();

        // then
        Optional<ConnectionContext> result = connections.get(john, stan);
        assertFalse(result.isPresent());
    }

}


text:
module.exports.file   = require('./qrep/file');
module.exports.url    = require('./qrep/url');
module.exports.stream = require('./qrep/stream');
module.exports.usage  = require('./qrep/usage');


text:
require 'ffaker'

FactoryGirl.define do
  factory :content_block, class: Sevenpages::ContentBlock do
    title { Faker::Lorem.words(2).join(' ').titleize }
    content { Faker::HTMLIpsum.p(100) }
  end
end


text:
This script uses tensorflow's `DNNCLassifier` to recognise capital letters from some corrupted data.
This was a task during University of Warsaw's Machine Learning course in 2017.

## Description of the data

Letters have the following attributes:

- `x.bar`: mean x of on pixels in box (integer)
- `y.bar`: mean y of on pixels in box (integer)
- `xybar`: mean x y correlation (integer)
- `x.edge`: mean edge count left to right (integer)
- `y.edge`: mean edge count bottom to top (integer)
- `a6,...,a15`: some linear combinations of
    - horizontal position of box
    - vertical position of box
    - width of box
    - height of box
    - total number of on pixels
    - mean x variance
    - mean y variance
    - mean of x * x * y
    - mean of x * y * y
    - correlation of x-edge with y
    - correlation of y-edge with x
- `letter`: capital letter (26 values from A to Z)

All numeric values have been scaled to the range 0..20. The data (including test sets) are of reduced quality. In particular, values of attributes a6,...,a15 may be missing.

## Requirements
The script requires python 2.7 and pip to run. Install dependencies using command
`pip install -r requirements.txt`

## Running full training and testing
To run interactive script for training and testing the classifier, execute
`python letters.py`
and provide training, testing and output file paths when prompted.

Example files can be found in the `data/` directory


text:
#include <pangolin/video/drivers/split.h>
#include <pangolin/factory/factory_registry.h>
#include <pangolin/video/iostream_operators.h>
#include <pangolin/video/video.h>

#include <exception>

namespace pangolin
{

SplitVideo::SplitVideo(std::unique_ptr<VideoInterface> &src_, const std::vector<StreamInfo>& streams)
    : src(std::move(src_)), streams(streams)
{
    videoin.push_back(src.get());

    // Warn if stream over-runs input stream
    for(unsigned int i=0; i < streams.size(); ++i) {
        if(src->SizeBytes() < (size_t)streams[i].Offset() + streams[i].SizeBytes() ) {
            pango_print_warn("VideoSplitter: stream extends past end of input.\n");
            break;
        }
    }
}

SplitVideo::~SplitVideo()
{
}

size_t SplitVideo::SizeBytes() const
{
    return videoin[0]->SizeBytes();
}

const std::vector<StreamInfo>& SplitVideo::Streams() const
{
    return streams;
}

void SplitVideo::Start()
{
    videoin[0]->Start();
}

void SplitVideo::Stop()
{
    videoin[0]->Stop();
}

bool SplitVideo::GrabNext( unsigned char* image, bool wait )
{
    return videoin[0]->GrabNext(image, wait);
}

bool SplitVideo::GrabNewest( unsigned char* image, bool wait )
{
    return videoin[0]->GrabNewest(image, wait);
}

std::vector<VideoInterface*>& SplitVideo::InputStreams()
{
    return videoin;
}

PANGOLIN_REGISTER_FACTORY(SplitVideo)
{
    struct SplitVideoFactory final : public TypedFactoryInterface<VideoInterface> {
        std::map<std::string,Precedence> Schemes() const override
        {
            return {{"split",10}};
        }
        const char* Description() const override
        {
            return "Transforms a set of video streams into a new set by providing region-of-interest, raw memory layout, or stream order specification.";
        }
        ParamSet Params() const override
        {
            return {{
                {"roi\\d+","X+Y+WxH","Region of Interest as WidthxHeight"},
                {"mem\\d+","width,height,pitch,pixelformat*","By default dynamically set from the first stream"},
                {"stream\\d+","0","Integer"}
            }};
        }

        std::unique_ptr<VideoInterface> Open(const Uri& uri) override {
            std::vector<StreamInfo> streams;

            std::unique_ptr<VideoInterface> subvid = pangolin::OpenVideo(uri.url);
            if(subvid->Streams().size() == 0) {
                throw VideoException("VideoSplitter input must have at least one stream");
            }

            ParamReader param_reader(Params(), uri);

            while(true) {
                const size_t n = streams.size() + 1;
                std::string key_roi = std::string("roi") + pangolin::Convert<std::string, size_t>::Do(n);
                std::string key_mem = std::string("mem") + pangolin::Convert<std::string, size_t>::Do(n);
                std::string key_str = std::string("stream") + pangolin::Convert<std::string, size_t>::Do(n);

                if(uri.Contains(key_roi)) {
                    const StreamInfo& st1 = subvid->Streams()[0];
                    const ImageRoi& roi = param_reader.Get<ImageRoi>(key_roi, ImageRoi());
                    if(roi.w == 0 || roi.h == 0) {
                        throw VideoException("split: empty ROI.");
                    }
                    const size_t start1 = roi.y * st1.Pitch() + st1.PixFormat().bpp * roi.x / 8;
                    streams.push_back( StreamInfo( st1.PixFormat(), roi.w, roi.h, st1.Pitch(), reinterpret_cast<unsigned char*>(start1) ) );
                }else if(uri.Contains(key_mem)) {
                    const StreamInfo& info = param_reader.Get(key_mem, subvid->Streams()[0]); //uri.Get<StreamInfo>(key_mem, subvid->Streams()[0] );
                    streams.push_back(info);
                }else if(uri.Contains(key_str)) {
                    const size_t old_stream = param_reader.Get<size_t>(key_str) - 1; //uri.Get<size_t>(key_str, 0) -1;
                    if(old_stream >= subvid->Streams().size()) {
                        throw VideoException("split: requesting source stream which does not exist.");
                    }
                    streams.push_back(subvid->Streams()[old_stream]);
                }else{
                    break;
                }
            }

            // Default split if no arguments
            if(streams.size() == 0) {
                const StreamInfo& st1 = subvid->Streams()[0];
                const size_t subw = st1.Width();
                const size_t subh = st1.Height();

                ImageRoi roi1, roi2;

                if(subw > subh) {
                    // split horizontally
                    roi1 = ImageRoi(0,0, subw/2, subh );
                    roi2 = ImageRoi(subw/2,0, subw/2, subh );
                }else{
                    // split vertically
                    roi1 = ImageRoi(0,0, subw, subh/2 );
                    roi2 = ImageRoi(0,subh/2, subw, subh/2 );
                }

                const size_t start1 = roi1.y * st1.Pitch() + st1.PixFormat().bpp * roi1.x / 8;
                const size_t start2 = roi2.y * st1.Pitch() + st1.PixFormat().bpp * roi2.x / 8;
                streams.push_back( StreamInfo( st1.PixFormat(), roi1.w, roi1.h, st1.Pitch(), (unsigned char*)(start1) ) );
                streams.push_back( StreamInfo( st1.PixFormat(), roi2.w, roi2.h, st1.Pitch(), (unsigned char*)(start2) ) );
            }

            return std::unique_ptr<VideoInterface>( new SplitVideo(subvid,streams) );
        }
    };

    return FactoryRegistry::I()->RegisterFactory<VideoInterface>(std::make_shared<SplitVideoFactory>());
}

}


text:
class T_CONTROLLER_EXPORT IndexController : public ApplicationController
{
    Q_OBJECT
public:
    Q_INVOKABLE
    IndexController() : ApplicationController() {}

public slots:
    void index();
};

#endif // INDEXCONTROLLER_H


text:
<!DOCTYPE html>

	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

	<title>Raster Foundry</title>
	<link rel="stylesheet" href="/assets/css/main.css">
	<link rel="stylesheet" href="/assets/font/fontello/css/raster-foundry.css">
	<link rel="stylesheet" href="/assets/css/vendors/animate/animate.css">
	<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />

				<button class="dl-trigger">

					 Untitled Project
				</button>

 Mosaic Projects

						New Mosaic Project
						Project Name 6
						Project Name 2
						Project Name 1

						More Mosaic Projects

New Mosaic Project

Project Name 1

Project Name 2

Project Name 3

Project Name 4

Project Name 5

Project Name 6

						 Library

						 Account

						 Logout

			Account
			Keys & Authentication
			Billing

				    60% Complete

			4.8 GB of 10 GB used

Billing & Plan


text:
TwistedOTA
-------
A very simple OTA checker with Android Settings look and feel.

How it works
------------
It parses the OTA xml file that you put in your file hosting and compares the version number with the local one.
If the version is newer, it notifies the user for a new ROM update.

How to use
----------
* Prepare the OTA xml file. Use this [template](https://raw.githubusercontent.com/TeamTwisted/packages_apps_SlimOTA/kantjer/examples/ota_twisted.xml).
* Upload it to your file hosting and create a hot link of it
* Copy the [ota_conf template](https://raw.githubusercontent.com/TeamTwisted/packages_apps_SlimOTA/kantjer/examples/ota_conf) to app/src/main/assets folder
  * If you are buiding this app as part of the ROM, you need to copy ota_conf in the android root folder.
  * The Android.mk will pick it up and copy it to app/src/main/assets folder automatically.
* Replace the "ota_url" with your OTA xml hot link
* Define how TwistedOTA should know about the "version". The version must be parseable to a date.
  * Usually, the version is a part of a build name. For example, the 20160122 in the Twisted-angler-6.0.1-build-3.0-20160122.
* Adjust the OTA configuration according to your build name on how should TwistedOTA parse the version
  * Find a key in build.prop that represents the Twisted-angler-6.0.1-build-3.0-20160122 and set it in the "version_name"
  * Set the delimiter in "version_delimiter" to "-"
  * Set the date format in "version_format" to "yyyyMMdd"
  * Set the position in "version_position" to "5" (zero based)
* Find a key in build.prop that represents your device name and set it in the "device_name"
  * TwistedOTA will search this device name in the OTA xml file

How to build
------------
* As part of the ROM
  * [Add this repo in your manifest](https://github.com/SlimSaber/platform_manifest/commit/0c0debe17d03cbe911f8693c4da2789b9d94b08e)
  * [Include this app in the build process](https://github.com/SlimSaber/vendor_slim/commit/c8c7bae682d837e21af3062dded327cda2d781e0)
* As a standalone app
  * With Android.mk: make SlimOTA
  * With Android Studio: Import this repo to your Android Studio and build it from there

Credits
-------
* [Slim team](http://slimroms.net/)
  * For the original idea of the SlimCenter and app icon
* [CommonsWare Android Components](https://github.com/commonsguy/cwac-wakeful)
  * For the wakeful intent service that is used in this app
* [Fusionjack] (http://forum.xda-developers.com/member.php?u=1228651)
  * For the original SlimOTA

Screenshots
-----------
<img alt="Screenshot"
   width="270" height="480"
   src="https://raw.githubusercontent.com/TeamTwisted/packages_apps_SlimOTA/kantjer/screenshots/Screenshot.png" />


text:
#pragma once

#include <vector>
#include <set>
#include <boost/unordered_map.hpp>
#include "util/file_stream.hh"

namespace ExpectedBleuTraining
{

class ExpectedBleuOptimizer
{
public:

  ExpectedBleuOptimizer(util::FileStream& err,
                        float learningRate=1,
                        float initialStepSize=0.001,
                        float decreaseRate=0.5,
                        float increaseRate=1.2,
                        float minStepSize=1e-7,
                        float maxStepSize=1,
                        float floorAbsScalingFactor=0,
                        float regularizationParameter=0)
    : m_err(err)
    , m_learningRate(learningRate)
    , m_initialStepSize(initialStepSize)
    , m_decreaseRate(decreaseRate)
    , m_increaseRate(increaseRate)
    , m_minStepSize(minStepSize)
    , m_maxStepSize(maxStepSize)
    , m_floorAbsScalingFactor(floorAbsScalingFactor)
    , m_regularizationParameter(regularizationParameter)
    , m_xBleu(0)
  { }

  void AddTrainingInstance(const size_t nBestSizeCount,
                           const std::vector<float>& sBleu,
                           const std::vector<double>& overallScoreUntransformed,
                           const std::vector< boost::unordered_map<size_t, float> > &sparseScore,
                           bool maintainUpdateSet = false);

  void InitSGD(const std::vector<float>& sparseScalingFactor);

  float UpdateSGD(std::vector<float>& sparseScalingFactor,
                  size_t batchSize,
                  bool useUpdateSet = false);

  void InitRPROP(const std::vector<float>& sparseScalingFactor);

  float UpdateRPROP(std::vector<float>& sparseScalingFactor,
                    const size_t batchSize);

protected:

  util::FileStream& m_err;

  // for SGD
  const float m_learningRate;

  // for RPROP
  const float m_initialStepSize;
  const float m_decreaseRate;
  const float m_increaseRate;
  const float m_minStepSize;
  const float m_maxStepSize;

  std::vector<float> m_previousSparseScalingFactor;
  std::vector<float> m_previousGradient;
  std::vector<float> m_gradient;
  std::vector<float> m_stepSize;

  // other
  const float m_floorAbsScalingFactor;
  const float m_regularizationParameter;

  double m_xBleu;

  std::set<size_t> m_updateSet;

  void UpdateSingleScalingFactorSGD(size_t name,
                                    std::vector<float>& sparseScalingFactor,
                                    size_t batchSize);

  inline int Sign(double x)
  {
    if (x > 0) return 1;
    if (x < 0) return -1;
    return 0;
  }
};

}


text:
Monaco
====

***Monaco*** is a web application framework, built on top of the marvelous [*backbone.js*](http://backbonejs.org/), that offers a non-opinionated solution for developing small and large scale front-end applications.

*Backbone* is great as it stands, and offers the developer the ability to architect a solution any way it is needed, but it doesn't offer a structure to tie the application code together, or to deal with common problems developers face on almost every app they build, such as local caching, or analytics integration, etc; All of that makes building applications much harder than it should be, ***Monaco*** is my take on solving these problems without forcing a develop to follow this or that convention.

To learn more about how ***Monaco*** works read the [getting started](/docs/getting-started.md) and the [platform overview](/docs/platform-overview.md) docs.

Monaco Modules
----

To accomplish all of that ***Monaco*** is divided into modules, where you can opt to use all or just some of them; whatever is needed to accomplish the task in hand. Each module is designed to help you active a specific requirement of your application.

Even if you decide to use all modules available, ***Monaco*** is just 5.5kb (minified and gzipped) - but it might be even smaller if you don't need all modules.

- **monaco-application** - this is the core and the only required module of ***Monaco***; responsible for managing the application object and all elements added to it - [learn more](docs/modules/monaco-application.md).

- **monaco-local** - this module creates a local caching system that can be used to help you architect your application caching strategy - [learn more](docs/modules/monaco-local.md).

- **monaco-router** - this module allows you to easily add advanced routes using regular expressions; it also has a reverse router implementation that can be used to create smart links - [learn more](docs/modules/monaco-router.md).

- **monaco-views** - this module help you organize *master views* (screen views) and their subviews - [learn more](docs/modules/monaco-views.md).

- **monaco-transitions** - this module gives your application a way of setting up screen transitions, where each transition effect can be implemented based on your app requirements using any technology needed (e.g: javascript, css, or both) - [learn more](docs/modules/monaco-transitions.md).

- **monaco-analytics** - this module automatically sends a pageview tracking request every time you navigate to a different url and can be integrated with almost any analytics service provider - [learn more](docs/modules/monaco-analytics.md).

- **monaco-experiments** - this module allows you to create split tests (experiments) and divide your users appropriately; you can target different controllers, views, templates or template elements as you need - [learn more](docs/modules/monaco-experiments.md).

Monaco Command Line Interface (monaco-cli)
----

On top of all the features described above, ***Monaco*** also provides a really handy command line interface, that allows you get started with your projects and prototypes really fast. The use of **monaco-cli** is not required and you can build your apps using whatever structure of files and folders you want, but this tool is really handy if you need help creating the project file structure for your application. [Learn more](/docs/monaco-cli.md).

License
----

See [LICENSE](LICENSE)


text:
package com.amazonaws.services.dynamodbv2.document;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.document.api.BatchGetItemApi;
import com.amazonaws.services.dynamodbv2.document.internal.InternalUtils;
import com.amazonaws.services.dynamodbv2.document.spec.BatchGetItemSpec;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.BatchGetItemResult;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

/**
 * The outcome of a batch get-item operation from DynamoDB.
 */
public class BatchGetItemOutcome {
    private final BatchGetItemResult result;

    /**
     * @param result the low-level result; must not be null
     */
    public BatchGetItemOutcome(BatchGetItemResult result) {
        if (result == null)
            throw new IllegalArgumentException();
        this.result = result;
    }

    /**
     * Returns a map of table name to the list of retrieved items
     */
    public Map<String, List<Item>> getTableItems() {
        Map<String, List<Map<String, AttributeValue>>> res =
            result.getResponses();
        Map<String, List<Item>> map = new LinkedHashMap<String, List<Item>>(res.size());
        for (Map.Entry<String, List<Map<String, AttributeValue>>> e
                : res.entrySet()) {
            String tableName = e.getKey();
            List<Map<String, AttributeValue>> items = e.getValue();
            map.put(tableName, InternalUtils.toItemList(items));
        }
        return map;
    }

    /**
     * Convenient method to return the low-level unprocessed keys.
     *
     * @see BatchGetItemApi#batchGetItemUnprocessed(Map)
     * @see BatchGetItemApi#batchGetItemUnprocessed(com.amazonaws.services.dynamodbv2.model.ReturnConsumedCapacity,
     *      Map)
     * @see BatchGetItemSpec#withUnprocessedKeys(Map)
     */
    public Map<String, KeysAndAttributes> getUnprocessedKeys() {
        return result.getUnprocessedKeys();
    }

    /**
     * Returns a non-null low-level result returned from the server side.
     */
    public BatchGetItemResult getBatchGetItemResult() {
        return result;
    }

    @Override
    public String toString() {
        return String.valueOf(result);
    }
}


text:
import React from "react";
import RecipeSearchList from "../../common/components/RecipeSearchList";
import { Helmet } from "react-helmet";

// Simple example of a React "smart" component
export default class Recipes extends React.Component {
  constructor(props, context) {
    super(props, context);
    if (this.props.recipes) {
      this.state = {
        recipes: this.props.recipes,
        loading: false
      };
    } else {
      this.state = {
        recipes: null,
        loading: true
      };
    }
  }

  componentDidMount() {
    if (this.state.loading) {
      fetch(this.props.base + "/api/recipes")
        .then(response => {
          return response.json();
        })
        .then(data => {
          this.setState({
            recipes: data,
            loading: false
          });
        });
    }
  }

  render() {
    if (this.state.loading) {
      return
Loading...
;
    } else {
      return (

          <Helmet>
            <title>Recipes List</title>
          </Helmet>

Recipes

          <RecipeSearchList
            recipes={this.state.recipes}
            routePrefix={this.props.base}
          />

      );
    }
  }
}


text:
/*
 * Projekt: Queen
 * Predmet: IJA - Seminar Java
 * Soubor: Position.java
 * Autori:
 *          xkolac12 < xkolac12 @ stud.fit.vutbr.cz >
 *          xmatya03 < xmatya03 @ stud.fit.vutbr.cz >
 *
 * Trida Position reprezentuje pozici na sachovnici
 */

package queen.basis;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author      Frantisek Kolacek <xkolac12 @ stud.fit.vutbr.cz>
 * @author      Petr Matyas <xmatya03 @ stud.fit.vutbr.cz>
 * @version     0.91
 * @since       2013-04-30
 */
public class Position {

    private char column;
    private int row;

    /**
     * Konstruktor pro objekt Position
     * @param column    znak sloupce
     * @param row       cislo radku
     */
    public Position(char column, int row){
        this.column = column;
        this.row = row;
    }

    /**
     * Kopirovaci konstruktor pro objekt Position
     * @param position  instance objektu Position
     */
    public Position(Position position){
        this.column = position.getColumn();
        this.row = position.getRow();
    }

    /**
     * Konstruktor pozice figurky
     * @param position string s pozici figurky
     */
    public Position(String position){
        //System.out.println("Position init: " + position);
        Pattern regex = Pattern.compile("^([a-z])([0-9])$");
        Matcher match = regex.matcher(position);

        if(match.find()){
            this.column = match.group(1).charAt(0);
            this.row = Integer.parseInt(match.group(2));
        }
        else{
            this.column = 'a';
            this.row = 1;
        }
    }

    /**
     * Getter pro znak sloupce
     * @return  znak sloupce
     */
    public char getColumn(){
        return this.column;
    }

    /**
     * Getter pro cislo radku
     * @return cislo radku
     */
    public int getRow(){
        return this.row;
    }

    /**
     * Porovnani dvou objektu Position
     * @param object druha pozice pro porovnani
     * @return true pokud jsou shodne, jinak false
     */
    @Override
    public boolean equals(Object object){
        if(object == null || object.getClass() != Position.class)
            return false;

        Position position = (Position) object;

        if(this.column == position.getColumn() && this.row == position.getRow())
            return true;
        else
            return false;
    }

    /**
     * Prevedeni pozice na string
     * @return string s pozici
     */
    @Override
    public String toString(){
        return new String(Character.toString(this.column) + Integer.toString(this.row));
    }

}


text:
package info.llanox.mobile.data;

import java.util.Date;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBRepository {

    public static final String KEY_ROWID = "_id";
    public static final String KEY_NOMBRE = "nombre_cancion";
    public static final String KEY_FECHA_REPRODUCCION = "fecha_reproduccion";

    private static final String TAG = DBRepository.class.getSimpleName();
    private static final String DATABASE_NAME = "db_reproductor";
    private static final String DATABASE_TABLE = "reproducciones";
    private static final int    DATABASE_VERSION = 1;
    private static final String DATABASE_CREATE = "create table "+DATABASE_TABLE+" "+
    "("+KEY_ROWID+" integer primary key autoincrement, "
        + ""+KEY_NOMBRE+" text not null UNIQUE, "+KEY_FECHA_REPRODUCCION+" text not null);";

    private final Context context;
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    public DBRepository(Context ctx)
    {
        this.context = ctx;
        DBHelper = new DatabaseHelper(context);
    }
    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db)
        {
            try {
                db.execSQL(DATABASE_CREATE);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            Log.w(TAG, "Upgrading database from version" + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE);
            onCreate(db);
        }
    }
    //---opens the database---
    public DBRepository open() throws SQLException
    {
        db = DBHelper.getWritableDatabase();
        return this;
    }
    //---closes the database---
    public void close()
    {
        DBHelper.close();
    }

    //---insert a contact into the database---
    public long insertReproduccion(String name, Date fechaReproduccion)
    {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_NOMBRE, name);
        initialValues.put(KEY_FECHA_REPRODUCCION, fechaReproduccion.toString());

        return db.insert(DATABASE_TABLE, null, initialValues);
    }
    //---deletes a particular contact---
    public boolean deleteContact(long rowId)
    {

        return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }
    //---retrieves all the contacts---
    public Cursor getAllContacts()
    {
        return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NOMBRE,
                KEY_FECHA_REPRODUCCION}, null, null, null, null, null);
    }
    //---retrieves a particular contact---
    public Cursor getContact(long rowId) throws SQLException
    {
        Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,KEY_NOMBRE, KEY_FECHA_REPRODUCCION}, KEY_ROWID + "=" + rowId, null,null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }
    //---updates a contact---
    public boolean updateContact(long rowId, String name, Date fechaReproduccion)

    {
        ContentValues args = new ContentValues();
        args.put(KEY_NOMBRE, name);
        args.put(KEY_FECHA_REPRODUCCION, fechaReproduccion.toString());
        return db.update(DATABASE_TABLE, args, KEY_NOMBRE + " like %" + name+"%", null) >0;
    }
}


text:
#ifndef __MD5_H
#define __MD5_H

void Curl_md5it(unsigned char *output,
                const unsigned char *input);

#endif


text:
Brouwkuyp brew control application
==================================

## Still in development phase!

To start brewing, run following command:

`app/console brouwkuyp:brew`

To consume messages sent by the Arduino, be sure to have the consume command running via:

`app/console brouwkuyp:consume`

## Dashboard

`http://brouwkuyp-control.dev/app_dev.php`

## Development commands

Get up to date:

`git pull --rebase upstream develop`
`composer install`

Composer install ensures that all necessary commands are ran, such as assets and cache clearing etc.

Generate entities

`app/console doc:gen:entities BrouwkuypDashboardBundle --no-backup`

Update database, view changes

`app/console doc:sch:update --dump-sql`

Updated orm files, generate doctrine migration file

`app/console doc:mig:diff`

Double check file in `app/DoctrineMigrations`
Perform doctrine migration

`app/console doc:mig:mig`

Commit changes

`git add -A`

`git commit` or `git commit -m 'commit message'`

Push to github

`git push origin develop`

Create pull request form `develop` to `master` on github.com

## Docker

# Extra commands

`yum -y update`
`yum -y install mlocate`
`updatedb`
`locate less`
`locate node`
`npm install -g less`


text:
package com.java110.dto.inspectionItem;

import com.java110.dto.PageDto;
import java.io.Serializable;
import java.util.Date;

/**
 * @ClassName FloorDto
 * @Description 巡检项目数据层封装
 * @Author wuxw
 * @Date 2019/4/24 8:52
 * @Version 1.0
 * add by wuxw 2019/4/24
 **/
public class InspectionItemDto extends PageDto implements Serializable {

    private String itemId;
private String itemName;
private String remark;
private String communityId;

    private Date createTime;

    private String statusCd = "0";

    public String getItemId() {
        return itemId;
    }
public void setItemId(String itemId) {
        this.itemId = itemId;
    }
public String getItemName() {
        return itemName;
    }
public void setItemName(String itemName) {
        this.itemName = itemName;
    }
public String getRemark() {
        return remark;
    }
public void setRemark(String remark) {
        this.remark = remark;
    }
public String getCommunityId() {
        return communityId;
    }
public void setCommunityId(String communityId) {
        this.communityId = communityId;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getStatusCd() {
        return statusCd;
    }

    public void setStatusCd(String statusCd) {
        this.statusCd = statusCd;
    }
}


text:
package org.cactoos.io;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * InputStream that returns content in small portions.
 *
 * @author Yegor Bugayenko (yegor256@gmail.com)
 * @version $Id$
 * @since 0.12
 */
final class SlowInputStream extends InputStream {

    /**
     * Original stream.
     */
    private final InputStream origin;

    /**
     * Ctor.
     * @param size The size of the array to encapsulate
     */
    SlowInputStream(final int size) {
        this(new ByteArrayInputStream(new byte[size]));
    }

    /**
     * Ctor.
     * @param stream Original stream to encapsulate and make slower
     */
    SlowInputStream(final InputStream stream) {
        super();
        this.origin = stream;
    }

    @Override
    public int read() throws IOException {
        final byte[] buf = new byte[1];
        final int result;
        if (this.read(buf) < 0) {
            result = -1;
        } else {
            result = buf[0];
        }
        return result;
    }

    @Override
    public int read(final byte[] buf, final int offset, final int len)
        throws IOException {
        final int result;
        if (len > 1) {
            result = this.origin.read(buf, offset, len - 1);
        } else {
            result = this.origin.read(buf, offset, len);
        }
        return result;
    }

    @Override
    public int read(final byte[] buf) throws IOException {
        return this.read(buf, 0, buf.length);
    }

}


text:
.. _arch_overview_circuit_break:

Circuit breaking
================

Circuit breaking is a critical component of distributed systems. It's nearly always better to fail
quickly and apply back pressure downstream as soon as possible. One of the main benefits of an Envoy
mesh is that Envoy enforces circuit breaking limits at the network level as opposed to having to
configure and code each application independently. Envoy supports various types of fully distributed
(not coordinated) circuit breaking:

.. _arch_overview_circuit_break_cluster_maximum_connections:

* **Cluster maximum connections**: The maximum number of connections that Envoy will establish to
  all hosts in an upstream cluster. If this circuit breaker overflows the :ref:`upstream_cx_overflow
  <config_cluster_manager_cluster_stats>` counter for the cluster will increment. All connections,
  whether active or draining, count against this limit. Even if this circuit breaker has overflowed,
  Envoy will ensure that a host selected by cluster load balancing has at least one connection
  allocated. This has the implication that the :ref:`upstream_cx_active
  <config_cluster_manager_cluster_stats>` count for a cluster may be higher than the cluster maximum
  connection circuit breaker, with an upper bound of
  `cluster maximum connections + (number of endpoints in a cluster) * (connection pools for the
  cluster)`. This bound applies to the sum of connections across all workers threads. See
  :ref:`connection pooling <arch_overview_conn_pool_how_many>` for details on how many connection
  pools a cluster may have.
* **Cluster maximum pending requests**: The maximum number of requests that will be queued while
  waiting for a ready connection pool connection. Requests are added to the list
  of pending requests whenever there aren't enough upstream connections available to immediately dispatch
  the request. For HTTP/2 connections, if :ref:`max concurrent streams <envoy_v3_api_field_config.core.v3.Http2ProtocolOptions.max_concurrent_streams>`
  and :ref:`max requests per connection <envoy_v3_api_field_config.cluster.v3.Cluster.max_requests_per_connection>` are not
  configured, all requests will be multiplexed over the same connection so this circuit breaker
  will only be hit when no connection is already established. If this circuit breaker overflows the
  :ref:`upstream_rq_pending_overflow <config_cluster_manager_cluster_stats>` counter for the cluster will
  increment.
* **Cluster maximum requests**: The maximum number of requests that can be outstanding to all hosts
  in a cluster at any given time. If this circuit breaker overflows the :ref:`upstream_rq_pending_overflow <config_cluster_manager_cluster_stats>`
  counter for the cluster will increment.
* **Cluster maximum active retries**: The maximum number of retries that can be outstanding to all
  hosts in a cluster at any given time. In general we recommend using :ref:`retry budgets <envoy_v3_api_field_config.cluster.v3.CircuitBreakers.Thresholds.retry_budget>`; however, if static circuit breaking is preferred it should aggressively circuit break
  retries. This is so that retries for sporadic failures are allowed, but the overall retry volume cannot
  explode and cause large scale cascading failure. If this circuit breaker overflows the
  :ref:`upstream_rq_retry_overflow <config_cluster_manager_cluster_stats>` counter for the cluster
  will increment.

  .. _arch_overview_circuit_break_cluster_maximum_connection_pools:

* **Cluster maximum concurrent connection pools**: The maximum number of connection pools that can be
  concurrently instantiated. Some features, such as the
  :ref:`Original Src Listener Filter <arch_overview_ip_transparency_original_src_listener>`, can
  create an unbounded number of connection pools. When a cluster has exhausted its concurrent
  connection pools, it will attempt to reclaim an idle one. If it cannot, then the circuit breaker
  will overflow. This differs from
  :ref:`Cluster maximum connections <arch_overview_circuit_break_cluster_maximum_connections>` in that
  connection pools never time out, whereas connections typically will. Connections automatically
  clean up; connection pools do not. Note that in order for a connection pool to function it needs
  at least one upstream connection, so this value should likely be no greater than
  :ref:`Cluster maximum connections <arch_overview_circuit_break_cluster_maximum_connections>`.
  If this circuit breaker overflows the
  :ref:`upstream_cx_pool_overflow <config_cluster_manager_cluster_stats>` counter for the cluster
  will increment.

Each circuit breaking limit is :ref:`configurable <config_cluster_manager_cluster_circuit_breakers>`
and tracked on a per upstream cluster and per priority basis. This allows different components of
the distributed system to be tuned independently and have different limits. The live state of these
circuit breakers, including the number of resources remaining until a circuit breaker opens, can
be observed via :ref:`statistics <config_cluster_manager_cluster_stats_circuit_breakers>`.

Workers threads share circuit breaker limits, i.e. if the active connection threshold is 500, worker
thread 1 has 498 connections active, then worker thread 2 can only allocate 2 more connections.
Since the implementation is eventually consistent, races between threads may allow limits to be
potentially exceeded.

Circuit breakers are enabled by default and have modest default values, e.g. 1024 connections per
cluster. To disable circuit breakers, set the :ref:`thresholds <faq_disable_circuit_breaking>` to
the highest allowed values.

Note that circuit breaking will cause the :ref:`x-envoy-overloaded
<config_http_filters_router_x-envoy-overloaded_set>` header to be set by the router filter in the
case of HTTP requests.


text:
module Domain (
    Domain,
    ToDomain,
    toDomain,
    member,
    isSubsetOf,
    elems,
    intersection,
    difference,
    Domain.null,
    singleton,
    isSingleton,
    filterLessThan,
    filterGreaterThan,
    findMax,
    findMin,
    maxDomain
) where

import qualified Data.IntSet as IntSet
import Data.IntSet (IntSet)

data Domain
    = Set IntSet
    | Range Int Int

-- Domain constructors
class ToDomain a where
    toDomain :: a -> Domain

instance ToDomain Domain where
    toDomain = id

instance ToDomain IntSet where
    toDomain = Set

instance Integral a => ToDomain [a] where
    toDomain = toDomain . IntSet.fromList . map fromIntegral

instance (Integral a, Integral b) => ToDomain (a, b) where
    toDomain (a, b) = Range (fromIntegral a) (fromIntegral b)

instance ToDomain () where
    toDomain () = Range minBound maxBound

--instance Integral a => ToDomain a where
--    toDomain a = toDomain (a, a)

-- Operations on Domains
instance Eq Domain where
    (Range xl xh) == (Range yl yh) = xl == yl && xh == yh
    xs == ys = elems xs == elems ys

instance Semigroup Domain where
    (<>) = intersection

instance Monoid Domain where
    mempty = maxDomain

member :: Int -> Domain -> Bool
member n (Set xs) = n `IntSet.member` xs
member n (Range xl xh) = n >= xl && n <= xh

isSubsetOf :: Domain -> Domain -> Bool
isSubsetOf (Set xs) (Set ys) = xs `IntSet.isSubsetOf` ys
isSubsetOf (Range xl xh) (Range yl yh) = xl >= yl && xh <= yh
isSubsetOf (Set xs) yd@(Range _ _) =
    isSubsetOf (Range xl xh) yd where
        xl = IntSet.findMin xs
        xh = IntSet.findMax xs
isSubsetOf (Range xl xh) (Set ys) =
    all (`IntSet.member` ys) [xl..xh]

elems :: Domain -> [Int]
elems (Set xs) = IntSet.elems xs
elems (Range xl xh) = [xl..xh]

intersection :: Domain -> Domain -> Domain
intersection (Set xs) (Set ys) = Set (xs `IntSet.intersection` ys)
intersection (Range xl xh) (Range yl yh) = Range (max xl yl) (min xh yh)
intersection (Set xs) (Range yl yh) =
    Set $ IntSet.filter (\x -> x >= yl && x <= yh) xs
intersection x y = intersection y x

difference :: Domain -> Domain -> Domain
difference (Set xs) (Set ys) = Set (xs `IntSet.difference` ys)
difference xd@(Range xl xh) (Range yl yh)
    | yl > xh || yh < xl = xd
    | otherwise = Set $ IntSet.fromList [x | x <- [xl..xh], x < yl || x > yh]
difference (Set xs) (Range yl yh) =
    Set $ IntSet.filter (\x -> x < yl || x > yh) xs
difference (Range xl xh) (Set ys)
    | IntSet.findMin ys > xh || IntSet.findMax ys < xl = Range xl xh
    | otherwise = Set $
        IntSet.fromList [x | x <- [xl..xh], not (x `IntSet.member` ys)]

null :: Domain -> Bool
null (Set xs) = IntSet.null xs
null (Range xl xh) = xl > xh

singleton :: Int -> Domain
singleton x = Set (IntSet.singleton x)

isSingleton :: Domain -> Bool
isSingleton (Set xs) = case IntSet.elems xs of
    [_] -> True
    _   -> False
isSingleton (Range xl xh) = xl == xh

filterLessThan :: Int -> Domain -> Domain
filterLessThan n (Set xs) = Set $ IntSet.filter (< n) xs
filterLessThan n (Range xl xh) = Range xl (min (n-1) xh)

filterGreaterThan :: Int -> Domain -> Domain
filterGreaterThan n (Set xs) = Set $ IntSet.filter (> n) xs
filterGreaterThan n (Range xl xh) = Range (max (n+1) xl) xh

findMax :: Domain -> Int
findMax (Set xs) = IntSet.findMax xs
findMax (Range _ xh) = xh

findMin :: Domain -> Int
findMin (Set xs) = IntSet.findMin xs
findMin (Range xl _) = xl

maxDomain :: Domain
maxDomain = Range minBound maxBound


text:
import functions.Function1;
import functions.MemoizationUtils;
import functions.MemoizedFunction1;
import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class MemoizationTest  {
    private final Function1<Integer, Integer> fib =
            new Function1<Integer, Integer>() {
        @Override
        public Integer evaluate(final Function1<Integer, Integer> self,
                                final Integer i1) {
            if (i1 == 0 || i1 == 1) return 1;
            return self.apply(i1 - 1).get() + self.apply(i1 - 2).get();
        }
    };

    final Function1<Integer, Integer> memoFib =
            new MemoizedFunction1<Integer, Integer>() {
        @Override
        public Integer evaluate(final Function1<Integer, Integer> self,
                                final Integer i1) {
            if (i1 == 0 || i1 == 1) return 1;
            return apply(i1 - 1).get() + apply(i1 - 2).get();
        }
    };

    @Test
    public void testUnmemoizedFibonacci() {
        long start = System.currentTimeMillis();
        fib.apply(40).get();
        long end = System.currentTimeMillis();
        assertTrue(end - start > 2000);
        System.out.println("Unmemoized took " + (end - start));
    }

    @Test
    public void testMemoizedFibonacci() {
        long start = System.currentTimeMillis();
        memoFib.apply(40).get();
        long end = System.currentTimeMillis();
        assertTrue(end - start < 100);
        System.out.println("Memoized took " + (end - start));
    }

    @Test
    public void testRuntimeMemoization() {
        long start = System.currentTimeMillis();
        MemoizationUtils.memoize(fib).apply(40).get();
        long end = System.currentTimeMillis();
        assertTrue(end - start < 100);
    }
}


text:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:text="@string/dl_select"
        android:textColor="#38b0de"
        android:textSize="30sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginBottom="-2dp"
        android:background="#38b0de" />

    <ListView
        android:id="@+id/lvDevice"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:stackFromBottom="true" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#38b0de" />

    <EditText
        android:id="@+id/etInputName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:hint="@string/dl_enter"
        android:lines="1"
        android:textColor="#ffffff" />

    <Button
        android:id="@+id/btnStartScan"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="@string/dl_start"
        android:textColor="#ffffff"
        android:textSize="20sp" />

    <Button
        android:id="@+id/btnCancelScan"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:gravity="center"
        android:text="@string/dl_cancel"
        android:textColor="#ffffff"
        android:textSize="20sp" />

</LinearLayout>


text:
<?php

namespace LiveCMS\Models;

use LiveCMS\Models\Core\BaseModel;
use LiveCMS\Models\Traits\AuthorModelTrait;

class Tag extends BaseModel
{
    use AuthorModelTrait;

    protected $useAuthorization = false;

    protected $fillable = ['tag', 'slug'];

    protected $forms = [
        'text' => ['tag', 'slug']
    ];

    public function rules()
    {
        $this->slugify('tag');

        return [
            'tag' => $this->uniqify('tag'),
            'slug' => $this->uniqify('slug'),
        ];
    }
}