2009-02-07 37 views
13

Làm cách nào để lưu trữ bảng băm có chuỗi riêng biệt trong một tệp trên đĩa?Làm thế nào để lưu trữ một bảng băm trong một tập tin?

Tạo dữ liệu được lưu trữ trong bảng băm trong thời gian chạy là tốn kém, sẽ nhanh hơn khi tải HT từ đĩa ... nếu chỉ tôi có thể tìm ra cách thực hiện.

Chỉnh sửa: Tra cứu được thực hiện bằng HT được tải trong bộ nhớ. Tôi cần phải tìm một cách để lưu trữ hashtable (trong bộ nhớ) vào một tập tin trong một số định dạng nhị phân. Vì vậy, thời gian tới khi chương trình chạy nó chỉ có thể tải HT ra đĩa vào RAM.

Tôi đang sử dụng C++.

+0

Bạn có đang thực hiện tra cứu từ đĩa hoặc bạn chỉ cần duy trì hàm Hashtable không? – Hank

+0

Hank, Việc tra cứu được thực hiện với HT được tải trong bộ nhớ. Vâng, tôi chỉ cần tiếp tục duy trì được hashtable. – Girish

+0

vui lòng cung cấp thêm chi tiết - ngôn ngữ, hệ thống, v.v. –

Trả lời

6

Bạn đang sử dụng ngôn ngữ nào? Phương pháp phổ biến là làm một số thứ tự sắp xếp nhị phân.

Ok, tôi thấy bạn đã chỉnh sửa để thêm ngôn ngữ. Đối với C++ có một vài tùy chọn. Tôi tin rằng cơ chế serialization Boost là khá tốt. Ngoài ra, trang cho thư viện tuần tự hóa của Boost cũng mô tả các lựa chọn thay thế. Dưới đây là liên kết:

http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html

+0

> Bạn đang sử dụng ngôn ngữ nào? Tôi đang sử dụng C++. > Phương pháp phổ biến là thực hiện một số sắp xếp tuần tự nhị phân. Bạn có thể giải thích về điều này không? Tôi không biết về serialization nhị phân. Tôi muốn thêm rằng đây cũng là một bài tập học tập cho tôi vì vậy tôi muốn làm tất cả bằng tay. :) – Girish

5

Giả sử C/C++: Sử dụng chỉ số mảng và cấu trúc kích thước cố định thay vì con trỏ và phân bổ chiều dài thay đổi. Bạn sẽ có thể viết trực tiếp() các cấu trúc dữ liệu để tập tin cho sau này đọc() ing.

Đối với mọi thứ cấp cao hơn: Nhiều API ngôn ngữ cao hơn có cơ sở tuần tự hóa. Java và Qt/C++ đều có các phương thức chạy nhanh ngay lập tức, vì vậy tôi biết những người khác cũng làm như vậy.

2

Có lẽ DBM có thể được sử dụng cho bạn.

+0

Bạn đã kiểm tra giấy phép trên đó chưa? Hoặc là bạn làm cho mã nguồn mở ứng dụng của bạn, hoặc bạn trả lệ phí cấp giấy phép khá dốc của Sleepycat (cho bất kỳ ai nhưng một công ty rất lớn). –

5

Bạn chỉ có thể viết toàn bộ cấu trúc dữ liệu trực tiếp vào đĩa bằng cách sử dụng tuần tự hóa (ví dụ: in Java). Tuy nhiên, bạn có thể bị buộc phải đọc toàn bộ đối tượng vào bộ nhớ để truy cập vào các phần tử của nó. Nếu điều này là không thực tế, thì bạn có thể xem xét sử dụng tệp random access để lưu trữ các phần tử của bảng băm. Thay vì sử dụng một con trỏ để biểu diễn phần tử tiếp theo trong chuỗi, bạn sẽ chỉ sử dụng vị trí byte trong tệp.

+0

Zach, Tôi vẫn còn mới đối với tràn ngăn xếp, làm thế nào tôi có thể trả lời từng bài đăng? Có thể/mong muốn tạo một bài đăng để nó xuất hiện cùng với các bài đăng của người khác (câu trả lời) hay tôi chỉ nên trả lời từng bài đăng qua nhận xét ("thêm nhận xét")? – Girish

+0

@Girish: Chào mừng bạn đến với cộng đồng =) Nếu câu trả lời của bạn ngắn gọn và cụ thể cho bài đăng, thì chỉ cần thêm nhận xét. Các câu trả lời dài hơn có thể hữu ích cho người khác phải ở trong câu hỏi ban đầu (nhấp vào "chỉnh sửa"). Không bao giờ đăng câu trả lời hoặc thông tin bổ sung dưới dạng câu trả lời mới (vì đó không phải là câu trả lời). –

+0

OK, cảm ơn. Bằng tệp truy cập ngẫu nhiên, bạn có nghĩa là fseek() 'đang nhập tệp không? ... không chắc. – Girish

1

Nếu triển khai bảng băm của bạn là tốt, hãy lưu trữ giá trị băm và dữ liệu của từng đối tượng - đặt đối tượng vào bảng không nên tốn kém cho hàm băm và không nối tiếp bảng hoặc chuỗi trực tiếp cho phép bạn thay đổi thực hiện chính xác giữa lưu và tải.

3

Tắt con trỏ cho chỉ mục.

Điều này hơi giống với việc xây dựng một DAWG trên đĩa, mà tôi đã thực hiện một lúc. Điều làm cho nó rất ngọt ngào đến nỗi nó có thể được nạp trực tiếp bằng mmap thay vì đọc tập tin. Nếu hash-không gian là dễ quản lý, nói 2 hoặc 2 mục, sau đó tôi nghĩ rằng tôi sẽ làm điều gì đó như thế này:

  • Giữ một danh sách các chỉ số miễn phí. (nếu bảng trống, mỗi chỉ số chuỗi sẽ trỏ đến chỉ mục tiếp theo.)
  • Khi cần chuỗi cần sử dụng không gian trống trong bảng.
  • Nếu bạn cần phải đặt một cái gì đó trong một chỉ số đó là chiếm bởi một người ngồi xổm (tràn từ nơi khác):
    • kỷ lục chỉ số (chúng ta hãy gọi nó là N)
    • hoán đổi các yếu tố mới và người ngồi xổm
    • đặt các squatter trong một chỉ số miễn phí mới, (F).
    • theo chuỗi trên chỉ số băm của người ngồi xổm, để thay thế N với F.
  • Nếu bạn hoàn toàn chạy ra khỏi chỉ số miễn phí, bạn có thể cần một bảng lớn hơn, nhưng bạn có thể đối phó lâu hơn một chút bằng cách sử dụng mremap để tạo thêm phòng sau bàn.

Điều này sẽ cho phép bạn chèn và sử dụng trực tiếp bảng mà không sửa đổi. (nhanh chóng đáng sợ nếu trong bộ nhớ cache của hệ điều hành!) nhưng bạn phải làm việc với các chỉ mục thay vì con trỏ. Thật là ma quái khi có megabyte có sẵn trong syscall-round-time-time, và vẫn có nó chiếm ít hơn trong bộ nhớ vật lý, vì phân trang.

Các vấn đề liên quan