text:
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Fody;
using LinqToTwitter;
using Newtonsoft.Json;
using Twice.Models.Twitter;
using Twice.Models.Twitter.Entities;

namespace Twice.Models.Cache
{
	[ConfigureAwait( false )]
	internal partial class SqliteCache : ICache
	{
		public SqliteCache( string connectionString )
		{
			Connection = new SQLiteConnection( connectionString );
			Connection.Open();

			Init();
		}

		public SqliteCache( SQLiteConnection connection )
		{
			Connection = connection;

			Init();
		}

		private async Task Cleanup()
		{
			string[] tables =
			{
				"Users", "TwitterConfig", "Hashtags", "Statuses", "Messages"
			};

			ulong now = SqliteHelper.GetDateValue( DateTime.Now );

			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					foreach( var table in tables )
					{
						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = $"DELETE FROM {table} WHERE Expires < @now;";
							cmd.AddParameter( "now", now );
							await cmd.ExecuteNonQueryAsync();
						}
					}

					using( var cmd = Connection.CreateCommand() )
					{
						cmd.CommandText = "DELETE FROM ColumnStatuses WHERE NOT EXISTS (Select s.Id FROM Statuses s WHERE s.Id = ColumnStatuses.StatusId);";
						await cmd.ExecuteNonQueryAsync();
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		private void Init()
		{
			foreach( var qry in GetDdlQueries().Concat( GetInitQueries() ) )
			{
				using( var cmd = Connection.CreateCommand() )
				{
					cmd.CommandText = qry;
					cmd.ExecuteNonQuery();
				}
			}
		}

		public async Task AddHashtags( IList<string> hashTags )
		{
			if( !hashTags.Any() )
			{
				return;
			}

			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					using( var cmd = Connection.CreateCommand() )
					{
						cmd.CommandText = "INSERT INTO Hashtags (Tag, Expires) VALUES ";
						cmd.CommandText += string.Join( ",", hashTags.Select( ( h, i ) =>
						{
							// ReSharper disable AccessToDisposedClosure
							cmd.AddParameter( $"tag{i}", h );

							// ReSharper restore AccessToDisposedClosure

							return $"( @tag{i}, @expires )";
						} ) );

						cmd.AddParameter( "expires", SqliteHelper.GetDateValue( DateTime.Now.Add( Constants.Cache.HashtagExpiration ) ) );

						await cmd.ExecuteNonQueryAsync();
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task AddMessages( IList<MessageCacheEntry> messages )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					int count = messages.Count;
					const int batchSize = 100;
					int runsNeeded = (int)Math.Ceiling( count / (float)batchSize );

					for( int batchIdx = 0; batchIdx < runsNeeded; ++batchIdx )
					{
						var items = messages.Skip( batchIdx * batchSize ).Take( batchSize );

						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = "INSERT OR REPLACE INTO Messages (Id, Sender, Recipient, Data, Expires) VALUES ";

							cmd.CommandText += string.Join( ",", items.Select( ( s, i ) =>
							{
								// ReSharper disable AccessToDisposedClosure
								cmd.AddParameter( $"id{i}", s.Id );
								cmd.AddParameter( $"sender{i}", s.Sender );
								cmd.AddParameter( $"recipient{i}", s.Recipient );
								cmd.AddParameter( $"json{i}", s.Data );

								// ReSharper restore AccessToDisposedClosure

								return $"( @id{i}, @sender{i}, @recipient{i}, @json{i}, @expires )";
							} ) );

							cmd.AddParameter( "expires", SqliteHelper.GetDateValue( DateTime.Now.Add( Constants.Cache.MessageExpiration ) ) );
							await cmd.ExecuteNonQueryAsync();
						}
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task AddStatuses( IList<Status> statuses )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					int count = statuses.Count;
					const int batchSize = 100;
					int runsNeeded = (int)Math.Ceiling( count / (float)batchSize );

					for( int batchIdx = 0; batchIdx < runsNeeded; ++batchIdx )
					{
						var items = statuses.Skip( batchIdx * batchSize ).Take( batchSize );

						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = "INSERT OR REPLACE INTO Statuses (Id, UserId, StatusData, Expires) VALUES ";

							cmd.CommandText += string.Join( ",", items.Select( ( s, i ) =>
							{
								// ReSharper disable AccessToDisposedClosure
								cmd.AddParameter( $"id{i}", s.GetStatusId() );
								cmd.AddParameter( $"userid{i}", s.User.GetUserId() );
								cmd.AddParameter( $"json{i}", JsonConvert.SerializeObject( s ) );

								// ReSharper restore AccessToDisposedClosure

								return $"( @id{i}, @userid{i}, @json{i}, @expires )";
							} ) );

							cmd.AddParameter( "expires", SqliteHelper.GetDateValue( DateTime.Now.Add( Constants.Cache.StatusExpiration ) ) );
							await cmd.ExecuteNonQueryAsync();
						}
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task AddUsers( IList<UserCacheEntry> users )
		{
			int count = users.Count;
			const int batchSize = 100;
			int runsNeeded = (int)Math.Ceiling( count / (float)batchSize );

			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					for( int batchIdx = 0; batchIdx < runsNeeded; ++batchIdx )
					{
						var items = users.Skip( batchIdx * batchSize ).Take( batchSize );

						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = "INSERT OR REPLACE INTO Users (Id, UserName, UserData, Expires) VALUES ";

							cmd.CommandText += string.Join( ",", items.Select( ( u, i ) =>
							{
								// ReSharper disable AccessToDisposedClosure
								cmd.AddParameter( $"userId{i}", u.UserId );
								cmd.AddParameter( $"userName{i}", u.UserName );
								cmd.AddParameter( $"json{i}", u.Data );

								// ReSharper restore AccessToDisposedClosure

								return $"( @userId{i}, @userName{i}, @json{i}, @expires )";
							} ) );

							cmd.AddParameter( "expires", SqliteHelper.GetDateValue( DateTime.Now.Add( Constants.Cache.UserInfoExpiration ) ) );
							await cmd.ExecuteNonQueryAsync();
						}
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task Clear()
		{
			string[] tables =
			{
				"Users", "TwitterConfig", "Hashtags", "Statuses", "Messages"
			};

			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					foreach( var table in tables )
					{
						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = $"DELETE FROM {table};";
							await cmd.ExecuteNonQueryAsync();
						}
					}

					using( var cmd = Connection.CreateCommand() )
					{
						cmd.CommandText = "DELETE FROM ColumnStatuses";
						await cmd.ExecuteNonQueryAsync();
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task<ulong> FindFriend( ulong friendId )
		{
			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT UserId FROM UserFriends WHERE FriendId = @friendId LIMIT 1;";
				cmd.AddParameter( "friendId", friendId );

				var db = await cmd.ExecuteScalarAsync();
				if( db == null )
				{
					return 0;
				}

				return (ulong)Convert.ChangeType( db, typeof( ulong ) );
			}
		}

		public async Task<IEnumerable<string>> GetKnownHashtags()
		{
			await Cleanup();

			List<string> tags = new List<string>();
			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT Tag FROM Hashtags;";
				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						tags.Add( await reader.GetFieldValueAsync<string>( 0 ) );
					}
				}
			}

			return tags;
		}

		public async Task<IEnumerable<UserCacheEntry>> GetKnownUsers()
		{
			await Cleanup();

			List<UserCacheEntry> result = new List<UserCacheEntry>();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT Id, UserName, UserData FROM Users;";

				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						result.Add( await UserCacheEntry.Read( reader ) );
					}
				}
			}

			return result;
		}

		public async Task<List<MessageCacheEntry>> GetMessages()
		{
			await Cleanup();

			List<MessageCacheEntry> result = new List<MessageCacheEntry>();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT Id, Sender, Recipient, Data FROM Messages;";

				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						result.Add( await MessageCacheEntry.Read( reader ) );
					}
				}
			}

			return result;
		}

		public async Task<Status> GetStatus( ulong id )
		{
			await Cleanup();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT StatusData FROM Statuses WHERE id = @id;";
				cmd.AddParameter( "id", id );

				var json = await cmd.ExecuteScalarAsync() as string;
				return json == null
					? null
					: JsonConvert.DeserializeObject<Status>( json );
			}
		}

		public async Task<List<Status>> GetStatusesForColumn( Guid columnId, int limit )
		{
			await Cleanup();

			List<Status> result = new List<Status>();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText =
					"SELECT s.StatusData FROM ColumnStatuses c JOIN Statuses s ON c.StatusId = s.Id " +
					" WHERE c.ColumnId = @columnId ORDER BY s.Id DESC LIMIT 0, @limit";
				cmd.AddParameter( "columnId", columnId );
				cmd.AddParameter( "limit", limit );

				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						var json = await reader.GetFieldValueAsync<string>( 0 );
						result.Add( JsonConvert.DeserializeObject<Status>( json ) );
					}
				}
			}

			return result;
		}

		public async Task<List<Status>> GetStatusesForUser( ulong userId )
		{
			await Cleanup();

			List<Status> result = new List<Status>();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT StatusData FROM Statuses WHERE UserId = @userId;";
				cmd.AddParameter( "userId", userId );

				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						var json = await reader.GetFieldValueAsync<string>( 0 );
						result.Add( JsonConvert.DeserializeObject<Status>( json ) );
					}
				}
			}

			return result;
		}

		public async Task<UserEx> GetUser( ulong userId )
		{
			await Cleanup();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT UserData FROM Users WHERE Id = @userId;";
				cmd.AddParameter( "userId", userId );

				var json = await cmd.ExecuteScalarAsync() as string;
				if( !string.IsNullOrEmpty( json ) )
				{
					return JsonConvert.DeserializeObject<UserEx>( json );
				}
			}

			return null;
		}

		public async Task<IEnumerable<ulong>> GetUserFriends( ulong userId )
		{
			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT FriendId FROM UserFriends WHERE UserId = @userId;";
				cmd.AddParameter( "userId", userId );

				List<ulong> result = new List<ulong>();
				using( var reader = await cmd.ExecuteReaderAsync() )
				{
					while( await reader.ReadAsync() )
					{
						result.Add( (ulong)Convert.ChangeType( reader.GetValue( 0 ), typeof( ulong ) ) );
					}
				}
				return result;
			}
		}

		public async Task MapStatusesToColumn( IList<Status> statuses, Guid columnId )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					int count = statuses.Count;
					const int batchSize = 100;
					int runsNeeded = (int)Math.Ceiling( count / (float)batchSize );

					for( int batchIdx = 0; batchIdx < runsNeeded; ++batchIdx )
					{
						var items = statuses.Skip( batchIdx * batchSize ).Take( batchSize );

						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = "INSERT OR REPLACE INTO ColumnStatuses (ColumnId, StatusId) VALUES ";
							cmd.AddParameter( "columnId", columnId );

							cmd.CommandText += string.Join( ",", items.Select( ( s, i ) =>
							{
								// ReSharper disable AccessToDisposedClosure
								cmd.AddParameter( $"statusId{i}", s.GetStatusId() );

								// ReSharper restore AccessToDisposedClosure

								return $"( @columnId, @statusId{i} )";
							} ) );

							await cmd.ExecuteNonQueryAsync();
						}
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task<LinqToTwitter.Configuration> ReadTwitterConfig()
		{
			await Cleanup();

			using( var cmd = Connection.CreateCommand() )
			{
				cmd.CommandText = "SELECT Data FROM TwitterConfig;";
				var json = await cmd.ExecuteScalarAsync() as string;

				return string.IsNullOrEmpty( json )
					? null
					: JsonConvert.DeserializeObject<LinqToTwitter.Configuration>( json );
			}
		}

		public async Task RemoveStatus( ulong id )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var cmd = Connection.CreateCommand() )
				{
					cmd.CommandText = "DELETE FROM Statuses WHERE Id = @id;";
					cmd.AddParameter( "id", id );
					await cmd.ExecuteNonQueryAsync();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task SaveTwitterConfig( LinqToTwitter.Configuration cfg )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var cmd = Connection.CreateCommand() )
				{
					cmd.CommandText = "DELETE FROM TwitterConfig;";
					await cmd.ExecuteNonQueryAsync();
				}
				using( var cmd = Connection.CreateCommand() )
				{
					cmd.CommandText = "INSERT INTO TwitterConfig (Data, Expires) VALUES(@json, @expires);";
					cmd.AddParameter( "json", JsonConvert.SerializeObject( cfg ) );
					cmd.AddParameter( "expires",
						SqliteHelper.GetDateValue( DateTime.Now.Add( Constants.Cache.TwitterConfigExpiration ) ) );

					await cmd.ExecuteNonQueryAsync();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public async Task SetUserFriends( ulong userId, IEnumerable<ulong> friendIds )
		{
			if( !await Semaphore.WaitAsync( SemaphoreWait ) )
			{
				return;
			}

			try
			{
				using( var tx = new Transaction( Connection ) )
				{
					using( var cmd = Connection.CreateCommand() )
					{
						cmd.CommandText = "DELETE FROM UserFriends WHERE UserId = @userId;";
						cmd.AddParameter( "userId", userId );
						await cmd.ExecuteNonQueryAsync();
					}

					var friends = friendIds.ToArray();

					int count = friends.Length;
					const int batchSize = 100;
					int runsNeeded = (int)Math.Ceiling( count / (float)batchSize );

					for( int batchIdx = 0; batchIdx < runsNeeded; ++batchIdx )
					{
						var items = friends.Skip( batchIdx * batchSize ).Take( batchSize );

						using( var cmd = Connection.CreateCommand() )
						{
							cmd.CommandText = "INSERT INTO UserFriends (UserId, FriendId) VALUES ";
							cmd.AddParameter( "userId", userId );

							cmd.CommandText += string.Join( ",", items.Select( ( s, i ) =>
							{
								// ReSharper disable AccessToDisposedClosure
								cmd.AddParameter( $"friendId{i}", s );

								// ReSharper restore AccessToDisposedClosure

								return $"( @userId, @friendId{i} )";
							} ) );

							await cmd.ExecuteNonQueryAsync();
						}
					}

					tx.Commit();
				}
			}
			finally
			{
				Semaphore.Release();
			}
		}

		public void Dispose()
		{
			Connection.Dispose();
		}

		private readonly SQLiteConnection Connection;
		private readonly SemaphoreSlim Semaphore = new SemaphoreSlim( 1, 1 );
		private readonly TimeSpan SemaphoreWait = TimeSpan.FromSeconds( 10 );
	}
}


text:
export default class is {

	/**
	 * Array
	 *
	 * Uses the engines built in array checker function
	 *
	 * @name array
	 * @access public
	 * @static	 *
	 * @param mixed a
	 * @return bool
	 */
	static array(a) {
		return Array.isArray(a);
	}

	/**
	 * Float
	 *
	 * Returns true only if the value is a number
	 *
	 * @name float
	 * @access public
	 * @static
	 * @param mixed f
	 * @return bool
	 */
	static float(f) {
		return typeof f == 'number';
	}

	/**
	 * Integer
	 *
	 * Returns true only if the value is a number with no decimal part
	 *
	 * @name integer
	 * @access public
	 * @static
	 * @param mixed i
	 * @return bool
	 */
	static integer(i) {
		// If the value converted to a number is the same as itself
		//	and the number or'ed with 0 is still itthis.
		//	it's an integer
		return i === +i && i === (i|0);
	}

	/**
	 * Object
	 *
	 * Returns true only if the value is an Object instance and not an Array
	 *
	 * @name object
	 * @access public
	 * @static
	 * @param mixed o
	 * @return bool
	 */
	static object(o) {

		// If the value is null, it's not an Object
		if(o === null) {
			return false;
		}

		// If the value is not an Object, it's not an Object
		if(typeof o != 'object') {
			return false;
		}

		// If the value is an array, it's not an Object
		if(Array.isArray(o)) {
			return false;
		}

		// It must be an Object
		return true;
	}

	/**
	 * String
	 *
	 * Returns true only if the value is a String instance and not an Array
	 *
	 * @name string
	 * @access public
	 * @static
	 * @param mixed s
	 * @return bool
	 */
	static string(s) {
		return typeof s === 'string';
	}
}

redpajama_set_name: RedPajamaGithub


text:
/*
 * Copyright (c) 2009 Carnegie Mellon University.
 *     All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an "AS
 *  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied.  See the License for the specific language
 *  governing permissions and limitations under the License.
 *
 * For more about this software visit:
 *
 *      http://www.graphlab.ml.cmu.edu
 *
 */

#ifndef GRAPHLAB_RPC_CIRCULAR_IOVEC_BUFFER_HPP
#define GRAPHLAB_RPC_CIRCULAR_IOVEC_BUFFER_HPP
#include <vector>
#include <sys/socket.h>

namespace graphlab{
namespace dc_impl {

/**
 * \ingroup rpc
 * \internal
 * A circular buffer which maintains a parallel sequence of iovecs.
 * One sequence is basic iovecs
 * The other sequence is used for storing the original unomidifed pointers
 * This is minimally checked. length must be a power of 2
 */
struct circular_iovec_buffer {
  inline circular_iovec_buffer(size_t len = 4096) {
    v.resize(4096);
    parallel_v.resize(4096);
    head = 0;
    tail = 0;
    numel = 0;
  }

  inline bool empty() const {
    return numel == 0;
  }

  size_t size() const {
    return numel;
  }

  void reserve(size_t _n) {
    if (_n <= v.size()) return;
    size_t originalsize = v.size();
    size_t n = v.size();
    // must be a power of 2
    while (n <= _n) n *= 2;

    v.resize(n);
    parallel_v.resize(n);
    if (head >= tail && numel > 0) {
      // there is a loop around
      // we need to fix the shift
      size_t newtail = originalsize;
      for (size_t i = 0;i < tail; ++i) {
        v[newtail] = v[i];
        parallel_v[newtail] = parallel_v[i];
        ++newtail;
      }
      tail = newtail;
    }
  }

  inline void write(const std::vector<iovec>& other, size_t nwrite) {
    reserve(numel + nwrite);
    for (size_t i = 0;i < nwrite; ++i) {
      v[tail] = other[i];
      parallel_v[tail] = other[i];
      tail = (tail + 1) & (v.size() - 1);
    }
    numel += nwrite;

  }

  /**
   * Writes an entry into the buffer, resizing the buffer if necessary.
   * This buffer will take over all iovec pointers and free them when done
   */
  inline void write(const iovec &entry) {
    if (numel == v.size()) {
      reserve(2 * numel);
    }

    v[tail] = entry;
    parallel_v[tail] = entry;
    tail = (tail + 1) & (v.size() - 1); ++numel;
  }

  /**
   * Writes an entry into the buffer, resizing the buffer if necessary.
   * This buffer will take over all iovec pointers and free them when done.
   * This version of write allows the iovec that is sent to be different from the
   * iovec that is freed. (for instance, what is sent could be subarray of
   * what is to be freed.
   */
  inline void write(const iovec &entry, const iovec& actual_ptr_entry) {
    if (numel == v.size()) {
      reserve(2 * numel);
    }

    v[tail] = actual_ptr_entry;
    parallel_v[tail] = entry;
    tail = (tail + 1) & (v.size() - 1); ++numel;
  }

  /**
   * Erases a single iovec from the head and free the pointer
   */
  inline void erase_from_head_and_free() {
    free(v[head].iov_base);
    head = (head + 1) & (v.size() - 1);
    --numel;
  }

  /**
   * Fills a msghdr for unsent data.
   */
  void fill_msghdr(struct msghdr& data) {
    data.msg_iov = &(parallel_v[head]);
    if (head < tail) {
      data.msg_iovlen = tail - head;
    }
    else {
      data.msg_iovlen = v.size() - head;
    }
    data.msg_iovlen = std::min<size_t>(IOV_MAX, data.msg_iovlen);
  }

  /**
   * Advances the head as if some amount of data was sent.
   */
  void sent(size_t len) {
    while(len > 0) {
      size_t curv_sent_len = std::min(len, parallel_v[head].iov_len);
      parallel_v[head].iov_len -= curv_sent_len;
      parallel_v[head].iov_base = (char*)(parallel_v[head].iov_base) + curv_sent_len;
      len -= curv_sent_len;
      if (parallel_v[head].iov_len == 0) {
        erase_from_head_and_free();
      }
    }
  }

  std::vector<struct iovec> v;
  std::vector<struct iovec> parallel_v;
  size_t head;
  size_t tail;
  size_t numel;
};

}
}

#endif


text: java -cp bin gui.LineSegment


text:
#include "task.h"
#include "memory.h"
#include "isr.h"
#include "descriptors.h"
#include "heap.h"
#include "elf.h"
#include "../drivers/ext2.h"
#include "../libs/string.h"
#include "../drivers/screen.h"
#include "../drivers/keyboard.h"
#include "../asm/asmio.h"
#include "../libs/log.h"

// A pointer to the running task in the linked list of tasks
static task_t *runningTask;
// Represents the kernel task
static task_t mainTask;
unsigned int pid_counter = 0;

/**
 * @brief Initialize tasking capabilites
 *
 * @param regs
 */
void tasking_init(registers_t *regs)
{
    // Create a task for the kernel
    regs->useresp = regs->kesp;
    regs->ss = regs->ds;
    memcpy(&mainTask.regs, regs, (int)sizeof(registers_t)); // Save kernel task regs
    mainTask.next = &mainTask;
    set_kernel_stack((unsigned int)regs->kesp);
    // For now the the kernel is the main task (later will be set to terminal)
    runningTask = &mainTask;
}

/**
 * @brief Create a task
 *
 * @param task ptr to task_t data struct
 * @param main the task's entry point
 * @param flags the eflags register
 * @param pagedir physical address of the task's paging directory pointer table
 * @param user_esp task's userland stack
 * @param isr_esp task's kmode stack
 */
void task_create(
    task_t *task,
    void (*main)(),
    unsigned int flags,
    unsigned int pagedir,
    unsigned int user_esp,
    unsigned int isr_esp)
{
    task->regs.eax = 0;
    task->regs.ebx = 0;
    task->regs.ecx = 0;
    task->regs.edx = 0;
    task->regs.esi = 0;
    task->regs.edi = 0;
    task->regs.cs = 0x18 | 0x3; // Userland GDT selectors
    task->regs.ss = 0x20 | 0x3; // All tasks will run in userland
    task->regs.ds = 0x20 | 0x3; // ORed with CPL 3 (userland)
    task->regs.eflags = flags;
    task->regs.eip = (unsigned int)main;
    task->regs.cr3 = (unsigned int)pagedir;
    task->regs.useresp = (unsigned int)user_esp; // Proccess' stack
    task->regs.kesp = (unsigned int)isr_esp;     // ISR's stack (Ignored by roundRobinNext, see note in asmisr.asm)
    task->next = 0;
    task->pid = pid_counter++;
}

/**
 * @brief Add a task to the linked list of running task
 *
 * @param task
 */
void task_add(task_t *task)
{
    task->next = runningTask->next;
    runningTask->next = task;
}

/**
 * @brief Free a task's page frame
 *
 * @param pdpt
 */
void task_free_frames(page_directory_pointer_table_entry_t *pdpt)
{
    page_directory_table_entry_t *pdir;
    page_table_entry_t *ptab;
    int i, j, k;
    disablePagingAsm();
    for (i = 0; i < 4; i++)
    {
        if (pdpt[i].present)
        {
            pdir = (page_directory_table_entry_t *)(pdpt[i].page_directory_table_address << 12);
            for (j = 0; j < 512; j++)
            {
                if (pdir[j].present && !pdir[j].size)
                {
                    ptab = (page_table_entry_t *)(pdir[j].page_table_address << 12);
                    for (k = 0; k < 512; k++)
                    {
                        if (ptab[k].present)
                        {
                            kfree_frame(ptab[k].physical_page_address << 12);
                        }
                    }
                    kfree_frame(pdir[j].page_table_address << 12);
                }
            }
            kfree_frame(pdpt[i].page_directory_table_address << 12);
        }
    }
    kfree_frame((unsigned int)pdpt);
    enablePagingAsm();
}

/**
 * @brief Remove a task from the linked list of running tasks
 *
 * @note calls task_free_frames
 * @param regs
 */
void task_remove(registers_t *regs)
{
    task_t *prev = 0, *task_to_remove = 0;
    if (runningTask->next == runningTask)
    {
        runningTask->next = &mainTask;
        mainTask.next = &mainTask;
    }
    else
    {
        task_to_remove = prev = runningTask;
        while (prev->next != runningTask)
            prev = prev->next;
        prev->next = runningTask->next;
    }
    task_free_frames((page_directory_pointer_table_entry_t *)regs->cr3);
    task_roundRobinNext(regs);
    if (task_to_remove)
    {
        free(task_to_remove);
        task_to_remove = 0;
    }
}

/**
 * @brief Round robin next
 *
 * @param regs
 */
void task_roundRobinNext(registers_t *regs)
{
    task_t *last = runningTask;
    runningTask = runningTask->next;
    // Save last's state
    memcpy(&last->regs, regs, (int)sizeof(registers_t));
    // Load runningTask's state
    memcpy(regs, &runningTask->regs, (int)sizeof(registers_t));
    // Set ISR stack
    set_kernel_stack(mainTask.regs.kesp);
}

/**
 * @brief posix fork+execve, like CreateProcess in win32.
 *
 * @param path Command line
 * @param argc Argument count
 * @param argv Argument values
 */
void execve(char *path, int argc, char **argv)
{
    int inode_num = 0;
    void *file = 0;
    EXT2_INODE_t *inode = 0;

    inode_num = ext2_path_to_inode(path);

    inode = malloc(sizeof(EXT2_INODE_t));
    if (!inode)
        goto _cleanup_inode;

    ext2_load_inode(inode_num, inode);

    file = malloc(inode->size_low);
    if (!file)
        goto _cleanup_file;

    ext2_load_file(inode, 0, 0, file);

    if (elf_check_supported((Elf32_Ehdr_t *)file))
    {
        elf_load_file(file, argc, argv);
    }

_cleanup_file:
    if (file)
    {
        free(file);
        file = 0;
    }
_cleanup_inode:
    if (inode)
    {
        free(inode);
        inode = 0;
    }
}

void task_set_next_task_forever()
{
    runningTask->next->next = runningTask->next;
}

/**
 * @brief Dump a running tasks list
 *
 */
void task_print_task_linked_list()
{
    task_t *task_ptr = runningTask;
    do
    {
        puts((char *)&task_ptr->name);
        putc('[');
        screen_print_int(task_ptr->pid, 10);
        puts("] -> ");
        task_ptr = task_ptr->next;
    } while (task_ptr != runningTask);
    puts("\b\b\b");
    task_ptr = runningTask;
    do
    {
        putc('\n');
        puts((char *)&task_ptr->name);
        putc('[');
        screen_print_int(task_ptr->pid, 10);
        puts("]:\n");
        task_disp_heap(task_ptr->pid);
        getc();
        task_ptr = task_ptr->next;
    } while (task_ptr != runningTask);
}

/**
 * @brief Print the page frames in use by running tasks
 *
 */
void task_dump_all_task_memory_usage()
{
    puts("Loaded tasks: \n");
    task_t *ptr = runningTask;
    page_directory_pointer_table_entry_t *pdpt;
    page_directory_table_entry_t *pdir;
    page_table_entry_t *ptab;
    int i, j, k;
    disablePagingAsm();
    do
    {
        pdpt = (page_directory_pointer_table_entry_t *)ptr->regs.cr3;
        puts((char *)&ptr->name);
        putc('[');
        screen_print_int(ptr->pid, 10);
        puts("]: ");
        for (i = 0; i < 4; i++)
        {
            if (pdpt[i].present)
            {
                pdir = (page_directory_table_entry_t *)(pdpt[i].page_directory_table_address << 12);
                for (j = 0; j < 512; j++)
                {
                    if (pdir[j].present && !pdir[j].size)
                    {
                        ptab = (page_table_entry_t *)(pdir[j].page_table_address << 12);
                        for (k = 0; k < 512; k++)
                        {
                            if (ptab[k].present)
                            {
                                screen_print_int((ptab[k].physical_page_address << 12) / 0x1000, 10);
                                putc(',');
                            }
                        }
                        screen_print_int((pdir[j].page_table_address << 12) / 0x1000, 10);
                        putc(',');
                    }
                }
                screen_print_int((pdpt[i].page_directory_table_address << 12) / 0x1000, 10);
                putc(',');
            }
        }
        screen_print_int(((unsigned int)pdpt) / 0x1000, 10);
        putc('\n');
        ptr = ptr->next;
    } while (ptr != runningTask);
    enablePagingAsm();
}

/**
 * @brief Dump a task's heap
 *
 * @param pid
 */
void task_disp_heap(unsigned int pid)
{
    task_t *ptr = runningTask;
    memory_block_header_t *heap_ptr = (memory_block_header_t *)0x700000;
    unsigned int pdpt_bk, i;
    do
    {
        ptr = ptr->next;
    } while ((ptr->pid != pid) && (ptr != runningTask));
    pdpt_bk = swapPageDirectoryAsm((unsigned int *)ptr->regs.cr3);
    if (!heap_ptr->used)
        return;
    unsigned char c;
    do
    {
        screen_set_bgfg(0x70);
        puts("Length: ");
        screen_print_int(heap_ptr->length, 10);
        puts("B; used: ");
        if (heap_ptr->used)
            puts("yes");
        else
            puts("no");
        screen_set_bgfg(0x07);
        for (i = 0; i < heap_ptr->length; i++)
        {
            screen_set_bgfg(0x07);
            c = *((unsigned char *)((unsigned int)heap_ptr + sizeof(memory_block_header_t) + i));
            screen_print_int(c, 16);
            i++;
            screen_set_bgfg(0x0F);
            c = *((unsigned char *)((unsigned int)heap_ptr + sizeof(memory_block_header_t) + i));
            screen_print_int(c, 16);
        }
        heap_ptr = heap_ptr->next;
    } while (heap_ptr->length > 0);
    swapPageDirectoryAsm((unsigned int *)pdpt_bk);
    screen_set_bgfg(0x07);
}


text:
(($: JQueryStatic) => {
        'use strict';

        $.fn.tmDomSearch = function (sourceContainer: JQuery, resultContainer: JQuery, options?: TmDomSearchOptions) {
            const defaults: TmDomSearchOptions = {
                resultTitle: 'Filtered content',
                countToActivate: 2
            };
            var settings: TmDomSearchOptions = $.extend({}, defaults, options),
                resultHeader = $('

').text(settings.resultTitle + ':'),
                targets = $('[data-tm-search=clone]', sourceContainer),
                nodesToHide = $('[data-tm-search=hide]', sourceContainer);

            if (!nodesToHide.length) {
                nodesToHide = sourceContainer;
            }

            this.keyup(function () {
                var searchString: string = $(this).val();

                resultContainer.hide().empty();
                nodesToHide.show();

                if (searchString && searchString.length >= settings.countToActivate) {
                    var innerContainer = $(document.createElement('div'))
                        .addClass(resultContainer.attr('class'));

                    targets.each((index, elem) => {
                        var block = $(elem),
                            match = $('[data-tm-search=target]', block).text().search(new RegExp(searchString, 'i')) !== -1;

                        if (match) {
                            innerContainer.append(block.clone());
                        }
                    });

                    resultContainer.append(resultHeader, innerContainer)
                        .show();

                    nodesToHide.hide();
                }
            });
        };
    })(jQuery);


text:
#include "types/operations/comparisons/LessComparison.hpp"

#include <functional>

#include "types/operations/comparisons/AsciiStringComparators.hpp"
#include "types/operations/comparisons/AsciiStringComparators-inl.hpp"
#include "types/operations/comparisons/BasicComparison.hpp"
#include "types/operations/comparisons/LiteralComparators.hpp"
#include "types/operations/comparisons/LiteralComparators-inl.hpp"

namespace quickstep {

bool LessComparison::compareTypedValuesChecked(const TypedValue &left,
                                               const Type &left_type,
                                               const TypedValue &right,
                                               const Type &right_type) const {
  return compareTypedValuesCheckedHelper<std::less>(left, left_type,
                                                    right, right_type);
}

UncheckedComparator* LessComparison::makeUncheckedComparatorForTypes(const Type &left,
                                                                     const Type &right) const {
  return makeUncheckedComparatorForTypesHelper<LessLiteralUncheckedComparator,
                                               LessAsciiStringUncheckedComparator>(left, right);
}

}  // namespace quickstep


text:
/*
 * ParticlesEffect.cpp
 *
 *  Created on: Nov 4, 2012
 *      Author: arturo
 */

#include "ParticlesEffect.h"

// Set up texture sampling offset storage
const GLint tcOffsetColumns = 3;
const GLint tcOffsetRows    = 3;
GLfloat	texCoordOffsets[tcOffsetColumns * tcOffsetRows * 2];

ParticlesEffect::ParticlesEffect() {
	// TODO Auto-generated constructor stub

}

ParticlesEffect::~ParticlesEffect() {
	// TODO Auto-generated destructor stub
}

void ParticlesEffect::setup(){

	shader.load("","particles.frag");

	float xInc = 1;
	float yInc = 1;
	for (int i = 0; i < tcOffsetColumns; i++)
	{
		for (int j = 0; j < tcOffsetRows; j++)
		{
			texCoordOffsets[(((i*tcOffsetColumns)+j)*2)+0] = (-2.0f * xInc) + ((GLfloat)i * xInc);
			texCoordOffsets[(((i*tcOffsetRows)+j)*2)+1] = (-2.0f * yInc) + ((GLfloat)j * yInc);
		}
	}
	fbo1.allocate(114,35);
	fbo2.allocate(114,35);
}

void ParticlesEffect::begin(){
	fbo1.begin();
}

void ParticlesEffect::end(){
	fbo1.end();

	fbo2.begin();
	shader.begin();
	shader.setUniformTexture("src_tex_unit0",fbo1.getTextureReference(),0);
	shader.setUniform2fv("tcOffset",texCoordOffsets,tcOffsetColumns * tcOffsetRows);
	fbo1.draw(0,0);
	shader.end();
	fbo2.end();
}


text:
import React, { useEffect, useState } from 'react';
import useSwr, { mutate } from 'swr';

import {
  AnalyticsSession,
  Config,
  Emulator,
  hostAndPort,
} from '../../store/config';

const emulatorConfigContext = React.createContext<
  | {
      config?: Config | null;
      promise: Promise<Config | null | undefined>;
    }
  | undefined
>(undefined);

const CONFIG_API = '/api/config';

/**
 * Returns a promise that resolves when the data changes.
 *
 * Note: When the argument passed !== previously passed, the previously returned
 * promise is resolved and a new pending promise is returned (resolved on the
 * next change).
 *
 * @example
 *   const data = useMyAwesomeDataThatMayChange();
 *   const promise = useOnChangePromise(data);
 *   if (!someCondition(data)) throw promise; // use with <Suspense>
 */
export function useOnChangePromise<T>(data: T): Promise<T> {
  // Use only one single state to prevent accidental partial updates.
  const [state, setState] = useState(() => ({
    oldData: data,
    deferred: makeDeferred<T>(),
  }));

  useEffect(() => {
    if (data !== state.oldData) {
      const oldDeferred = state.deferred;
      setState({
        oldData: data,
        deferred: makeDeferred<T>(),
      });
      oldDeferred.resolve(data);
    }
  }, [data, state, setState]);
  return state.deferred.promise;
}

export const EmulatorConfigProvider: React.FC<
  React.PropsWithChildren<{ refreshInterval: number }>
> = ({ refreshInterval, children }) => {
  // We don't use suspense here since the provider should never be suspended --
  // it merely creates a context for hooks (e.g. useConfig) who do suspend.
  const { data } = useSwr<Config | null>(CONFIG_API, configFetcher, {
    // Keep refreshing config to detect when emulators are stopped or restarted
    // with a different config (e.g. different emulators or host / ports).
    refreshInterval,

    // Emulator UI works fully offline. Even if the browser cannot reach LAN or
    // any router, this page and the CONFIG_API will still work if they are on
    // the same physical device (e.g. localhost/127.0.0.1/containers/VMs). See:
    // https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine
    refreshWhenOffline: true,
    onErrorRetry(_, __, ___, revalidate, { retryCount }) {
      if (retryCount < 2) {
        // If the Emulator Hub is running locally, we are very unlikely to get
        // any errors at all. However, an occasional blip may happen when using
        // Emulator UI remotely (or through port forwarding). Let's retry once.
        // Note that swr will keep `data` while retrying, so UI won't unload.
        // (This overwrites swr's built-in exponential backoff timeouts.)
        setTimeout(() => revalidate({ retryCount }), refreshInterval);
      } else {
        // We cannot reach the discovery API for 2+ times. This usually means
        // Emulator Hub is stopped or unreachable. swr won't clear data on error
        // so we manually set data to null to represent this situation.
        // Tell swr to revalidate (retry the fetch). No need for setTimeout.
        mutate(CONFIG_API, null, /* shouldRevalidate= */ true);
      }
    },
  });

  const promise = useOnChangePromise(data);

  return (
    <emulatorConfigContext.Provider
      value={{
        config: data,
        promise,
      }}
    >
      {children}
    </emulatorConfigContext.Provider>
  );
};

export const TestEmulatorConfigProvider: React.FC<
  React.PropsWithChildren<{
    config: Config | null | undefined;
  }>
> = ({ config, children }) => {
  const promise = useOnChangePromise(config);
  return (
    <emulatorConfigContext.Provider
      value={{
        config,
        promise,
      }}
    >
      {children}
    </emulatorConfigContext.Provider>
  );
};

export function useConfig(): Config {
  const context = React.useContext(emulatorConfigContext);
  if (context === undefined) {
    throw new Error('useConfig must be used within a <EmulatorConfigProvider>');
  }
  if (context.config === undefined) {
    // Loading. Throw the promise to suspend rendering (to support <Suspense>).
    throw context.promise;
  } else if (context.config == null) {
    // Emulator Suite is disconnected / unreachable.
    throw context.promise;
  } else {
    return context.config;
  }
}

export function useEmulatorConfig<E extends Emulator>(
  emulator: E
): NonNullable<Config[E]> {
  const config = useConfig();
  const emulatorConfig = config[emulator];
  const promise = useOnChangePromise(emulatorConfig);
  if (emulatorConfig === undefined) {
    // Emulator Suite is running, but the specified emulator is not running.
    throw promise;
  }
  // Needed to convince TypeScript that emulatorConfig is not undefined.
  return emulatorConfig as NonNullable<Config[E]>;
}

export function useIsEmulatorDisabled(emulator?: Emulator): boolean {
  const config = useConfigOptional();
  if (config === undefined) {
    // Still loading, we cannot tell if emulator is disabled.
    return false;
  }
  if (config === null) {
    // The whole suite is disconnected, so we show all emulators as disabled.
    return true;
  }
  if (emulator && !config[emulator]) {
    return true;
  }
  return false;
}

/**
 * Try getting Config, but return null if disconnected or undefined if loading.
 * Should be used very sparingly. Prefer useConfig() for most cases.
 */
export function useConfigOptional(): Config | undefined | null {
  const context = React.useContext(emulatorConfigContext);
  if (context === undefined) {
    throw new Error(
      'useConfigOptional must be used within a <EmulatorConfigProvider>'
    );
  }
  return context.config;
}

async function jsonFetcher<T>(url: string): Promise<T> {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Got HTTP status code ${response.status}`);
  }
  return response.json();
}

async function configFetcher(url: string): Promise<Config> {
  const json = (await jsonFetcher(url)) as any;
  const result: Config = {
    projectId: json.projectId as string,
    analytics: json.analytics as AnalyticsSession,
  };
  for (const [key, value] of Object.entries<any>(json)) {
    if (key === 'projectId' || key === 'analytics') {
      continue;
    }
    let host = value.host as string;
    let port = value.port as number;
    // For emulators listening using wildcard, we assume that they can be connected
    // using the same hostname as the current page (but different ports of course).
    // This works for local setup as well as running the suite (emulators + UI)
    // remotely and connect from another device. It does not work for some setups
    // e.g. when Emulator UI is proxied but not the individual emulators.
    for (const listen of (value.listen ?? []) as {
      host: string;
      port: number;
    }[]) {
      if (listen.host === '0.0.0.0') {
        port = listen.port;
        host = window.location.hostname;
        if (!host || host === 'localhost') {
          // Replace localhost with IPv4 loopback since some browsers / OSes may
          // resolve it to IPv6 and connection may fail.
          host = '127.0.0.1';
        }
        break;
      } else if (listen.host === '::') {
        port = listen.port;
        host = window.location.hostname;
        if (!host || host === 'localhost') {
          // Ditto for IPv6.
          host = '::1';
        }
        break;
      }
    }
    result[key as Emulator] = {
      ...value,
      host,
      port,
      hostAndPort: hostAndPort(host, port),
    };
  }

  if (result.firestore?.webSocketPort) {
    // Apply the same `host` change above to the WebSocket server.
    result.firestore.webSocketHost = result.firestore.host;
  }
  return result;
}

export function makeDeferred<T>() {
  let resolve!: (value: T) => void;
  const promise = new Promise<T>((res) => {
    resolve = res;
  });
  return { promise, resolve };
}


text:
layout: post
title:  Junit5-14-Repeated Tests
date:  2018-06-25 18:57:21 +0800
categories: [Test]
tags: [test, sh]
published: true
---

# 重复测试

JUnit Jupiter提供了通过使用@RepeatedTest注释方法并指定所需重复次数的能力。重复测试的每次调用都表现为对相同生命周期回调和扩展的完全支持的常规@Test方法的执行。

下面的示例演示如何声明一个名为repeatedTest()的测试,它将自动重复10次。

```java
@RepeatedTest(10)
void repeatedTest() {
    // ...
}
```

## 特性说明

除了指定重复次数之外,还可以通过 `@RepeatedTest` 注释的name属性为每次重复配置自定义显示名。
此外,显示名称可以是由静态文本和动态占位符组合而成的模式。目前支持以下占位符。

{displayName}: @RepeatedTest方法的显示名称。

{currentRepetition}:当前重复计数

{总重复}:总重复次数

给定重复的默认显示名称是基于以下模式生成的: `repetition {currentRepetition} of {totalRepetitions}`。
因此,显示名称为个人重复以前的repeatedTest()的例子是: `repetition 1 of 10, repetition 2 of 10`,等等。
如果你想要显示的名称@RepeatedTest方法包含在每个重复的名称,您可以定义自己的自定义模式或使用预定义的 `RepeatedTest.LONG_DISPLAY_NAME` 模式。
后者等于`{displayName}:repetition{totalrepeat}`,这导致了 `repeatedTest() :: repetition 1 of 10`,
`repeatedTest() :: repetition 2 of 10`,等等。

为了检索有关当前重复的信息和编程的总重复次数,开发人员可以选择将重复信息的实例注入到@RepeatedTest、@BeforeEach或@AfterEach方法中。

## 测试案例

本节末尾的RepeatedTestsDemo类演示了几个重复测试的示例。

repeatedTest()方法与前一节中的示例相同;
然而,repeatedtestwithtioninfo()演示了如何将一个 `RepetitionInfo` 实例注入到测试中,以访问当前重复测试的总重复次数。

接下来的两个方法演示了如何在每次重复的显示名中包含@RepeatedTest方法的自定义@DisplayName。
customDisplayName()将自定义显示名称与自定义模式组合在一起,然后使用TestInfo来验证生成的显示名称的格式。
`Repeat!` 是来自@DisplayName声明的{displayName},
而`1/1`来自{currentrepeat}/{totalrepeat}。
相反,customDisplayNameWithLongPattern()使用前面提到的预定义 `RepeatedTest.LONG_DISPLAY_NAME` 模式。

repeatedTestInGerman()演示了将重复测试的名称翻译成外语的能力——在本例中是德语,导致了单个重复的名称,
比如:

```
Wiederholung 1 von 5, Wiederholung 2 von 5
```

因为beforeEach()方法是用@BeforeEach注释的,所以每次重复测试之前都会执行它。
通过将TestInfo和repeat tioninfo注入到方法中,我们可以获得关于当前正在执行的重复测试的信息。
在下面的输出中,使用信息日志级别启用的结果执行RepeatedTestsDemo。

- 日志

```
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 1 of 10 for repeatedTest

Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 2 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 3 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 4 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 5 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 6 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 7 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 8 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 9 of 10 for repeatedTest
Jun 25, 2018 7:09:09 PM com.github.houbb.jdk.junit5.repeat.RepeatedTestsDemo beforeEach
信息: About to execute repetition 10 of 10 for repeatedTest
```

## 实例

- RepeatedTestsDemo.java

```java
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.TestInfo;

import java.util.logging.Logger;

public class RepeatedTestsDemo {
    Logger logger = Logger.getLogger(RepeatedTestsDemo.class.getName());

    @BeforeEach
    void beforeEach(TestInfo testInfo, RepetitionInfo repetitionInfo) {
        int currentRepetition = repetitionInfo.getCurrentRepetition();
        int totalRepetitions = repetitionInfo.getTotalRepetitions();
        String methodName = testInfo.getTestMethod().get().getName();
        logger.info(String.format("About to execute repetition %d of %d for %s", //
                currentRepetition, totalRepetitions, methodName));
    }

    @RepeatedTest(10)
    void repeatedTest() {
        // ...
    }

    @RepeatedTest(5)
    void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
        assertEquals(5, repetitionInfo.getTotalRepetitions());
    }

    @RepeatedTest(value = 1, name = "{displayName} {currentRepetition}/{totalRepetitions}")
    @DisplayName("Repeat!")
    void customDisplayName(TestInfo testInfo) {
        assertEquals(testInfo.getDisplayName(), "Repeat! 1/1");
    }

    @RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
    @DisplayName("Details...")
    void customDisplayNameWithLongPattern(TestInfo testInfo) {
        assertEquals(testInfo.getDisplayName(), "Details... :: repetition 1 of 1");
    }

    @RepeatedTest(value = 5, name = "Wiederholung {currentRepetition} von {totalRepetitions}")
    void repeatedTestInGerman() {
        // ...
    }
}
```

* any list
{:toc}


text:
using System.Collections.Generic;

namespace Logger.Models.Interfaces
{
    public interface ILogger
    {
        IReadOnlyCollection<IAppender> Appenders { get; }

        void Log(IError error);
    }
}


text:
(function() {var implementors = {};
implementors["tokio_http2"] = ["impl<S> Serializer for SerdeSerializer<S> where S: Serializer",];

            if (window.register_implementors) {
                window.register_implementors(implementors);
            } else {
                window.pending_implementors = implementors;
            }

})()


text:
/**
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */
/* Generated By:JJTree: Do not edit this line. ASTTypeArgument.java */

package net.sourceforge.pmd.lang.java.ast;

public class ASTTypeArgument extends AbstractJavaNode {
    public ASTTypeArgument(int id) {
        super(id);
    }

    public ASTTypeArgument(JavaParser p, int id) {
        super(p, id);
    }

    /**
     * Accept the visitor. *
     */
    public Object jjtAccept(JavaParserVisitor visitor, Object data) {
        return visitor.visit(this, data);
    }
}


text:
FROM ubuntu:14.04
MAINTAINER Cogniteev <tech@cogniteev.com>

ENV RSYSLOG8_VERSION=8.14.0

RUN apt-get install -y software-properties-common && \
    add-apt-repository ppa:adiscon/v8-stable      && \
    apt-get update                                && \
    apt-get install -y "rsyslog=${RSYSLOG8_VERSION}-0adiscon1trusty1"

# Copy config files of dependant images
ONBUILD ADD rsyslog.d/* /etc/rsyslog.d/

CMD rsyslogd -n


text: {{ include.caption }}


text:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<!-- Well-formed and valid xml file -->
<client-cache xmlns="http://geode.apache.org/schema/cpp-cache"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://geode.apache.org/schema/cpp-cache http://geode.apache.org/schema/cpp-cache/cpp-cache-1.0.xsd"
              version="1.0">

 <region name = "Root1" >
    <region-attributes id="root1" scope="local" caching-enabled="true" initial-capacity="25" load-factor="0.32" concurrency-level="10" lru-entries-limit = "35">
       <region-idle-time>
         <expiration-attributes timeout="20s" action="destroy"/>
       </region-idle-time>
       <entry-idle-time>
         <expiration-attributes timeout="10s" action="invalidate"/>
       </entry-idle-time>
       <region-time-to-live>
         <expiration-attributes timeout="0s" action="local-destroy"/>
       </region-time-to-live>
       <entry-time-to-live>
         <expiration-attributes timeout="0s" action="local-invalidate"/>
       </entry-time-to-live>
    </region-attributes>

    <region name="SubRegion1">
         <region-attributes id="sub1" scope="local" caching-enabled="true" initial-capacity="23" load-factor=".89" concurrency-level="52">
         </region-attributes>

         <region name="SubRegion11">
         	<region-attributes id="sub11" refid="sub1" initial-capacity="10" />
    	 </region>
    </region>

    <region name="SubRegion2">
    	<region-attributes refid="sub11" />
    </region>

 </region>

 <region name= "Root2">
    <region-attributes refid="root1" concurrency-level="16" >
      <region-time-to-live>
        <expiration-attributes timeout="0s" action="destroy"/>
      </region-time-to-live>
       <region-idle-time>
        <expiration-attributes timeout="0s" action="invalidate"/>
      </region-idle-time>
    </region-attributes>

    <region name="SubRegion21">
         <region-attributes refid="sub11">
            <region-idle-time>
               <expiration-attributes timeout="20s" action="destroy"/>
            </region-idle-time>
            <entry-idle-time>
               <expiration-attributes timeout="10s" action="invalidate"/>
            </entry-idle-time>
         </region-attributes>
    </region>

 </region>

</client-cache>


text:
Autonomous Surface Vehicle Payload Autonomy Interface
=====================================================

Build Instructions
------------------

  1. Checkout the moos-ivp-extend tree

  svn co https://oceanai.mit.edu/svn/moos-ivp-extend/trunk moos-ivp-extend

  2. Navigate to the moos-ivp-extend folder

  cd moos-ivp-extend

  3. Check out the `src` folder of the trunk of the ASV repository (you may need to delete local .svn directories first)

  svn co https://mbogo.svn.cloudforge.com/seniorproject/trunk/src

  4. Run the `build.sh` script provided by moos-ivp-extend

  ./build.sh

  5. The iMOOSArduino and pMOOSArduinoTester applications should now be found in the `bin` folder


text:
package com.dianping.cat.report.page.state;

public enum JspFile {
	HOURLY("/jsp/report/state/state.jsp"),

	HISTORY("/jsp/report/state/stateHistory.jsp"),

	GRAPH("/jsp/report/state/stateGraphs.jsp"),

	HISTORY_GRAPH("/jsp/report/state/stateGraphs.jsp");

	private String m_path;

	private JspFile(String path) {
		m_path = path;
	}

	public String getPath() {
		return m_path;
	}
}


text:
package com.github.stigmata;

import com.github.stigmata.filter.Criterion;
import com.github.stigmata.spi.ComparisonPairFilterService;

/**
 * Filtering results by some criteria.
 * For example,
 *

 *
extract comparison pairs which similarity over 0.8, and

 *
extract comparison pairs which similarity over 0.8 and element count over 10.

 *

 *
 * @author Haruaki TAMADA
 */
public interface ComparisonPairFilter{
    public boolean isFiltered(ComparisonPair pair);

    public Criterion[] getAcceptableCriteria();

    public boolean isAcceptable(Criterion criterion);

    public void setCriterion(Criterion criterion);

    public Criterion getCriterion();

    public ComparisonPairFilterService getService();
}


text:
<?xml version="1.0" encoding="UTF-8"?><!--
	version $Rev: 47160 $
	@levd.rating GREEN Hash: 321A395008C5E5041E8DA51C54A089BE
-->
<bundle xmlns="http://conqat.cs.tum.edu/ns/bundle">
   <name>Self Bundle</name>
   <provider>The ConQAT Project</provider>
   <description>
		Processors for analyzing ConQAT and its bundles.
	</description>
   <version major="2013" minor="12"/>
   <requiresCore major="2013" minor="12"/>
   <dependsOn bundleId="org.conqat.engine.commons" major="2013" minor="12"/>
   <dependsOn bundleId="org.conqat.engine.java" major="2013" minor="12"/>
   <dependsOn bundleId="org.conqat.engine.graph" major="2013" minor="12"/>
   <dependsOn bundleId="org.conqat.engine.html_presentation" major="2013" minor="12"/>
</bundle>


text:
using System;

namespace BluffinMuffin.Server.DataTypes.EventHandling
{
    public class ModuleEventArg : EventArgs
    {
        public IGameModule Module { get; set; }
    }
}


text:
/* eslint-disable */

'use strict';

/*::
import type { ConcreteRequest, Query } from 'relay-runtime';
type UserClientEdgeResolver$key = any;
import userClientEdgeResolver from "../resolvers/UserClientEdgeResolver.js";
// Type assertion validating that `userClientEdgeResolver` resolver is correctly implemented.
// A type error here indicates that the type signature of the resolver module is incorrect.
(userClientEdgeResolver: (
  rootKey: UserClientEdgeResolver$key,
) => mixed);
export type RelayReaderClientEdgesTest6Query$variables = {||};
export type RelayReaderClientEdgesTest6Query$data = {|
  +me: ?{|
    +the_alias: ?{|
      +name: ?string,
    |},
  |},
|};
export type RelayReaderClientEdgesTest6Query = {|
  response: RelayReaderClientEdgesTest6Query$data,
  variables: RelayReaderClientEdgesTest6Query$variables,
|};
*/

var node/*: ConcreteRequest*/ = (function(){
var v0 = {
  "alias": null,
  "args": null,
  "kind": "ScalarField",
  "name": "name",
  "storageKey": null
};
return {
  "fragment": {
    "argumentDefinitions": [],
    "kind": "Fragment",
    "metadata": {
      "hasClientEdges": true
    },
    "name": "RelayReaderClientEdgesTest6Query",
    "selections": [
      {
        "alias": null,
        "args": null,
        "concreteType": "User",
        "kind": "LinkedField",
        "name": "me",
        "plural": false,
        "selections": [
          {
            "kind": "ClientEdgeToServerObject",
            "operation": require('./ClientEdgeQuery_RelayReaderClientEdgesTest6Query_me__the_alias.graphql'),
            "backingField": {
              "alias": "the_alias",
              "args": null,
              "fragment": {
                "args": null,
                "kind": "FragmentSpread",
                "name": "UserClientEdgeResolver"
              },
              "kind": "RelayResolver",
              "name": "client_edge",
              "resolverModule": require('./../resolvers/UserClientEdgeResolver.js'),
              "path": "me.the_alias"
            },
            "linkedField": {
              "alias": "the_alias",
              "args": null,
              "concreteType": "User",
              "kind": "LinkedField",
              "name": "client_edge",
              "plural": false,
              "selections": [
                (v0/*: any*/)
              ],
              "storageKey": null
            }
          }
        ],
        "storageKey": null
      }
    ],
    "type": "Query",
    "abstractKey": null
  },
  "kind": "Request",
  "operation": {
    "argumentDefinitions": [],
    "kind": "Operation",
    "name": "RelayReaderClientEdgesTest6Query",
    "selections": [
      {
        "alias": null,
        "args": null,
        "concreteType": "User",
        "kind": "LinkedField",
        "name": "me",
        "plural": false,
        "selections": [
          (v0/*: any*/),
          {
            "alias": null,
            "args": null,
            "kind": "ScalarField",
            "name": "id",
            "storageKey": null
          }
        ],
        "storageKey": null
      }
    ]
  },
  "params": {
    "cacheID": "80412f2805c0f96efd2fb86ce6ef3008",
    "id": null,
    "metadata": {},
    "name": "RelayReaderClientEdgesTest6Query",
    "operationKind": "query",
    "text": "query RelayReaderClientEdgesTest6Query {\n  me {\n    ...UserClientEdgeResolver\n    id\n  }\n}\n\nfragment UserClientEdgeResolver on User {\n  name\n}\n"
  }
};
})();

if (__DEV__) {
  (node/*: any*/).hash = "9b8dd5eefbc4ad7a0eb7a42257b6abb5";
}

module.exports = ((node/*: any*/)/*: Query<
  RelayReaderClientEdgesTest6Query$variables,
  RelayReaderClientEdgesTest6Query$data,
>*/);


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

'use strict';

/**
 * Import the GoogleAuth library, and create a new GoogleAuth client.
 */
const {GoogleAuth} = require('google-auth-library');

/**
 * Acquire a client, and make a request to an API that's enabled by default.
 */
async function main() {
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/cloud-platform',
  });
  const client = await auth.getClient();
  const projectId = await auth.getProjectId();
  const url = `https://dns.googleapis.com/dns/v1/projects/${projectId}`;
  const res = await client.request({url});
  console.log('DNS Info:');
  console.log(res.data);
}

main().catch(console.error);


text:
var config = require('./config');

// Express.js stuff
var express = require('express');
var app = require('express')();
var server = require('http').Server(app);

// Websockets with socket.io
var io = require('socket.io')(server);

console.log("Trying to start server with config:", config.serverip + ":" + config.serverport);

// Both port and ip are needed for the OpenShift, otherwise it tries
// to bind server on IP 0.0.0.0 (or something) and fails
server.listen(config.serverport, config.serverip, function() {
  console.log("Server running @ http://" + config.serverip + ":" + config.serverport);
});

// Allow some files to be server over HTTP
app.use(express.static(__dirname + '/'));

// Serve GET on http://domain/
app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

// Server GET on http://domain/api/config
// A hack to provide client the system config
app.get('/api/config', function(req, res) {
  res.send('var config = ' + JSON.stringify(config));
});

// And finally some websocket stuff
io.on('connection', function (socket) { // Incoming connections from clients
  // Greet the newcomer
  socket.emit('hello', { greeting: 'Hi socket ' + socket.id + ' this is Server speaking! Let\'s play ping-pong. You pass!' });

  socket.on('ping', function (data) { // ping-event from the client to be respond with pong
    console.log("received ping from client: ", data);
    socket.emit('pong', { id: data.id });
  });
});


text:
//------------------------------------------------------------------------------
// <auto-generated>This code was generated by LLBLGen Pro v5.9.</auto-generated>
//------------------------------------------------------------------------------
#nullable enable
using System;
using System.Collections.Generic;

namespace EFCore.Bencher.EntityClasses
{
	/// Class which represents the entity 'SalesPersonQuotaHistory'.
	public partial class SalesPersonQuotaHistory : CommonEntityBase
	{
		/// Method called from the constructor
		partial void OnCreated();

		/// Initializes a new instance of the <see cref="SalesPersonQuotaHistory"/> class.
		public SalesPersonQuotaHistory() : base()
		{
			OnCreated();
		}

		/// Gets or sets the ModifiedDate field.
		public System.DateTime ModifiedDate { get; set; }
		/// Gets or sets the QuotaDate field.
		public System.DateTime QuotaDate { get; set; }
		/// Gets or sets the Rowguid field.
		public System.Guid Rowguid { get; set; }
		/// Gets or sets the SalesPersonId field.
		public System.Int32 SalesPersonId { get; set; }
		/// Gets or sets the SalesQuota field.
		public System.Decimal SalesQuota { get; set; }
		/// Represents the navigator which is mapped onto the association 'SalesPersonQuotaHistory.SalesPerson - SalesPerson.SalesPersonQuotaHistories (m:1)'
		public virtual SalesPerson SalesPerson { get; set; } = null!;
	}
}


text:
#include <beryllium/vfs.h>
#include <string.h>
#include <log.h>
#include <lib/tree.h>
#include <stdlib.h>
#include <stdio.h>
#include <beryllium/driver.h>
#include <beryllium/device.h>
driver_t			 vfs_driver;
device_t            *vfs_device;
tree_t     			*vfs_tree 		= NULL;
struct vfs_entry 	*vfs_root 		= NULL;
vfs_node_t 			*vfs_root_node 	= NULL;

int vfs_start()
{
	vfs_tree = tree_create();

	vfs_root = malloc(sizeof(struct vfs_entry));
	vfs_root->name = strdup("[root]");
	vfs_root->file =  NULL;
	tree_set_root(vfs_tree, vfs_root);
	return 0;
}
void vfs_init()
{
	vfs_driver.start = &vfs_start;
	vfs_device = malloc(sizeof(device_t));
	vfs_device->name       = "vfs";
	vfs_device->type       = DEVICE_TYPE_INTERGRATED;
	vfs_device->flags      = 0;
	vfs_device->interface  = DEVICE_INTERFACE_KERNEL;
	vfs_device->driver     = &vfs_driver;
	device_start(vfs_device);
	device_manager_insert(vfs_device, device_search("kernel_ns"));
}

uint32_t read_vfs(vfs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer)
{
	if (node->read) {
		printf("read_vfs: node->read = 0x%X\n",node->read);
		uint32_t ret = node->read(node, offset, size, buffer);
		return ret;
	} else {
		return 0;
	}
}
uint32_t write_vfs(vfs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer)
{
	if (node->write) {
		uint32_t ret = node->write(node, offset, size, buffer);
		return ret;
	} else {
		return 0;
	}
}
void open_vfs(vfs_node_t *node, unsigned int flags)
{
	printf("open_vfs: node: 0x%X\n",node);
	if (node->open) {
		node->open(node, flags);
	}
}

void close_vfs(vfs_node_t *node)
{
	if(node == vfs_root_node)
	{
		klog(LOG_SEVERE,"VFS","Kernel just attempted to close the root filesystem. Disallowing...\n");
		return;
	}
	if (node->close) {
		node->close(node);
	}
}

struct dirent *readdir_vfs (vfs_node_t *node, uint32_t index)
{
	if ((node->type & VFS_DIRECTORY) && node->readdir)
	{
		struct dirent *ret = node->readdir(node, index);
		return ret;
	}
	else
	{
		return (struct dirent *)NULL;
	}
}

vfs_node_t *finddir_vfs(vfs_node_t *node, char *name)
{
	if ((node->type & VFS_DIRECTORY) && node->finddir)
	{
		vfs_node_t *ret = node->finddir(node, name);
		return ret;
	}
	else
	{
		return (vfs_node_t *)NULL;
	}
}

int create_file_vfs(char *name, uint16_t permission)
{
	vfs_node_t * parent;
	char *cwd = "/";
	char *path = canonicalize_path(cwd, name);

	char * parent_path = malloc(strlen(path) + 4);
	sprintf(parent_path, "%s/..", path);

	char * f_path = path + strlen(path) - 1;
	while (f_path > path) {
		if (*f_path == '/') {
			f_path += 1;
			break;
		}
		f_path--;
	}

	klog(LOG_WARN,"VFS","creating file %s within %s (hope these strings are good)\n", f_path, parent_path);

	parent = kopen(parent_path, 0);

	free(parent_path);
	if (!parent) {
		printf("No parent to file\n");
		//free(path);
		return -1;
	}

	if (parent->create) {

		parent->create(parent, f_path, permission);
	}
	else
	{
		printf("No create function for parent!\n");
	}
	free(path);
	free(parent);

	return 0;
}

/*
Credit Kevin Lange AGAIN for the path canonicalizer
*/
char *canonicalize_path(char *cwd, char *input) {
	/* This is a stack-based canonicalizer; we use a list as a stack */
	list_t *out = list_create();

	/*
	 * If we have a relative path, we need to canonicalize
	 * the working directory and insert it into the stack.
	 */
	if (strlen(input) && input[0] != PATH_SEPARATOR) {
		/* Make a copy of the working directory */
		char *path = malloc((strlen(cwd) + 1) * sizeof(char));
		memcpy(path, cwd, strlen(cwd) + 1);

		/* Setup tokenizer */
		char *pch;
		char *save;
		pch = strtok_r(path,PATH_SEPARATOR_STRING,&save);

		/* Start tokenizing */
		while (pch != NULL) {
			/* Make copies of the path elements */
			char *s = malloc(sizeof(char) * (strlen(pch) + 1));
			memcpy(s, pch, strlen(pch) + 1);
			/* And push them */
			list_insert(out, s);
			pch = strtok_r(NULL,PATH_SEPARATOR_STRING,&save);
		}
		free(path);
	}

	/* Similarly, we need to push the elements from the new path */
	char *path = malloc((strlen(input) + 1) * sizeof(char));
	memcpy(path, input, strlen(input) + 1);

	/* Initialize the tokenizer... */
	char *pch;
	char *save;
	pch = strtok_r(path,PATH_SEPARATOR_STRING,&save);

	/*
	 * Tokenize the path, this time, taking care to properly
	 * handle .. and . to represent up (stack pop) and current
	 * (do nothing)
	 */
	while (pch != NULL) {
		if (!strcmp(pch,PATH_UP)) {
			/*
			 * Path = ..
			 * Pop the stack to move up a directory
			 */
			list_node_t * n = list_pop(out);
			if (n) {
				free(n->value);
				free(n);
			}
		} else if (!strcmp(pch,PATH_DOT)) {
			/*
			 * Path = .
			 * Do nothing
			 */
		} else {
			/*
			 * Regular path, push it
			 * XXX: Path elements should be checked for existence!
			 */
			char * s = malloc(sizeof(char) * (strlen(pch) + 1));
			memcpy(s, pch, strlen(pch) + 1);
			list_insert(out, s);
		}
		pch = strtok_r(NULL, PATH_SEPARATOR_STRING, &save);
	}
	free(path);

	/* Calculate the size of the path string */
	size_t size = 0;
	foreach(item, out) {
		/* Helpful use of our foreach macro. */
		size += strlen(item->value) + 1;
	}

	/* join() the list */
	char *output = malloc(sizeof(char) * (size + 1));
	char *output_offset = output;
	if (size == 0) {
		/*
		 * If the path is empty, we take this to mean the root
		 * thus we synthesize a path of "/" to return.
		 */
		output = realloc(output, sizeof(char) * 2);
		output[0] = PATH_SEPARATOR;
		output[1] = '\0';
	} else {
		/* Otherwise, append each element together */
		foreach(item, out) {
			output_offset[0] = PATH_SEPARATOR;
			output_offset++;
			memcpy(output_offset, item->value, strlen(item->value) + 1);
			output_offset += strlen(item->value);
		}
	}

	/* Clean up the various things we used to get here */
	list_destroy(out);
	list_free(out);
	free(out);

	/* And return a working, absolute path */
	return output;
}

#include <stdio.h>
void vfs_print_node(vfs_node_t *node)
{
	klog(LOG_DEBUG,"VFS","Reading vfs node '%s' at 0x%X\n",node->name,node);
	klog(LOG_DEBUG,"VFS","Type: ");
	if(node->type & VFS_FILE)
	{
		printf("file ");
	}
	if(node->type & VFS_DIRECTORY)
	{
		printf("directory ");
	}
	if(node->type & VFS_CHARDEVICE)
	{
		printf("chardev ");
	}
	if(node->type & VFS_BLOCKDEVICE)
	{
		printf("blockdev ");
	}
	if(node->type & VFS_PIPE)
	{
		printf("pipe ");
	}
	if(node->type & VFS_SYMLINK)
	{
		printf("symlink ");
	}
	if(node->type & VFS_MOUNTPOINT)
	{
		printf("mountpoint");
	}
	printf("\n");
	klog(LOG_DEBUG,"VFS","perm: ");
	if(node->permissions & VFS_PERMISSION_READ)
	{
		printf("r");
	}
	if(node->permissions & VFS_PERMISSION_WRITE)
	{
		printf("w");
	}
	if(node->permissions & VFS_PERMISSION_EXECUTE)
	{
		printf("x");
	}
	printf("\n");
	klog(LOG_DEBUG,"VFS","uid:%d, gid:%d\n",node->uid,node->gid);
	klog(LOG_DEBUG,"VFS","inode:%d\n",node->inode);
	klog(LOG_DEBUG,"VFS","size:%d bytes\n",node->length);
	klog(LOG_DEBUG,"VFS","From device:");
	if(node->device & VFS_DEVICE_VFS)
	{
		printf("vfs\n");
	}
	else
	{
		printf("unkn\n");
	}
	printf("\n");
}
void vfs_print_tree_node(tree_node_t * node, size_t height)
{
	/* End recursion on a blank entry */
	if (!node) return;
	/* Indent output */
	for (uint32_t i = 0; i < height; ++i) { printf(" "); }
	/* Get the current process */
	struct vfs_entry * fnode = (struct vfs_entry *)node->value;
	/* Print the process name */
	if (fnode->file) {
		printf("%s -> 0x%x (%s)", fnode->name, fnode->file, fnode->file->name);
	} else {
		printf("%s -> (empty)", fnode->name);
	}
	/* Linefeed */
	printf("\n");
	foreach(child, node->children) {
		/* Recursively print the children */
		vfs_print_tree_node(child->value, height + 4);
	}
}
int vfs_mount(char * path, vfs_node_t * local_root) {
	if (!vfs_tree) {
		klog(LOG_SEVERE,"VFS", "VFS hasn't been initialized, you can't mount things yet!\n");
		return 1;
	}
	if (!path || path[0] != '/') {
		klog(LOG_ERROR,"VFS", "Path must be absolute for mountpoint.\n");
		return 2;
	}
	int ret_val = 0;

	char * p = strdup(path);
	char * i = p;

	int path_len   = strlen(p);

	/* Chop the path up */
	while (i < p + path_len) {
		if (*i == PATH_SEPARATOR) {
			*i = '\0';
		}
		i++;
	}
	/* Clean up */
	p[path_len] = '\0';
	i = p + 1;

	/* Root */
	tree_node_t * root_node = vfs_tree->root;

	if (*i == '\0') {
		/* Special case, we're trying to set the root node */
		struct vfs_entry * root = (struct vfs_entry *)root_node->value;
		if (root->file) {
			klog(LOG_WARN,"VFS", "Path %s already mounted, unmount before trying to mount something else.\n", path);
			ret_val = 3;
			goto _vfs_cleanup;
		}
		root->file = local_root;
		/* We also keep a legacy shortcut around for that */
		vfs_root_node = local_root;
	} else {

		tree_node_t * node = root_node;
		char * at = i;
		while (1) {
			if (at >= p + path_len) {
				break;
			}
			int found = 0;
			//klog(LOG_INFO,"VFS", "Searching for %s\n", at);
			foreach(child, node->children) {
				tree_node_t * tchild = (tree_node_t *)child->value;
				struct vfs_entry * ent = (struct vfs_entry *)tchild->value;
				if (!strcmp(ent->name, at)) {
					found = 1;
					node = tchild;
					break;
				}
			}
			if (!found) {
				//klog(LOG_INFO,"VFS", "Did not find %s, making it.\n", at);
				struct vfs_entry * ent = malloc(sizeof(struct vfs_entry));
				ent->name = strdup(at);
				ent->file = NULL;
				node = tree_node_insert_child(vfs_tree, node, ent);
			}
			at = at + strlen(at) + 1;
		}
		struct vfs_entry * ent = (struct vfs_entry *)node->value;
		if (ent->file) {
			klog(LOG_WARN,"VFS", "Path %s already mounted, unmount before trying to mount something else.\n", path);
			ret_val = 3;
			goto _vfs_cleanup;
		}
		ent->file = local_root;
		//vfs_print_node(local_root);
	}

_vfs_cleanup:
	free(p);
	return ret_val;
}

vfs_node_t *get_mount_point(char * path, unsigned int path_depth, char **outpath, unsigned int * outdepth) {
	size_t depth;

	for (depth = 0; depth <= path_depth; ++depth) {
		path += strlen(path) + 1;
	}

	/* Last available node */
	vfs_node_t   * last = vfs_root_node;
	tree_node_t * node = vfs_tree->root;

	char * at = *outpath;
	int _depth = 1;
	int _tree_depth = 0;

	while (1) {
		if (at >= path) {
			break;
		}
		int found = 0;
		klog(LOG_INFO,"VFS","Searching for %s\n", at);
		foreach(child, node->children) {
			tree_node_t * tchild = (tree_node_t *)child->value;
			struct vfs_entry * ent = (struct vfs_entry *)tchild->value;
			if (!strcmp(ent->name, at)) {
				found = 1;
				node = tchild;
				at = at + strlen(at) + 1;
				if (ent->file) {
					_tree_depth = _depth;
					last = ent->file;
					*outpath = at;
				}
				break;
			}
		}
		if (!found) {
			break;
		}
		_depth++;
	}

	*outdepth = _tree_depth;

	if (last) {
		vfs_node_t * last_clone = malloc(sizeof(vfs_node_t));
		memcpy(last_clone, last, sizeof(vfs_node_t));
		return last_clone;
	}
	return last;
}

vfs_node_t *kopen(char *filename, uint32_t flags) {
	/* Simple sanity checks that we actually have a file system */
	if (!vfs_tree->root || !filename) {
		printf("vfs_tree->root or filename = NULL!\n");
		return NULL;
	}

	klog(LOG_INFO,"VFS", "kopen(%s)\n", filename);

	/* Reference the current working directory */
	char *cwd = "/";
	/* Canonicalize the (potentially relative) path... */
	char *path = canonicalize_path(cwd, filename);
	/* And store the length once to save recalculations */
	size_t path_len = strlen(path);

	/* If strlen(path) == 1, then path = "/"; return root */
	if (path_len == 1) {
		/* Clone the root file system node */
		vfs_node_t *root_clone = malloc(sizeof(vfs_node_t));
		memcpy(root_clone, vfs_root_node, sizeof(vfs_node_t));

		/* Free the path */
		free(path);

		/* And return the clone */
		return root_clone;
	}

	/* Otherwise, we need to break the path up and start searching */
	char *path_offset = path;
	uint32_t path_depth = 0;
	while (path_offset < path + path_len) {
		/* Find each PATH_SEPARATOR */
		if (*path_offset == PATH_SEPARATOR) {
			*path_offset = '\0';
			path_depth++;
		}
		path_offset++;
	}
	/* Clean up */
	path[path_len] = '\0';
	path_offset = path + 1;

	/*
	 * At this point, the path is tokenized and path_offset points
	 * to the first token (directory) and path_depth is the number
	 * of directories in the path
	 */

	/*
	 * Dig through the (real) tree to find the file
	 */
	unsigned int depth = 0;
	vfs_node_t *node_ptr = malloc(sizeof(vfs_node_t));
	/* Find the mountpoint for this file */
	vfs_node_t *mount_point = get_mount_point(path, path_depth, &path_offset, &depth);

	if (path_offset >= path+path_len) {
		free(path);
		return mount_point;
	}
	/* Set the active directory to the mountpoint */
	memcpy(node_ptr, mount_point, sizeof(vfs_node_t));
	vfs_node_t *node_next = NULL;
	for (; depth < path_depth; ++depth) {
		/* Search the active directory for the requested directory */
		klog(LOG_INFO,"VFS","... Searching for %s\n", path_offset);
		node_next = finddir_vfs(node_ptr, path_offset);
		free(node_ptr);
		node_ptr = node_next;
		if (!node_ptr) {
			/* We failed to find the requested directory */
			free((void *)path);
			return NULL;
		} else if (depth == path_depth - 1) {
			/* We found the file and are done, open the node */
			open_vfs(node_ptr, flags);
			free((void *)path);
			return node_ptr;
		}
		/* We are still searching... */
		path_offset += strlen(path_offset) + 1;
	}
	klog(LOG_INFO,"VFS","- Not found.");
	/* We failed to find the requested file, but our loop terminated. */
	free((void *)path);
	return NULL;
}


text:
/**
 * Looks for potential hot spot string comparisons
 * @author Adam Baldwin
 */

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

var keywords = '((' + [
    'password',
    'secret',
    'api',
    'token',
    'auth',
    'pass',
    'hash'
].join(')|(') + '))';

var re = new RegExp('^' + keywords + '$', 'im');

function containsKeyword (node) {
    if (node.type === 'Identifier') {
        if (re.test(node.name))
            return true;
        }
        return
}

module.exports = function(context) {

    "use strict";

    return {
        "IfStatement": function(node) {
            if (node.test && node.test.type === 'BinaryExpression') {
                if (node.test.operator === '==' || node.test.operator === '===' || node.test.operator === '!=' || node.test.operator === '!==') {

                    if (node.test.left) {
                    var left = containsKeyword(node.test.left);
                        if (left) {
                            return context.report(node, "Potential timing attack, left side: " + left);
                        }
                    }

                    if (node.test.right) {
                    var right = containsKeyword(node.test.right);
                        if (right) {
                            return context.report(node, "Potential timing attack, right side: " + right);
                        }
                    }
                }
            }
        }
    };

};