• Akka is a Scala-based platform that provides simpler scalability, fault-tolerance, concurrency, and remoting through the actor model and software transactional memory.

  • Apache James Server is a modular e-mail server platform that integrates SMTP, POP3, IMAP, and NNTP.

  • Apache Spark is a fast and general purpose cluster compute framework, commonly used for "Big Data" applications.

  • Apache Tajo is a distributed, fault-tolerance, low-latency, and high throughput SQL engine that provides ETL features and ad-hoc query processing on large-scale data sets.

  • Arquillian is an innovative in-container testing platform for the JVM

  • Async HTTP Client is a simple-to-use library that allows you to execute HTTP requests and process the HTTP responses asynchronously.

  • BungeeCord is the de facto proxy solution for combining multiple Minecraft servers into a cloud / hub system.

  • Couchbase is a distributed NoSQL document-oriented database that is optimized for interactive applications.

  • Cluster - Service Fabric I/O Service Fabric Cluster provides a fault-tolerant decentralized peer-to-peer based cluster membership service with no single point of failure or single point of bottleneck. It does this using gossip protocols and an automatic failure detector.

  • Elastic Search is a distributed RESTful search engine built on top of Lucene.

  • Eucalyptus is a software infrastructure for implementing on-premise cloud computing using an organization's own IT infrastructure, without modification, special-purpose hardware or reconfiguration.

  • Finagle is an extensible RPC system for the JVM, used to construct high-concurrency servers.

  • Forest is a general purpose friend-to-friend platform.

  • Gatling is an asynchronous and efficient stress tool developed with Netty and Akka.

  • Hammersmith is a pure asynchronous MongoDB driver for Scala

  • Higgs is a high performance, message oriented network library.

  • Holmes is a Java application that implements DLNA/UPnP protocol for playing videos, music, pictures and podcasts (RSS) to compatible devices.

  • HornetQ is a project to build a multi-protocol, embeddable, very high performance, clustered, asynchronous messaging system.

  • http-client is a high performance and throughput oriented HTTP client library.

  • Infinispan is an extremely scalable, highly avaiable data grid platform.

  • jaC64 is a C64 emulator with multiplayer support.

  • JBossWS is a feature-rich JAX-WS compatible web service stack.

  • Jetserver is a fast multiplayer java game server written using JBoss Netty and Mike Rettig's Jetlang. It supports TCP and UDP transmission and Flash AMF3 protocol.

  • JXTA is a set of open protocols that enable any connected device on the network, ranging from cell phones and wireless PDAs to PCs and servers, to communicate and collaborate in a P2P manner.

  • LittleProxy is a high-performance HTTP proxy.

  • LittleShoot is an open source P2P technology for publishing, searching, and downloading files based on open protocols and open standards.

  • MessagePack is a binary-based efficient object serialization library that enables to exchange structured objects between many languages.

  • Mobicents Media Server is a media gateway server that processes the audio and/or video streams associated with telephone calls or VoIP connections.

  • Mobicents SIP Servlets is an open source certified SIP Servlet implementation.

  • Moquette MQTT broker Simple MQTT broker that uses Netty for protocol codec.

  • Naggati "it's (DEPRECATED) now" is a protocol builder for Netty, written in Scala.

  • Netflow.io is a Scala/Netty Netflow Collector used at wasted.io

  • Netty Tools is a small collection of tools useful when working with Netty, which includes various HTTP clients and servers, bandwidth meter, and Thrift RPC processor.

  • Netty-ICAP Codec is a high performance full RFC3507 compliant ICAP codec implementation. This protocol is mostly used in proxy environments in order to offload work to external servers.

  • Netty-Livereload is the Livereload protocol implementation on Netty WebSocket implementation.

  • Netty-SocketIO is a Socket.IO server written on top of Netty

  • Netty-ZMTP is a collection of Netty channel handlers that aims to implement ZMTP/1.0, the ZeroMQ Message Transport Protocol.

  • Socket-IO - Service Fabric I/O Ultra Fast Socket.IO server based on Netty.

  • Nifty is a Netty-based Thrift transport implementation.

  • NIOSMTP is an asynchronous SMTP client implementation.

  • OpenTSDB is a distributed, scalable, Time Series Database written on top of HBase to store, index, and serve the metrics collected from computer systems.

  • Peregrine is a map reduce framework designed for running iterative jobs across partitions of data. Peregrine is designed to be FAST for executing map reduce jobs by supporting a number of optimizations and features not present in other map reduce frameworks.

  • Play Framework is a clean alternative web application framework to J2EE stack, which focuses on developer productivity and targets RESTful architecture.

  • PS3 Media Server is a DLNA compliant UPNP Media Server for PS3 which transcodes and streams any kind of media files.

  • Protobuf-RPC-Pro is a Java implementation for Google's Protocol Buffer RPC services.

  • Pushy is a Java library for sending APNs (iOS/OS X) push notifications.

  • Ratpack is a simple, capable, toolkit for creating high performance web applications.

  • Redisson provides a distributed and scalable Java data structures (Set, SortedSet, Map, ConcurrentMap, List, Queue, Deque, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog) on top of Redis server.

  • RESTExpress is a lightweight, fast, micro-framework for building stand-alone REST services in Java. It supports JSON and XML serialization automagically as well as ISO 8601 date formats.

  • RHQ collectd decoder decodes collectd UDP datagrams.

  • Spigot is a high performance Minecraft server based on CraftBukkit designed to provide the highest possible performance and reliability. It uses Netty for its custom network stack.

  • Spinach is a scalable thread-safe Disque client providing both synchronous and asynchronous connections.

  • Teiid is a data virtualization system that allows applications to use data from multiple, heterogenous data stores.

  • Torrent4J is a BitTorrent library implemented in pure Java.

  • TomP2P is an extended DHT (distributed hash table) which stores values for a location key in a sorted table.

  • Unfiltered is a toolkit for servicing HTTP requests in Scala that provides a consistent vocabulary for handing requests on various server backends.

  • Vert.x is an effortless asynchronous application development for the modern web and enterprise

  • WaarpFtp is an FTP Server based on Netty

  • Webbit is an event-based WebSocket and HTTP server.

  • Xitrum is an async and clustered Scala web framework and HTTP(S) server on top of Netty and Hazelcast.

  • zooterrain is a small self-containing web server app which pushes all ZooKeeper znodes and their changes to the browser (using WebSocket).



C++


일반 멤버변수 초기화

- C++ 같은 경우는 멤버변수를 선언과 동시에 초기화를 못시키기때문에 (수정: C++11 부터는 가능) 생성자에서 초기화하며 ,
  생성자 내부 말고 ,생성자 초기화리스트에서 생성하는  효율적인 이디엄이있으며, 

- 자바의 경우 멤버번수를 자동 초기화 해주지만 C/C++ 은 그러지 않기때문에  초기화 과정이 필요함.


class A {
    B b = new B();  <-- 에러이다.
}

- 초기화 리스트를 사용하지 않은 경우.

class A
{
      int x;
      int y;
public:
      Point(int a, int b)
      {
            x = a;
            y = b;
      }
};

 - 초기화 리스트를 사용한 경우.

class A
{
      int x;
      int y;
public:
      Point(int a, int b) : x(a), y(b)
      {
      }
};

이 경우는  int x = a; 와 같이 바로 초기화 된다.


const 멤버변수 

const int a = 20;          //에러 발생 

const int i;                   //에러 발생
    

const 는 바로 초기화 해야한다.  이때 멤버변수라 문제가 생기는데 이때 초기화 리스트를 사용할수 있다.
초기화 리스트에서 초기화 안하면 에러발생한다.

#pragma once
class test
{
const  int n;

public:
test(void);
~test(void);

};

test::test(void):n(0)
{
}

정적 멤버변수 

static  int s;                       // ok

static  int s = 10;                //에러 발생 

const static  int s = 10;       //ok



//////////////////////   test.h /////////////////////

#pragma once
class test
{
const  int n;
static int s;
const static  int cs;

public:
test(void);
~test(void);

};


//////////////////////   test.cpp /////////////////////

#include "test.h"

const int test::cs = 10;       // 이렇게 초기화도 가능하다.
int test::s = 10;

test::test(void):n(0)
{
}




자바
 


- 자바같은경우는 ,멤버변수(인스턴스) 변수를  생성자 뿐만 아니라 선언하면서 바로 대입가능.
- 자바 경우는 멤버변수는 자동 초기화 , 지역변수는 자동초기화 안됨. 
- 자바의 경우 

Example 1:

class A {
    B b = new B();  <-- 정상
}

Example 2:

class A {
    B b;

    A() {
         b = new B();  <-- 정상  
    }
}

Exampe 1 과 Example2 방식의  차이점 정리  (선언하자마자 대입 vs 나중에 대입) 


  • 둘간의 근본적인 차이는 없다. (둘다 컴파일시 생성자에서 초기화 된다)
  • 첫번째 방법이 좀 더 읽기 쉽다.
  • 첫번째 방법으로는 예외처리가 쉽지 않다. ( 선언 아래에 {} 를 추가하여 할수있다)
  • 첫번째 방법은 너무 이른 할당을 하게 한다.
  • 두번째 방법은 생성자가 여러개일때 이곳 저곳에 해야한다. 까먹을수도.. (init() 함수이용)
  • 첫번째 방법으로는  DI 를 '쉽게' 하기 어렵다. 
  • 상황에 맞춰서 쓰도록~


'Java' 카테고리의 다른 글

자바8 Streams API 를 다룰때 실수하기 쉬운것 10가지  (0) 2016.05.22
자바로 MS 문서 다루기  (0) 2015.11.05
자바 EnumBitSet 사용하기  (0) 2015.09.01
자바 enum 정리  (0) 2015.09.01
자바 volatile / C volatile 정리  (0) 2015.09.01


Putty 로 서버에 SSH 로 접속해서 java 와 python 으로 되있는 여러가지 프로세스를 띄운후에 

집에 가보면 작동이 안되는 문제가 발생했는데 알고보니 SSH 세션이 끊기면 프로세스도 같이 죽음


예를 들어 a.jar 라는 프로그램을 java -jar a.jar & 로 putty 로 접속해서 실행후 putty 창을 닫은후 

다시 접속해서 ps -ef | grep java 해보면 죽어있는데 이것은 테스트해본결과

stdout 과 관련있는거 같다. 로깅 출력으로 파일과 stdout 으로 한 프로그램은 죽었고, 

stdout 을 파일로 리다이렉트 해놓은 프로그램은 안죽더라~


아무튼 해결책은 여러가지가 있는데


첫째, stdout 을 file 로 리다이렉트 시켜라.   

둘째. nohup 을 사용해서 띄워라.


nohup java -jar trams.jar & 


세째. screen 이라는것을 사용하라. 아래 링크참조


http://kevinx64.net/337

http://www.bangmoney.org/posts/2004-03-24-screen.html

  


http://iloveulhj.github.io/posts/http/http-digest-auth.html 펌



[HTTP] 다이제스트 인증

이 포스트는 “HTTP 완벽가이드”의 “13장, 다이제스트 인증”을 정리한 내용입니다.


  • 기본 인증은 편리하고 유연하지만 안전하지 못함
  • 다이제스트 인증은 기본 인증과 호환되는 대체재로서 개발
  • 널리 쓰이지는 않지만 개념은 보안트랜잭션의 구현에 유용함

다이제스트 인증의 개선점

특징

  • 비밀번호를 네트워크를 통해 평문으로 전송하지 않음
  • 인증 체결을 가로채서 재현하지 못함
  • 구현 방법에 따라 메시지 내용 위조 방지 가능

단방향 다이제스트

  • 다이제스트(요약)는 단방향 함수로 동작, 무한 가지의 모든 입력값을 유한의 범위로 압축 변환
  • MD5(메시지 다이제스트 #5), SHA(Secure Hash Algorithm)…
  • 요약함수는 보통 cryptographic checksums로 불림, 단반향 해시 함수이거나 fingerprint function임

재전송 방지를 위한 난스 사용

  • 난스(nonce)라 불리는 자주 바뀌는 증표를 발급
  • 다이제스트를 탈취하여 서버로 전송하는 해킹을 막기위한 방법
  • 다이제스트는 특정 난스 값에 대해서만 유효

다이제스트 인증 핸드쉐이크

그림1. 다이제스트 인증 핸드셰이크
자료 출처: David Gourley and Brian Totty, "HTTP: The Definitive Guide (Definitive Guides)", O'Reilly, 2002

  1. 서버는 난스값을 계산
  2. 난스를 WWW-Authenticate 인증요구 메시지에 담아, 서버가 지원하는 알고리즘 목록과 함께 클라이언트에 전송
  3. 클라이언트는 알고리즘 선택, 비밀번호와 그 외 데이터에 대한 요약 계산
  4. 클라이언트는 Authorization 메시지에 요약을 담아 서버로 전송, 서버를 인증하려면 클라이언트를 난수를 보낼 수 있음
  5. 서버는 요약, 알고리즘, 그외 보조데이터를 받아 요약을 검증함. 클라이언트가 서버에게 인증을 요구했다면 클라이언트 요약이 만들어 클라이언트에 전송. 다음번 난스를 클라이언트에게 미리 전송하기도 함

요약(digest) 계산

다이제스트 인증이 핵심은 공개된 정보, 비밀 정보, 시한부 난스 값을 조합한 단방한 요약

다이제스트 알고리즘의 입력 값

H(d)단방향 해시함수
KD(s,d)요약함수. s는 secret, d는 data를 의미
A1비밀번호 등 보안 정보를 담고 있는 데이터 덩어리
A2요청 메시지의 비밀이 아닌 속성을 담고 있는 데이터 덩어리

H(d)와 KD(s,d) 알고리즘

  • RFC2617에서 제안된 알고리즘은 MD5, MD5-sess(‘sess’는 세션을 의미)
  • 만약 알고리즘이 정해지지 않았다면 MD5가 기본
  • KD 요약 함수는 콜론으로 연결된 비밀 데이터와 일반데이터의 MD5를 계산

    H(<데이터>) = MD5(<데이터>)  
    KD(<비밀>,<데이터>) = H(연결(<비밀>:<데이터>)
    

보안 관련 데이터(A1)

  • 사용자 이름, 비밀번호, 보호 영역, 난스와 같은 비밀 보호 정보로 이루어짐

    MD5: A1 = <사용자>:<영역>:<비밀번호>
    MD5-sess: A1 = MD5(<사용자>:<영역>:<비밀번호>):<난스>:<c난스>
    

메시지 관련 데이터(A2)

  • URL, 요청 메서드, 메시지 엔티티 본문과 같은 메시지 자체의 정보
  • qop(quality of protection)에 따라 A2의 두가지 사용법이 있음

    정의되지 않음:  <요청메서드>:<uri 지시자 값>
    auth:  <요청메서드>:<uri 지시자 값>
    auth-int:  <요청메서드>:<uri 지시자 값>
    

보호수준(qop) 향상

  • qop 필드는 WWW-Authenticate, Authorization, Authentication-Info에 모두 존재 가능
  • qop 필드는 클라이언트와 서버가 어떤 보호 기법을 어느 정도 수준으로 사용할 수 있지 협상할 수 있게 허용

메시지 무결성 보호

  • qop=”auth-int”면 메시지 무결성 보호가 적용
  • auth-int의 경우 계산되는 H(엔티티 본문)은 메시지 본문의 해시가 아닌 엔티티 본문의 해시

실제 상황에 대한 고려

다중 인증 요구

  • 서버는 클라이언트에게 가능한 가능한 인증 요구를 보냄

오류 처리

  • 다이제스트 인증에서, 지시자나 그 값이 적절하지 않거나 요구된 지시자가 빠진 경우 400 Bad Request가 절절한 응답임
  • 인증서버는 반드시 uri 지시자가 가리키는 리소스가 요청줄에 명시된 리소스와 같음을 확인해야함
    다를 경우 이는 공격의 징후일 수 있으므로 로그를 남기는 것이 좋음

보안에 대한 고려사항

  • 헤더 부당 변경
  • 재전송 공격
  • 다중 인증 메커니즘
  • 사전(dictionary) 공격
  • 악의적인 프락시와 중간자 공격
  • 선택 평문 공격
  • 비밀번호 저장

다이제스트 인증 기능의 구현을 위한 지원 데이터

WWW-Authenticate 지시자들

realm사용자 이름과 비밀번호가 어디 사용될 것인지 알려주기 위해 사용자에게 보여질 문자열
nonce401 응답이 만들어질 때마다 유일하게 생성되어야 하는 서버에 특화된 데이터 문자열
domain보호될 공간을 정의한 따옴표로 감싸진 URI들의 공백으로 분리된 목록
opaque서버에 의해 정의된 데이터의 문자열, 클라이언트는 같은 보호 공간의 URI에 대한 다음번 요청에서 Authorizaiton 허더에 이 값을 담아 반환
stable클라이언트로부터의 이전 요청이 nonce 값이 신선하지 않아서 거부되었음을 의미하는 플래그
algorithm다이제스트와 체크섬을 생성할 때 사용하는 알고리즘, 기본 값은 MD5
qop선택적, 서버가 지원하는 보호 수준을 의미

Authorization 지시자들

username특정 realm에서의 사용자 이름
realmWWW-Authenticte 헤더에 담겨 클라이언트에게 넘겨진 releam
nonceWWW- Authenticate 헤더에 담겨 클라이언트에게 넘겨진 nonce
uri요청 URI에서의 URI, 프락시에 의해 요청이 변경될 수 있기 때문에 존재
response다이제스트 값, 사용자가 비밀번호를 알고 있음을 증명
algorithm다이제스트와 체크섬을 생성할 때 사용하는 알고리즘, 기본 값은 MD5
opaque서버에 의해 정의된 데이터의 문자열, 같은 보호 공간의 URI에 대한 다음번 요청에서 값을 그대로 넣어서 반환
cnonceqop 지시자가 보내진 경우만 포함. 메시지 무결성 보호를 제공
qop클라이언트가 메세지에 적용한 “보호 수준”의 정도
ncqop 지시자가 보낸 경우에만 포함. 클라이언트가 이 요청의 nonce값과 함께 보낸 요청들의 횟수 합계

Authentication-Info 지시자들

nextnonce미래의 인증 응답 시에 클라이언트가 사용해주기를 서버가 원하는 nonce
qop서버에 의해 응답에 적용된 ‘보호 수준”의 정도
rspauthresponse auth를 의미. 선택적인 응답 다이제스트가 들어있으며 이를 이용해 상호 인증을 지원
cnonce응답 대상인 클라이언트의 요청에 들어있는 값과 반드시 같아야 함
nc응답 대상인 클라이언트 요청에 들어있는 값과 반드시 같아야 함

추가 정보


'보안' 카테고리의 다른 글

SSH 인사이드  (0) 2016.06.09
HTTP 기본인증 (Basic authentication)  (0) 2015.09.20
HTTP 세션을 이용한 인증  (0) 2015.06.04
HTTPS 설정 및 사설인증서 관련 글들  (0) 2015.06.04
자바와 보안을 알기위한 스터디  (0) 2015.04.27

http://iloveulhj.github.io/posts/http/http-basic-auth.html 펌 




[HTTP] 기본 인증

이 포스트는 “HTTP 완벽가이드”의 “12장, 기본 인증”을 정리한 내용입니다.


  • 수 많은 사람들이 웹을 통해 업무를 보거나 개인적인 데이터에 접근한다.
  • 웹 사이트에 리소스에는 소유자의 동의 없이 권한 없는 사용자가 접근할 수 없어야 한다.
  • 이를 위해서 서버는 사용자가 누구인지 식별할 수 있어야 한다. 서버는 사용자를 식별하여 작업이나 리소스에 접근할 권한을 결정한다.
  • 보통은 사용자 이름과 비밀번호를 입력해서 인증한다. HTTP는 자체적인 인증 관련 기능을 제공한다

인증 프로토콜과 헤더

  • HTTP는 필요에 따라 고쳐 쓸 수 있는 제어 헤더를 통해, 다른 인증 프로토콜에 맞추어 확장할 수 있는 프레임워크를 제공한다.
  • 아래 표에 나열된 헤더의 형식과 내용은 인증 프로토콜에 따라 달라진다.
  • 인증 프로토콜은 HTTP 인증 헤더에 기술되어 있다.
  • HTTP에는 “기본 인증” 과 “다이제스트 인증”이 있다.
  • 이 포스트에는 “기본 인증” 관해서만 다룬다.

네 가지 인증 단계
자료 출처: "HTTP 완벽가이드", 이응준, 정상일 옮김, 인사이트, 2014


기본 인증의 예

구체적으로 살펴보기 위해 다음 그림을 참고하자.
 기본 인증의 예
자료 출처: http://www.asp.net/web-api/overview/security/basic-authentication

  1. 서버가 사용자에게 인증요구를 보낼 때 
    서버는 401 Unauthorized 응답과 함께 WWW-Authenticate헤더를 기술해서 어디서 어떻게 인증할지 설명

  2. 다음으로 클라이언트가 서버로 인증 
    인코딩된 비밀번호와 그 외 인증 파라미터들을 Authorization 헤더에 담아서 요청

  3. 성공적으로 완료되면 정상적인 상태 코드를 반환한다. 추가적인 인증 알고리즘에 대한 정보를 Authentication-Info 헤더에 기술


보안 영역

  • 서버가 클라이언트로 인증 요구를 할 때, realm 지시자가 기술 되어 있는 WWW-Authenticate헤더를 전송
  • 웹 서버는 기밀문서를 보안 영역(realm) 그룹으로 나눈다. 보안 영역은 저마다 다른 사용자 권한을 요구

      HTTP/1.0 401 Unauthorized   
      WWW-Authenticate: Basic realm="Corporate Financials"
    
  • remalm은 위의 예시와 같이 해설 형식으로 돼어 사용자가 권한 범위를 이해하는데 도움이 되어야 한다.
  • "executive-committee@bigcompany.com"과 같은 서버의 호스트명을 넣는 것도 유용할 수 있다.

HTTP 기본 인증의 헤더

자료 출처: "HTTP 완벽가이드", 이응준, 정상일 옮김, 인사이트, 2014


기본 인증의 보안 결함

  • 기본 인증은 단순하고 편리하지만 안심할 수 없다. 기본 인증은 악의적이지 않은 누군가가 의도치 않게 리소스에 접근하는 것을 막는데 사용하거나, SSL 같은 암호 기술과 혼용한다.
  1. base-64인코딩된 값은 쉽게 디코딩할 수 있다. 사실상 ‘비밀번호 그대로’ 보내는 것과 다름없다.
  2. 제삼자는 사용자 이름과 비밀번호를 캡처하여 악용할 수 있다. 캡처한 정보를 통해 인증에 성공하고 서버에 접근할 수 있다.
  3. 사용자들의 행태에 비추어 매우 위험하다. 악의적으로 정보를 훔친 다음 금융 정보에 접근할 수 있다.
  4. 프락시나 중개자가 개입하는 경우 정상적인 동작을 보장하지 않는다.
  5. 기본 인증은 가짜 서버의 위장에 취약하다.

결론

기본 인증은 일반적인 환경에서 개인화나 접근을 제어하는데 편리하며, 다른 사람들이 보지 않기를 원하기는 하지만, 보더라도 치명적이지 않은 경우에는 여전히 유용하다. 기본 인증은 호기심 많은 사용자가 우연이나 사고로 정보에 접근해서 보는 것을 예방하는 데 사용한다.


출처: "HTTP 완벽가이드", 이응준, 정상일 옮김, 인사이트, 2014


'보안' 카테고리의 다른 글

SSH 인사이드  (0) 2016.06.09
HTTP 다이제스트 엑세스인증  (0) 2015.09.20
HTTP 세션을 이용한 인증  (0) 2015.06.04
HTTPS 설정 및 사설인증서 관련 글들  (0) 2015.06.04
자바와 보안을 알기위한 스터디  (0) 2015.04.27


C++ 의 map 은 레드블랙트리로 구현되있으며, java 의 treeMap 또한 레드블랙트리로 구현되어있습니다.

C++ 진영에서 해쉬테이블이 표준으로 구현되지 않았었기때문에,  많은 경우 해쉬를 굳이 외부라이브러리등

을 통하거나,만들어서 사용하지 않았는데, 그 의미는 많은 경우에 있어서 레드블랙트리로 맵을 사용하는게 충

분하다는 방증(circumstantial evidence) 이겠지요. Java 진영에서는 많은 경우 HashMap 을 사용하더군요.  

이런걸 보면 , 두개 알고리즘의 각각의 특징에 따라서 맵을 사용한다기보다는 , 대개의 프로그래머들은 그냥 

아무 생각없이 많이 쓰여 지는것을 쓴다고 볼수있습니다. 이 얘기는 프로그래머들이 게을러서라고 생각치 않

습니다. 많은 경우 두개의 알고리즘의 성능차이는 80대20법칙에서 중요치 않은 쪽에 속한다고 볼수있겠지

요. 어플리케이션 성능 체크를 해볼때, 병목이 일어나는 곳은 다른곳에 있었을 테니깐요.


그래도 우리는 소프트웨어 개발자이기때문에, 가끔 먼가 꺼림칙하기도 합니다. 따라서 여기에 

레드블랙트리의 장점을 간략히 기술해보면 


레드블랙트리의 장점 (해쉬에 비해)

- 순서가 있는 자료일 경우.  (해쉬는 순서가 없습니다) 

- 일관성있는 퍼먼스를 보여줍니다. (해쉬는 rehashing 될때 비정상적인 시간이걸릴수있음)

- 해쉬는 페이지폴트를 일으킬수있다. (페이지간 전환이 많아지면 느려지겠지요) 

- 연속된 삽입간에 지역성을 유지하기 쉽다. 더 적은 I/O 가 발생한다.( 해쉬테이블은 효율적인        lookup 을 위해 버켓안의 모든 요소를 스왑할수있다)

- 해쉬는 테이블 리사이징 이슈 : 갑자기 성능이 다운됨.

- 해쉬는 메모리 낭비가 있을수있다.( 이건 해쉬의 구현이 어떻게 되있냐에 따라 다름)

- 트리는 부정확한 검색에 사용될수있다.( "a" 로시작되는 모든것, 범위검색) 



자바를 사용해 개발한다면, 대부분의 경우 순서가 필요하면 TreeMap , 아니면 HashMap 을 쓰는게 좋다고 

생각합니다. Hash 가 java 7 에서 또 한번 큰 발전이 있었으며,(http://d2.naver.com/helloworld/831311

큰 차이가 없다면 가독성이라도 도움이 되니깐요. 아 이건 순서를 중요시했구나, 순서가 필요없구나~ 

물론 많은 데이터를 관리해야할 필요가 있을때는, 벤치마크가 필요하겠지요. 






I'll talk about the HashMap and TreeMap implementation in Java:

  • HashMap -- implement basic map interface

    1. implemented by an array of buckets, each bucket is a LinkedList of entries
    2. running time of basic operations: put(), average O(1), worst case O(n), happens when the table is resized; get(), remove(), average O(1)
    3. not synchronized, to synchronize it: Map m = Collections.synchronizedMap(new HashMap(...));
    4. Iteration order of the map is unpredictable.
  • TreeMap -- implement navigable map interface

    1. implemented by a red-black tree
    2. running time of basic operations: put(), get(), remove(), worst case O(lgn)
    3. not synchronized, to synchronize it: SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));
    4. provide ordered iteration. higherKey(), lowerKey() can be used to get the successor and predecessor of a given key.

To sum, the biggest difference between HashMap and TreeMap is that TreeMap implements NavigableMap<K,V>, which provide the feature of ordered iteration. Besides, both HashMap and TreeMap are members of Java Collection framework. You can investigate the source code of Javato know more about their implementations.


레드블랙트리는 이진트리이자, 균형을 갖춘트리입니다. C++ 의 map 이 레드블랙트리 기반이며, jemalloc 에서도 사용됩니다.레드블랙트리의 정의는 다음과 같습니다.

1. 모든 노드는 red나 black의 색깔을 갖는다.
2. Root 노드는 항상 black이다.
3. 모든 leaf 노드는 센티넬 노드(sentinel node)로서 black이다. (일단 항상 2개의 다른 값으로 채워질 수 있는 NIL=NULL 자식을 가진다.)
4. Red 노드의 자식은 모두 black이다. (Black의 자식은 black/red 모두 가능)
5. 루트(root)에서 leaf로의 경로를 생각할 때, 모든 경로에 대해서 black의 숫자는 같다. (이것을 black height라고 한다.)


삽입

삽입시에 이진트리와 마찬가지로 자신의 위치를 찾아가서 매달리게되는데, 그 이후에 레드블랙트리의  정의에 맞게끔 재구성이 시작됩니다.

부모가 조부모의 오른쪽 자식인지 왼쪽 자식인지에 따라 두가지의 경우로 나뉘는데 이 두 경우는 서로 정확히 대칭이므로 여기서는 부모가 조부모의 왼쪽 자식인경우 위주로 설명합니다. 레드블랙 트리 삽입을 이해하는데 매우 중요한 포인트 입니다. 대부분의 블로그 설명에서 이거 빼놓은듯 싶네요. 


노드 삽입를 위해서 먼저 binary search tree에 대한 노드 삽입 알고리즘대로 노드를 일단 추가한다. 당연히 새롭게 삽입된 노드는 기존의 센티넬 노드의 자리에 추가되어야 한다. 즉, 새 노드는 두 개의 센티넬 노드를 자식 노드로 갖고 기존 센티넬 노드 자리에 들어가게 된다. 새롭게 삽입된 노드의 색깔은 무조건 R 로 한다. (단, root 노드로 삽입시 B)

A. Root로 삽입

  1. void insert_case1(node n)
  2. {
  3.     if (n->parent == NULL)
  4.         n->color = BLACK;
  5.     else
  6.         insert_case2(n);
  7. }


N 이 root로 삽입되었다. 속성 2를 위해 B 로 설정한다.


B. 부모 P가 Black 인 경우

  1. void insert_case2(node n)
  2. {
  3.     if (n->parent->color == BLACK)
  4.         return; /* Tree is still valid */
  5.     else
  6.         insert_case3(n);
  7. }


삽입되는 노드는 red로 설정되기 때문에 속성 4를 만족하며 N이 red로 삽입되면서 2개의 black nil 자식을 가지기 때문에 각각의 leaf까지 black의 수는 똑같으므로 속성 5도 만족하며 아직 valid 한 RB 트리.

이 상황에서 다시 노드를 삽입하면...

1. 센티넬 노드 자리에 센티넬 노드를 자식으로 갖는 노드를 추가했기 때문에 속성 1, 2는 만족한다.
2. R로 했기 때문에 속성 3, 5를 만족한다.

위반할 수 있는 속성은 속성 4 밖에 없다. 즉, 다른 속성에 위반되지 않도록 하면서 속성 4 를 만족하도록 트리를 변경해 주면된다. 속성 4 를 위반하는 경우는 새로운 노드의 부모 노드가 R인 경우 밖에 없다. 이 때에 대한 처리 방법은 아래의 C, D의 2가지 경우로 나뉜다.

C. 부모가 R, 삼촌도 R

  1. void insert_case3(node n)     // 이미 부모는 R이 판명된 상태
  2. {
  3.     if (uncle(n) != NULL && uncle(n)->color == RED)
  4.     {
  5.         n->parent->color = BLACK;
  6.         uncle(n)->color = BLACK;
  7.         grandparent(n)->color = RED;
  8.  
  9.         insert_case1(grandparent(n));
  10.     }
  11.     else
  12.         insert_case4(n);
  13. }


부모가 R 이라면 할아버지는 반드시 B 여야 한다. (기존 트리가 RB트리 속성을 모두 만족하기 때문에 연속된 R을 갖을 수는 없다.) 부모와 삼촌이 모두 R 이라면 아래의 그림처럼 부모와 삼촌을 B로 바꾸고 할아버지를 R로 바꾼다. 이렇게 하면 모든 노드의 black height는 보전된다.

새롭게 생긴 R 노드, 즉 할아버지 노드에 대해서는 지금 적용한 삽입후 처리 알고리즘을 재귀적으로 적용할 수 있다. 할아버지 노드는 R 노드이고 B 를 자식으로 갖기 때문에 새롭개 삽입된 노드의 특징을 모두 지니기 때문에 같은 알고리즘이 적용될 수 있다. 만약 할아버지 노드가 루트 노드라면 할아버지 노드를 다시 B 로 칠하면 된다. 이 경우는 전체 트리의 black height가 1 증가하게 된다. (X의 black 자식으로 인해 height 1->2로 증가)

D. 부모가 R, 삼촌은 B

  1. // 삽입된 노드와 부모, 부모의 부모가 일련의 왼쪽 라인을 타도록...
  2. void insert_case4(node n)      
  3. {
  4.     if (== n->parent->right && n->parent == grandparent(n)->left)
  5.     {
  6.         rotate_left(n->parent);
  7.         n = n->left;
  8.     }
  9.     else if (== n->parent->left && n->parent == grandparent(n)->right)
  10.     {
  11.         rotate_right(n->parent);
  12.         n = n->right;
  13.     }
  14.     insert_case5(n);
  15. }
  16.  
  17. // 노드와 부모와 부모의 부모, 모두 같은 방향의 자식 관계라면... 색 반전하면서 회전
  18. void insert_case5(node n)
  19. {
  20.     n->parent->color = BLACK;
  21.     grandparent(n)->color = RED;
  22.  
  23.     if (== n->parent->left && n->parent == grandparent(n)->left)
  24.     {
  25.         rotate_right(grandparent(n));
  26.     }
  27.     else
  28.     {
  29.         /* Here, n == n->parent->right && n->parent == grandparent(n)->right */
  30.         rotate_left(grandparent(n));
  31.     }
  32. }



CASE D-1  (부모의 오른쪽 자식일때)

부모를 중심으로 왼쪽으로 회전한다. 여전히 레드블랙특성 4를 위반한다. CASE D-2 로 이동한다.


CASE D-2 (부모의 왼쪽 자식일때) 

조부를 중심으로 오른쪽으로 회전하고 부모와 조부의 색상을 맞바꾼다.


케이스 D 를 만나면 CASE D-2 의 수선을 마지막으로 상황이 종료된다.

케이스 C 를 만나면 상황이 끝날수도있고, 똑같은 상황이 다른노드에서 다시 시작될수도있다. 

재귀적으로 반복해서 루트까지 올라갈수도있다.


다시 한번 언급하지만  위의 CASE 들은 부모가 조부모의 왼쪽 자식을 기준으로 설명한것이다.

그 반대도 정확히 대칭이므로 반대로 생각하면 된다.

https://www.cs.usfca.edu/~galles/visualization/RedBlack.html 를 이용하여 시뮬레이션을 해보았다.

부모가 조부모의 왼쪽 자식인지 오른쪽 자식인지 염두해두고 살펴보자. 

                               100이 추가되며, 루트가 되면서 검정색이 되었다.

                             150이 빨강색 노드로 루트의 오른쪽에 여느 이진트리처럼 배치되었다.

                                 200이 추가된후에  좌회전되며 150이 루트가 되었다.

                               300 이 추가된후에 부모와 삼촌노드가 검정색으로 변경되었다. 

       180이 추가된후에 부모(175)와 삼촌(300) 가 검정이 되고 할아버지(200)이 빨강이 되었다.

다음 160번 노드 인서트되면서 대격변의 시작이다. 눈여겨 살펴보자.

160번 노드 삽입 


      삽입된 노드와 부모가 모두 빨강이라, 부모와 삼촌을 검정으로 바꾸고 할아버지를 빨강으로 바꿈 

할아버지 노드 = 그냥 삽입한 노드로 생각하고 다시 시작.  그 노드와 부모노드가 빨강이다. 

삼촌은 검정이다. 노드는 왼쪽자식이고 부모는 오른쪽 자식이다.  회전한다. 

                                                우회전 후 모습 


  노드와 부모가 모두 빨강, 노드는 오른쪽 자식이다. 부모는 오른쪽 자식이다. 회전을 통해 바로잡는다.


                                               좌화전후 모습 

                                          루트를 검정색으로 바꾸고, 정리한다.


레퍼런스:
http://www.yes24.com/24/goods/9345796?scode=032&OzSrank=3  https://en.wikipedia.org/wiki/Red%E2%80%93black_tree
http://egloos.zum.com/sweeper/v/900135
https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

Netty  라는 오픈소스를 살펴보다가 4.0 에 pool buffer 를 구현하는데 jemalloc 를 참고 했다는 언급이 있어

서 처음 알게되었습니다.  malloc  레벨에서 이러한 작업결과들이  있다는걸 이제서야 알게되었네요. 

jemalloc 함수는 Jason Evans라는 사람에 의해 만들어 졌습니다. (앞자를 따서 je).  일반적인 목적의 malloc 이


며, 2005년에 FreeBSD의  libc할당자로 채택되어졌습니다. 메모리단편화를 최소 화하는데 집중되었으며 멀티


프로세서/멀티쓰레드 시대에 맞게 병렬화 지원을 확장하였습니다. 이 메모리 할당자는 현재 나와있는 메모리 


할당자중 성능이 가장 좋다고 알려져 있습니다. 기본적인 malloc 함수에 비해 두 배가 넘는 성능을 보인다고 


합니다. jemalloc 에 관한 유명한 문서로  


https://www.facebook.com/notes/facebook-engineering/scalable-memory-allocation-using-jemalloc/480222803919 


가 있습니다. http://www.canonware.com/jemalloc/index.html  는 홈페이지이며 


논문은 http://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf  를 참고하시면 됩니다.


 buddy allocation와 slab allocation 는 jemalloc 를 이해하기위한 기반이론입니다.

+ Recent posts