diff options
author | David Barksdale <amatus@amat.us> | 2017-04-16 12:39:43 -0500 |
---|---|---|
committer | David Barksdale <amatus@amat.us> | 2017-04-16 12:42:34 -0500 |
commit | 4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch) | |
tree | a2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/gnunet-service-datastore.c | |
parent | cacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff) | |
download | gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip |
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore/gnunet-service-datastore.c')
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 194 |
1 files changed, 22 insertions, 172 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 277530843..d965ad8e0 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c | |||
@@ -733,41 +733,23 @@ check_data (const struct DataMessage *dm) | |||
733 | 733 | ||
734 | 734 | ||
735 | /** | 735 | /** |
736 | * Context for a PUT request used to see if the content is | ||
737 | * already present. | ||
738 | */ | ||
739 | struct PutContext | ||
740 | { | ||
741 | /** | ||
742 | * Client to notify on completion. | ||
743 | */ | ||
744 | struct GNUNET_SERVICE_Client *client; | ||
745 | |||
746 | #if ! HAVE_UNALIGNED_64_ACCESS | ||
747 | void *reserved; | ||
748 | #endif | ||
749 | |||
750 | /* followed by the 'struct DataMessage' */ | ||
751 | }; | ||
752 | |||
753 | |||
754 | /** | ||
755 | * Put continuation. | 736 | * Put continuation. |
756 | * | 737 | * |
757 | * @param cls closure | 738 | * @param cls closure |
758 | * @param key key for the item stored | 739 | * @param key key for the item stored |
759 | * @param size size of the item stored | 740 | * @param size size of the item stored |
760 | * @param status #GNUNET_OK or #GNUNET_SYSERROR | 741 | * @param status #GNUNET_OK if inserted, #GNUNET_NO if updated, |
742 | * or #GNUNET_SYSERROR if error | ||
761 | * @param msg error message on error | 743 | * @param msg error message on error |
762 | */ | 744 | */ |
763 | static void | 745 | static void |
764 | put_continuation (void *cls, | 746 | put_continuation (void *cls, |
765 | const struct GNUNET_HashCode *key, | 747 | const struct GNUNET_HashCode *key, |
766 | uint32_t size, | 748 | uint32_t size, |
767 | int status, | 749 | int status, |
768 | const char *msg) | 750 | const char *msg) |
769 | { | 751 | { |
770 | struct PutContext *pc = cls; | 752 | struct GNUNET_SERVICE_Client *client = cls; |
771 | 753 | ||
772 | if (GNUNET_OK == status) | 754 | if (GNUNET_OK == status) |
773 | { | 755 | { |
@@ -782,10 +764,9 @@ put_continuation (void *cls, | |||
782 | size, | 764 | size, |
783 | GNUNET_h2s (key)); | 765 | GNUNET_h2s (key)); |
784 | } | 766 | } |
785 | transmit_status (pc->client, | 767 | transmit_status (client, |
786 | status, | 768 | GNUNET_SYSERR == status ? GNUNET_SYSERR : GNUNET_OK, |
787 | msg); | 769 | msg); |
788 | GNUNET_free (pc); | ||
789 | if (quota - reserved - cache_size < payload) | 770 | if (quota - reserved - cache_size < payload) |
790 | { | 771 | { |
791 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 772 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -799,125 +780,6 @@ put_continuation (void *cls, | |||
799 | 780 | ||
800 | 781 | ||
801 | /** | 782 | /** |
802 | * Actually put the data message. | ||
803 | * | ||
804 | * @param pc put context | ||
805 | */ | ||
806 | static void | ||
807 | execute_put (struct PutContext *pc) | ||
808 | { | ||
809 | const struct DataMessage *dm; | ||
810 | |||
811 | dm = (const struct DataMessage *) &pc[1]; | ||
812 | plugin->api->put (plugin->api->cls, | ||
813 | &dm->key, | ||
814 | ntohl (dm->size), | ||
815 | &dm[1], | ||
816 | ntohl (dm->type), | ||
817 | ntohl (dm->priority), | ||
818 | ntohl (dm->anonymity), | ||
819 | ntohl (dm->replication), | ||
820 | GNUNET_TIME_absolute_ntoh (dm->expiration), | ||
821 | &put_continuation, | ||
822 | pc); | ||
823 | } | ||
824 | |||
825 | |||
826 | /** | ||
827 | * | ||
828 | * @param cls closure | ||
829 | * @param status #GNUNET_OK or #GNUNET_SYSERR | ||
830 | * @param msg error message on error | ||
831 | */ | ||
832 | static void | ||
833 | check_present_continuation (void *cls, | ||
834 | int status, | ||
835 | const char *msg) | ||
836 | { | ||
837 | struct GNUNET_SERVICE_Client *client = cls; | ||
838 | |||
839 | transmit_status (client, | ||
840 | GNUNET_NO, | ||
841 | NULL); | ||
842 | } | ||
843 | |||
844 | |||
845 | /** | ||
846 | * Function that will check if the given datastore entry | ||
847 | * matches the put and if none match executes the put. | ||
848 | * | ||
849 | * @param cls closure, pointer to the client (of type `struct PutContext`). | ||
850 | * @param key key for the content | ||
851 | * @param size number of bytes in data | ||
852 | * @param data content stored | ||
853 | * @param type type of the content | ||
854 | * @param priority priority of the content | ||
855 | * @param anonymity anonymity-level for the content | ||
856 | * @param replication replication-level for the content | ||
857 | * @param expiration expiration time for the content | ||
858 | * @param uid unique identifier for the datum; | ||
859 | * maybe 0 if no unique identifier is available | ||
860 | * @return #GNUNET_OK usually | ||
861 | * #GNUNET_NO to delete the item | ||
862 | */ | ||
863 | static int | ||
864 | check_present (void *cls, | ||
865 | const struct GNUNET_HashCode *key, | ||
866 | uint32_t size, | ||
867 | const void *data, | ||
868 | enum GNUNET_BLOCK_Type type, | ||
869 | uint32_t priority, | ||
870 | uint32_t anonymity, | ||
871 | uint32_t replication, | ||
872 | struct GNUNET_TIME_Absolute expiration, | ||
873 | uint64_t uid) | ||
874 | { | ||
875 | struct PutContext *pc = cls; | ||
876 | const struct DataMessage *dm; | ||
877 | |||
878 | dm = (const struct DataMessage *) &pc[1]; | ||
879 | if (key == NULL) | ||
880 | { | ||
881 | execute_put (pc); | ||
882 | return GNUNET_OK; | ||
883 | } | ||
884 | if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == type) || | ||
885 | (GNUNET_BLOCK_TYPE_FS_IBLOCK == type) || | ||
886 | ( (size == ntohl (dm->size)) && | ||
887 | (0 == memcmp (&dm[1], | ||
888 | data, | ||
889 | size)) ) ) | ||
890 | { | ||
891 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
892 | "Result already present in datastore\n"); | ||
893 | if ( (ntohl (dm->priority) > 0) || | ||
894 | (ntohl (dm->replication) > 0) || | ||
895 | (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us > | ||
896 | expiration.abs_value_us) ) | ||
897 | plugin->api->update (plugin->api->cls, | ||
898 | uid, | ||
899 | ntohl (dm->priority), | ||
900 | ntohl (dm->replication), | ||
901 | GNUNET_TIME_absolute_ntoh (dm->expiration), | ||
902 | &check_present_continuation, | ||
903 | pc->client); | ||
904 | else | ||
905 | { | ||
906 | transmit_status (pc->client, | ||
907 | GNUNET_NO, | ||
908 | NULL); | ||
909 | } | ||
910 | GNUNET_free (pc); | ||
911 | } | ||
912 | else | ||
913 | { | ||
914 | execute_put (pc); | ||
915 | } | ||
916 | return GNUNET_OK; | ||
917 | } | ||
918 | |||
919 | |||
920 | /** | ||
921 | * Verify PUT-message. | 783 | * Verify PUT-message. |
922 | * | 784 | * |
923 | * @param cls identification of the client | 785 | * @param cls identification of the client |
@@ -950,8 +812,6 @@ handle_put (void *cls, | |||
950 | struct GNUNET_SERVICE_Client *client = cls; | 812 | struct GNUNET_SERVICE_Client *client = cls; |
951 | int rid; | 813 | int rid; |
952 | struct ReservationList *pos; | 814 | struct ReservationList *pos; |
953 | struct PutContext *pc; | ||
954 | struct GNUNET_HashCode vhash; | ||
955 | uint32_t size; | 815 | uint32_t size; |
956 | 816 | ||
957 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 817 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -979,30 +839,20 @@ handle_put (void *cls, | |||
979 | GNUNET_NO); | 839 | GNUNET_NO); |
980 | } | 840 | } |
981 | } | 841 | } |
982 | pc = GNUNET_malloc (sizeof (struct PutContext) + size + | 842 | bool absent = GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (filter, |
983 | sizeof (struct DataMessage)); | 843 | &dm->key); |
984 | pc->client = client; | 844 | plugin->api->put (plugin->api->cls, |
985 | GNUNET_memcpy (&pc[1], | 845 | &dm->key, |
986 | dm, | 846 | absent, |
987 | size + sizeof (struct DataMessage)); | 847 | ntohl (dm->size), |
988 | if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (filter, | 848 | &dm[1], |
989 | &dm->key)) | 849 | ntohl (dm->type), |
990 | { | 850 | ntohl (dm->priority), |
991 | GNUNET_CRYPTO_hash (&dm[1], | 851 | ntohl (dm->anonymity), |
992 | size, | 852 | ntohl (dm->replication), |
993 | &vhash); | 853 | GNUNET_TIME_absolute_ntoh (dm->expiration), |
994 | plugin->api->get_key (plugin->api->cls, | 854 | &put_continuation, |
995 | 0, | 855 | client); |
996 | false, | ||
997 | &dm->key, | ||
998 | &vhash, | ||
999 | ntohl (dm->type), | ||
1000 | &check_present, | ||
1001 | pc); | ||
1002 | GNUNET_SERVICE_client_continue (client); | ||
1003 | return; | ||
1004 | } | ||
1005 | execute_put (pc); | ||
1006 | GNUNET_SERVICE_client_continue (client); | 856 | GNUNET_SERVICE_client_continue (client); |
1007 | } | 857 | } |
1008 | 858 | ||