#pragma once

#include "btree.h"

class FileInfoBTree
	: public BTreeBase
{
public:
	typedef int TraverseFileInfoCallback(const FileInfo* const file_info, void* const arg);

	struct Key
	{
		inline Key()
			: entry_index(kINVALID_INDEX)
		{
		}

		inline Key(const uint32_t entry_index)
			: entry_index(entry_index)
		{
		}

		uint32_t entry_index;
	};

	inline FileInfoBTree(const void* const table_data)
		: BTreeBase(table_data, key_comparsion_op(&key_less_than_op), key_comparsion_op(&key_equal_op))
	{
	}

	inline ~FileInfoBTree()
	{
	}

	inline bool search_by_index(const uint32_t index, FileInfo* file_info) const
	{
		const void* const data = BTreeBase::search(index);
		if (!data)
			return false;
		return file_info->parse(data) != nullptr;
	}

	inline const void* search(const uint32_t entry_index, uint32_t* const index = nullptr) const
	{
		return BTreeBase::search(&Key(entry_index), index);
	}

	inline void traverse(TraverseFileInfoCallback* const callback, void* const arg) const
	{
		TraverseCallbackArgs<TraverseFileInfoCallback> args(callback, arg);
		BTreeBase::traverse(traverse_callback, &args);
	}
	
protected:
	virtual const void* skip_node_data(const void* const node) const;

private:
	static int key_equal_op(const Key* const key, const void* const data);
	static int key_less_than_op(const Key* const key, const void* const data);

	static int traverse_callback(const void* const data, void* const arg);
};
