Tuesday, June 18, 2013

NIO - Buffer

Buffer

  • Dùng để chứa dữ liệu của một primitive type nhất định
  • Buffer là một trình tự tuyến tính, hưu hạn
  • Có 3 thuộc tính chinh:
    1. Capacity: đại diện cho số lượng các phần tử mà nó chứa. C => 0 và không đổi
    2. Limit: là chỉ số của phần tử đầu tiên không thể đọc hoặc ghi. 0<= L <= C
    3. poisition: là chỉ số của phần tử tiếp theo được đọc hoặc ghi. 0 <= P <= L <= C









Truyền dữ liệu.
Mỗi một subclass của Buffer class định nghĩa 2 loại của hoạt động put và get:
  • Relative: đọc và ghi một hoặc nhiều phần tử bắt đầu ở position hiện tại sau đó tăng position lên tương ứng số lượng các phần tử được truyền. Nếu yêu cầu truyền dữ liệu vượt quá limit thì relative get  sẽ ném ra một BufferUnderflowExeption và relative put ném ra một BufferOverflowExeption, trong cả hai trường hợp này không có dư liệu được truyền.
  • Absolute: nhận một chỉ số phần tử chính xác không ảnh hưởng đến position. Ném ra một IndexOutOfBoundsExeption nếu chỉ số truyền vào vượt quá limit.
Mark  và resetting

Mark là chỉ số mà tới đó buffer position sẽ bị reset khi hàm reset được gọi. Mark không phải lúc nào cũng được định nghĩa, 0 <= M <= P <= L <= C. Nếu mark được định nghĩa nó sẽ hủy bỏ nếu position hoặc limit được điều chỉnh tới một giá trị nhỏ hơn mark. Nếu mark không được định nghĩa thì khi gọi hàm reset sẽ gây ra InvalidMarkException.

Khi mới khỏi tạo buffer position = 0, mark = undefined, limit có thể bằng 0 hoặc giá trị bất kì dựa trên kiêu của buffer và cách mà nó được khởi tạo. Content của buffer là undefined

Các Subclass:


  • ByteBuffer
    • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer
Khởi tạo

Buffer được khởi tạo bởi 2 cách: sử dụng phương thức allocate hay allocateDirect, vốn nhận một tham số là một integer, ấn định capacity của Buffer. Điểm khác biện giữa 2 phương thức này là allocateDirect sẽ khởi tạo một buffer nằm bên ngoài heap của JVM, giúp bỏ bới thao tác copy dữ liệu giữa JVM buffer và OS buffer, kết quả là tăng tốc đáng kể tác vụ I/O. Tuy nhiên, việc này cũng có 1 tradeoff, đó là quy trình khởi tạo buffer sẽ tốn nhiều thời gian và công sức hơn. Tuy nhiên yếu điểm này cũng có thể giảm nếu sử dụng một vài practice đúng cách để tối ưu hóa.

Một số phương thức cơ bản

  • clear() làm cho buffer sẵn sàng cho một trình tự mới của channel-read hoặc relative put operation: nó thiết lập L = C, P = 0.
  • flip() làm cho buffer sẵn sàng cho một trình tự mới của channel-write hoặc relative get operation: nó thiết lập L = P, P = 0.
  • rewind() làm cho buffer sẵn sàng để đọc lại dữ liệu mà nõ đã có sẵn: không thay đổi limit, thiết lập P = 0.


Read-only buffers
Tất cả mọi buffer đều có thể đọc được, nhưng không phải tất cả có thể ghi. Các phương thức đột biến của từng lớp con được xác định như optional operations mà sẽ ném ra ReadOnlyBufferException khi được gọi trên một read-only buffer. Một read-only buffer không cho phép nội dung của nó bị sửa đổi, nhưng mark, postion, limit có thể thay đổi. Để xác định buffer read-only hay không sử dụng phương thức isReadOnly

No comments:

Post a Comment